<?xml version= "1.0" encoding= "utf-8" standalone= "yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"
  xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Work on Spinning Code</title>
    <link>https://spinningcode.org/tags/work/</link>
    <description>Recent content in Work on Spinning Code</description> <generator>Hugo -- 0.157.0</generator>
    <language>en-US</language> <lastBuildDate>Sat, 21 Feb 2026 21:19:59 +0000</lastBuildDate> <atom:link href= "https://spinningcode.org/tags/work/feed.xml" rel= "self" type= "application/rss+xml" /> <item>
      <title>Estimates Tool Expansion</title>
      <link>https://spinningcode.org/2026/fib-estimates/</link>
      <pubDate>
        Sat, 21 Feb 2026 21:19:59 +0000
      </pubDate> <guid isPermaLink="false">https://spinningcode.org/2026/fib-estimates/</guid>  <description>Adding story points, t-shirt sizing, and other new features to my estimating tool.</description> <content:encoded><![CDATA[<p>Several years ago <a href="/2017/06/time-estimation-making-up-numbers-as-we-go-along/">I created a tool to help me estimate projects</a>.
It uses a <a href="https://en.wikipedia.org/wiki/Monte_Carlo_method">Monte Carlo</a> approach by taking your task list, estimated hours range, and your confidence in your own estimates.
From those inputs it generates a series of possible outcomes to give you a sense of how long the project might take.</p>
<p><a href="/estimates">Try my estimation tool.</a></p>
<h2 id="quick-history">Quick History</h2>
<p>At the time I created it I was struggling with the accuracy of the estimates I was doing.
I was either underestimating because of <a href="https://en.wikipedia.org/wiki/Optimism_bias">optimism bias</a>, or over estimating because I offset my bias too much.</p>
<p>The solution as startlingly effective.
I used <a href="https://www.joelonsoftware.com/2007/10/26/evidence-based-scheduling/">someone else&rsquo;s ideas</a> and built a <a href="/2017/06/time-estimation-making-up-numbers-as-we-go-along/">basic tool</a> and changed my behavior.
That first version was enough to vastly improve my estimating ability, and give me a tool to help other team members think about their own.
When I&rsquo;ve been able to check estimate vs actual all but once I&rsquo;ve been within on standard deviation of the mean (the &ldquo;likely range&rdquo; in that tool&rsquo;s results).</p>
<p>A few years later I needed to estimate costs in addition to hours.
So <a href="/2022/01/project-estimates-tool-2-0/">I created a second version</a> which added cost projections to the process.
That helped in a few scenarios, but honestly not as much as I&rsquo;d hoped.
Still, I learned stuff, therefore making it a useful exercise.
Mostly it got to me fix some old bugs, and add scatter plot graphs to deal with complex outputs.</p>
<p>Those versions were driven purely by hour range estimates.
They were extremely useful in helping me improve my estimates, if limited in estimating approach.</p>
<h2 id="time-to-add-new-approaches">Time To Add New Approaches</h2>
<p>Now I work on a team that estimates with <a href="https://www.atlassian.com/agile/project-management/fibonacci-story-points">Fibonacci story points</a> and <a href="https://www.easyagile.com/blog/agile-estimation-techniques">t-shirt sizing</a>.
I need my tool to support those approaches.</p>
<p>So over the last few weeks I&rsquo;ve done more updates and upgrades.
I now have a new version that will let you estimate using either of those techniques.
It automatically converts those estimates to day ranges and runs the same simulations as it did before.</p>
<h3 id="new-options">New Options</h3>
<p>My experience is that teams using Fibonacci estimates, story points, or t-shirt sizing are usually estimating in days.
Calendar time, or business days, are often what matters to product teams or in house teams.</p>
<p>Consultants track billable hours.
In house teams hit a deadline.</p>
<p>To give users control over the conversion between the raw inputs and the day ranges the tool offers two modes.
Which mode is best depends on what you&rsquo;re doing, how you team works, and how well you track productivity now.</p>
<p>The first is a simple points to days conversion that takes maps the Fibonacci number to a number of days.
It is labeled &ldquo;Calendar Days&rdquo; and lets users control the mapping.
This approach is better for long-term estimation covering months or more.</p>
<p>The second mode is for teams that are good at measuring their velocity for agile methodologies.
This mode let&rsquo;s users specify a number of points per sprint, and the length of a sprint.
It uses those factors to determine the number of points per day, and converts from there.
This approach is better for shorter term estimate cover a few sprints.</p>
<h3 id="other-updates">Other Updates</h3>
<p>While I was doing those updates I addressed a few other long standing issues.
Older versions lacked feedback that a simulation was running.
I also fixed several <a href="/2025/empathetic-accessibility/">accessibility issues</a>, improved test coverage, and added line item results summaries.
The ReadMe file is now far more complete with better descriptions of process and more instructions.</p>
<p>Importantly, I changed the behavior for under-run estimates.
Previously 50% of the time when the simulated value was outside the range provided it would pick a number below the specified range.
Now that happens only 25% of the time, the other 75% generate numbers above the range.
It also uses a calculation similar to the existing overestimate approach – the lower your confidence the wider a range it uses.
This greatly reduces the number of 0 hour/day tasks in the simulations.
It also changes the typical graph shape a bit to long-tail more on the high side.
I think that is likely more realistic for most projects.</p>
<h3 id="welcome-our-new-ai-overlords">Welcome Our New AI Overlords</h3>
<p>To accelerate the updates I used Copilot to help draft and review the code.
AI coding still feels like cheating, but it <em>is</em> far faster.
The code new is a bit sloppier in spots than I&rsquo;d like and required several rounds of revisions at times.
However, the AI added a lot of speed and reduced research level for new features.
That saved time meant I added polishes I&rsquo;ve been thinking about for years, but never took the time to do.</p>






<figure class="figure-figure-right">
  
  <a href="/images/posts/estimate-tool/ScatterPlotWithKdeLine.png" target="_blank" rel="noopener noreferrer">
    
    

    











<noscript>
  <img class="rcf-image" src="/images/posts/estimate-tool/ScatterPlotWithKdeLine.png" alt="A scatter plot graph, with a red trend line over the top outlining the graph&#39;s curve." loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/images/posts/estimate-tool/ScatterPlotWithKdeLine_hu_de90c12f91c4c902.png 680w, /images/posts/estimate-tool/ScatterPlotWithKdeLine_hu_d9c85115efc91e79.png 850w, /images/posts/estimate-tool/ScatterPlotWithKdeLine_hu_55002b8f0a53c692.png 1020w, /images/posts/estimate-tool/ScatterPlotWithKdeLine_hu_411e3066dfd8f994.png 1360w, /images/posts/estimate-tool/ScatterPlotWithKdeLine.png 1648w"
     data-src="/images/posts/estimate-tool/ScatterPlotWithKdeLine.png"
     src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAABhCAIAAACRRD67AAAU9ElEQVR4nNQdXW8jSbGrqntm7IQod7tCB7wchxAP8AL//zegE49IIKHTPu3Cfib2TH8UqqqZtuOMc8nerj2pXbiNM7Zrqrq&#43;P8bf3Ny4e8DM9R&#43;gcP&#43;aRQDz&#43;Bdg/PvcwN9/qeyBXOE9ES2RB6VwShyjK8UhQhOAvEM8N1pPg0MGMHOMcbPZxBiZGRHX63XXdYtjALNQf7spfa8MIMytW63gucnBDANSSpvNZhgGAPDet21bNdJygEvhOPAwOMEycMk89I5QRIHo3Ng9AQ4ZAAAhhPV63TRNKQUAEHGBx9&#43;Z8nEOQ&#43;MQ3CAHx/UD&#43;CBaaGkIH4d5BhBRzjnGmFLC5WlVOf4pupQdeUcEOYkWMqWUInh58dw4PhbmiVsP/hJdIGaXs9BaPQSHKH4QovzbOZEMZca5sXwszNgAO/tZgRXOhNsREBSTS1l0vfcFiRvnigdmFwfOGVISCVjauTkC817Qp0&#43;fYoxmhEMIZ8JtHpiLKB8ujgKTzw4KBkBGZihFeZAcN8&#43;D/LMqyE59DQWWJQGifwrnLAeciAEKu&#43;JccVAANAgAzsWV/Fy00LwRvri46LoupWShwJlwmwO1tC5nUTLknQMH7JTULCzxjqLLiUVB&#43;WehhWYY4L1HxFLKAr0g0T85cckQ1PyCc5qGYHbgXBHPgVwaID8bCfgZ4i7LCE/6h9kVwKLJiPEFFQN2wHrq2TTncjA/DvNGuO/7lJLlghZkhEdPP4vTiVTYpcJJaC2hGACIGKAYBtFRpqYWD/MMuLm5GYYBES0VcSbcDoHVRy45c2gYsag8jF4CSigGCEXCF4SUMCUIYflmYCYbioh26i0cW4oNUJUi9FYUHSA7dYXk32IAnEiAuEPOAWbx34B56eSfNcJN0yBiztm00IIi4ZxdKYDEJPrHokRCJISdskdxRlmT1btSwYJhhgEmAXbwU0pLYYDqn1GzI2V2MRUVBiExuGpxNRpAFNOc8/Izo/MFmZRSlYCleEHi&#43;mRxQ1Gi31wmrPacHVFRwg4kIpEACYmXbgbmc0GbzWa73TLzYlIRFp2ranGQ9J&#43;EQASexOzaLwuLVwoOSByh4p5DVm5GAqwmY2Ew6L2dA7EDnFSnq6PDgGJmQagfSKul&#43;stcxD8qzB7AyTVOfhA7LNb63DdwFGYYQETr9dp7n3M2p&#43;gciN0FiwCyRAAFqTjLPoBYXNMwek6KyAEXcAxYQKJ5FQJaMP3njDARdV0XQhiGYSlG2AxAyYVCUv/HAl43FYBNIDxjERXEmpPAkhKkBH7RSaEZCaiwCNIrmAEQLjhgOyUI8seNCgZBjAGIcS6qdhwDsMZpCzcD80Z4GAaryTDz&#43;Y2wEN4MgLiYREhIXiywnHOhv/HAAYtLiqb6hQFqOdgtOhybkYADL&#43;j8qQg9FJxzAWQkQPQk1Cetlu4fb7RXwGWGsTRvnMPlhmMzDDAz4L2XOHMJLVlaBBYXh4LF5RIt2v/Uv2E3hWH626L/ZSKx2DnDsmsDIwNqwIUi42RtKRaInd0LshAA7IRrzcterxSF0RwzGjOK/FisqSAnXHZtwBv1h2Ho&#43;x4R27b1CktJRUwGQEIS0T87dPbde81FaE5Oaa15OxCDIOFZWXIg4M3qfvr06e3bt977b7/99uLionaInr8gYwYgZQbMgMwgDqbq&#43;gOa3jknPGa1RGLYzMBCu7VGCdhsNu/evbNqsCkf84KsRHxOBCcDkNAnFoeHxL7ep/90uWkhtRAUApSs/Euw1EYVv98LhIjVDd1ut6WUEILVxc4F1qAhWEn85WhydR4mppUHtG0Ci5aIeam1AV8Lv&#43;bzmP9j1vj8qYidAUCHcoSV9EePv5EeweWxfqw/Fiazw4usDcx4QZYBbdv2/KmIKQUkbn8Qv&#43;Dn&#43;4SVP4ggUbCcejXPCy4Rj6fbmlBijKZw4C6cDTtNAZkJRSJPEoIhPiAAJgFACJ4kZkbvHVJJiVNapjM6SgAAWB3GSjHWEWQZ6bMZYdP&#43;WS0QokMQetLD9HduKhSDdqgULmIJYualmgG/X3wvpRj1Y4w1FXE2IzxlIBjREaH2a&#43;PjJBK0YU7rAlgQix4vXKQzesfA8pjFgiXMZbAagJJydpgcllExPvK9Y3UsFVeQ2ErEi9RCOy/IzG&#43;FEEIdEzsDXur/iEdcSkKXMntkVZePPRM2RZANfySX4zK10C4ZZzGXzURaRggAzugF1QDYuhCfeHTZuobUZUVtombMeYEhMdasg3WjkPpqfBdOj5YOIaWcUgFkPRBP1YjmjIoddi47zAxFPdons/Irw5gLsi5oaweqdtgCsTN4Qap/iuZii/cM4lB6tcCP1kCA4gtBKVAcMCEjmRngEGBJ8YC3WQwA6LputVrZeN5WwXzQM3hBNgSQkgPgKQC24/xI&#43;oMVyEZ3AhyTOKNJfKqlaSFvvYjX19cXCiEEAGjbFgByzmfpDR39H3FAiYlg8j4ff/5HHmhEVhiYJTDjDCUmiAmXUGWawBu5v/nmm1LKfiKoaZqaED0pRtYCnRI7yNoEh26Xgn4aqBZihiKmznOiHCPECE1YzkC9twJkPeb7d6lO4Kmbc7kwxygMQILgtQhvPRBP/qhavGTtFBJ5YvlkWlJeaJeKqC/V7LTFASf1gqz/R/RPycE7pKCbQqbq71NBS/QA7DixY5BzZvs92HvARTRszTfn9n1/e3ubcyaik3pB4wxM0voXsYOgiZ3P0T9jjczo7zKrZ0S&#43;pKHECCFwgNpXd0aYH1O1pJCpoNMJgWXfYtQGCPFbdor/c8k01g9QPwARQnBIJaYyRE3znT8mmJ&#43;QMS&#43;opiJOYwaEzzHlIebiOBAoA8wAPMn/OYDRHSLQ1l4PJfDQ8zCArjlwdGYRODqiZNUxm5c/BSJjLbTPKWX0RYIlObi/fBMWOPGFPGLWZolM3oFoOd/3IAGBh7P23RztDT1xBkKUzxDzMGjg6gt&#43;htdzBPZqZDrPig69SxmG3iEQrMTOnM8UzBthm1SNupDnFEbYMj99n1LOFAqJ&#43;TW98ZT4dx6gZuVqii4EcbbiwJstWJh3vp6JmeZc69O6vb1NKZ2iN9Qir75Pw5AYI1ApQOCC6g36EgbIhoh3jaSIkQLH7GOEzVZY0Lbn4sHMfICFZpaT&#43;OqpCFP92z5u&#43;lRcJi/eJ0t8qDWwL6McaloCwcU8da2DL1AgJne78cyVBycOPOeNsE2qfvVUxI76myGm7AP7YJVHr&#43;nPX6p99sAGCGy2O&#43;aSiig5RwFKKn30ufiUqW0xhC8jdI&#43;Go93RtVflq2BjsYVqnrzZZlH9PmJwmnkORG3QFMSX&#43;2qt1EMgzJ6ybphgcA59RizRpSH6lH1MvutC1yD5z0l9fBbMD&#43;kdBGJf8PvGsE6sbi5DL8c/5oSUKCT1BwNA8I/qfng6yBcEQtcIb4sIgXpfADkCp6HcbjlnKMV3rTXAnMAqzDOgrg61ZPWX&#43;SprM8&#43;lpCTupjidccglAmXyrObGy/HXe//M5M9DYArNk0i4qCPVRRJrEjE0CUB&#43;6CUOb1IMnaij0TJPOY0vi4/BPANqMo6IflFBhu3PtOYhpTTE1A9RVH6JDL0T6kMBj9AQtoGaQISP7D55Mqhb4Wz2tqAqIucyu8LA6DFgSVF7ojZtTE0b0HvbwThKw8iML4nbvA0IIaxWKxuSeaoXtGvQr9rGaoE5l5RTTGIDGSKGBFTUDfdEbUNdQ20gT5&#43;ZensMgJvSc&#43;qXBuJEqPN/wIiaAQQGLCWJdJTiKSLROI0m8bQ3mWCobaq/FNF5L8gGNB5ORexPPewTfTrs2Yq6jov2lxfHXAATUUKfHLIEp9jqfYVAXaDgyeM4ePT1wNSJpSGDR&#43;e8p5IV35hK1spBZh&#43;FI074UgqmHjSVB&#43;QdodNDI4zxHvYSZbshKWexx&#43;77HkgnzqciDojOY2YC6kTWOJc1TWftnfQs1NeSug1ZqhNOuuCT7JSV7FIS4feETRCfJ3hsvLl/p/P/zC/SYXvUFsgSqQyppFwKo0PggAyu6IQByC0xiA8b7ejJ2yZDDUaZSUeBzc3aeMgobuBgXnMdNcKDjqqWUki7Ey2OhPH309xoGRcmyf/Zj7ZqVEe0CoXxLm3BntKXHIRUHGQu7EXpeyP9ialvoIlqiQfKOP8qscKQchoHolAzUt5NayR1X05WiyE37ProbHhtNAz6cTo16yycsb0tulSWvDfjdoDD0VyQpSLUMQ8EEZS4MNpUXY3BhScGmPQ5QrZ5RO3mBCKwhOZU&#43;TAae4Q2ECtPxeP8aib3MTAO2qtoqyMmcpnVQ63zaMXUKqsc2/KJOjhVyqQPnA7I1pnypAt9tRGP0PlAXde0DdwLbo6qIPV/dOZQ3QLISTSlKR3bhqGrkZwnU01gHYBEblp6jJZLcPWEOBhTYwiT/jor8ffuVsc6TLcwgp&#43;GXqv6ZQdm3WpMVMhzKJP&#43;vdPL5qZmNy5FO5OyGwYEYC9K&#43;OBuj6YiACAOQ&#43;x7NwzZsWhw8ozjiVZyj3/Hqd1R&#43;42CaP04ON1DZcAdM7WM4UUYTWbde8Blp9f1eOv5UZGfrhCHAtSQqy6YHG5jhcnTKAm5QE6YEtpyzXurW46mIrSrr5R&#43;EIvig2taF4KrA9JQDT3gZF4Q6o24KfCBvY91C6H4AzDuIQWuJnNiw7QXBEbh4Kp4VEe5cXWps7zTyBh27NkVj7rCZbYf6aGCTFH9hb4LmqWyxcCTwR/NwX6MWD8c7t7S5KI6V4uw/HA19vGDvV/tSji2YwJGXQWTbExTyjz92riIOrnM5hE5sgN6H47mgsQRijGza5oAFpTv3UTVe2YmxsY1vu9p3VGP0&#43;e7IxkmnvQs11m8IwmhwyvhqD577JVc/QuxAqAFWZyvy/Go&#43;essBUw7Gx07mLtsCv/cfRGYlwDLRhTd/6UN4rulGDxdsEvY6Xqesa8dDsPmsfk3S1igHNL92g4O6c&#43;ucLHr2J7cQeR1M8ohzta5q5cWVmJ5&#43;YOIh4StV2b17cXLHJvvD67UM5HHjf2FibDtmq5pJDJ0ByERl2x/srWUex/GtV37BLIOG0OyFPEQAYOXmBPuNjnM2wDLRgAgOxYH9qAxgjkzpzhsN5tBawbe03q1ptVqzOLvU7&#43;UOPTb7TbGKPfmfdt2TdOIQrx7XGIqMQ2Dzic78VCDX68a6pDw7pVlGHI/9H3fW&#43;Ne27Xtet0ED3fZX7jEIdUr5XPatvHrJuDdK8WX7ofYD9thGOR2hKJrF8SVPrzxwjnF7Vav1Irheq03jjRz432/2WxsxiJ4WnWd1vjuIDkvAdYYYX2ik5DBTp2D2h3N2OVBAhdXPDctOfb7TbR6pU5Y5xyHbE0ujqlr2kDe&#43;wOMCXJERpd13QYDQ0DXNXJo99PCIh&#43;cByiRkzgsDshJNNc1/iBtJewpqYcM4pUXZCIobYD28EoWMc4wuIKcuSQHEmoROD8FtrsbZ23ZHIbU91kiZOaS0bHHPZ9jd&#43;PJ&#43;jxE8DnwXF75aBxw1DsHW0yCbdsAuJRaS9i1bWuSuHufouuJuq5FBJs2IKKmacK9lBuza0K4vJCDXCeW27b1ZLMZe9QCbJvAlxdt29iVIYRWk6gHSON45WWnD4IysW6axh&#43;qNfmhaxtwF6tVZwpQkfR3yGAERmzaxjm2byciRZLAzd54B7YyR41K0zT31//A7JP0fhbuz8/UZ848fOUD48f1wRETVR66cv/5Erg3QHPQRmZXViQfGD48uPLY7dRC4Ze6nc9kwNnB/LTtdmtDDDbnbEJjBe1zI/hYeGhp35KBmbfb7f/&#43;97/tdlvPb9d1L168qMuOngU8VwbUFcvWQGZ1C5ODc&#43;P1NHiuDLDBnqurqzrJg4j26JtndPyfPQMQ8fLysgalNl9&#43;9uzqk&#43;AZM8Bi2v2cxkPe81LhuTLA4DlS/ABmmnNPj8Qxx/z0mBicpzWxjsyf&#43;KEN1n6x7zueC5P9pbUnmwsaGWCF&#43;Pfv379&#43;/frm5ialdILvrvmGb7755sWLF&#43;v12nR6Sun9&#43;/dv3rz5&#43;PHj2FpxEjAzfnV19fLly6urq9NsDd7tjLu5ufn3v//9448/vnr1qu/7r/3FBoh4fX39pz/96a9//WvTNCEEZr69vf3Pf/7z97///aeffjoZJsaAruu&#43;//77v/3tbz/88MN6vT4dA&#43;y2f/rppx9//PFf//qXPc&#43;8XrSfS3nSp&#43;8/g6MK9a6Yo8mDb7/91jn3/fff//rXv7bVFJvN5tWrV//4xz/&#43;&#43;c9/9n0/i8lTkTkQo30Ns5&#43;tWq/X79&#43;//&#43;67737729&#43;uVqsn3eznwR0VZPtz3717x8y2uKOmveya/XkNu4G6T2JX95k62uuzQOsT&#43;SwFbR9oT643Xffu3TtL2dsnp5Rubm7eKliCYf&#43;N1eunu9PuVhswnA/YU5dgm35DxPqZZm/qqtTtdvv27VtTwqdRfXeMcL3Dtm1fvny5Xq8Ne1PEVlgwvGvj4jAMtuPSyGf3b3dl2iOEYPffKViNwUj85s2bDx8&#43;1LxmRWMfk6ZpXrx4cXFxUVfaWRrOPrmq6ZTSMAze&#43;67r6lmp9K1LaG0zv&#43;m91WpV3xtj/PDhw&#43;vXr0//EN&#43;j9QCbDrOdKXVwTItfvvoJJjeWEzfCWSBqjLFDZ6kCI5lR2VjYNM1jsmZ2qK3YUHmz3W5TSpZhNzSM4nalrTwyPC1ZZKalaZpKXONNfVdl5&#43;lTSXdWlhlYovH169cfP36sGtxobTS1EWLnnD1oY3&#43;Qz25jUDDtZHdlqsb4au&#43;15jsbgdqPpw7y5tvt9r///e/t7a0R2vCpyZ&#43;6ZqRiYjjbeffe27in1YKs2XsYBma&#43;ubmxN1ZB6RXsx1MuLNwxwMqbl5eXFxcXRsEDZ3S/D6C&#43;Ujdd2itGkfo8&#43;npxPVnVvBtfu667VNhP4hPRarUyTOy5rgdFi/uYlLFFtVSc72NSpdD0EtwduzCedV33q1/9quu6kz25YmQAIq7X69/97nd/&#43;ctfrq6uPtv52&#43;fNY64nouvr6z/&#43;8Y/X19cmGYi4Wq1&#43;85vf/PnPfzYGfJ46fiom9pbVavXDDz989913XdedmgEXFxd/&#43;MMfLi8vP378eMpAzKooL1&#43;&#43;rIduvV7//ve/N4/wZJhUDXl9fX1KBuxKkvUBeicOPu22q23Yn5E6JSYVH5uRPpkKOqwJnysFNlvUPgsmZ0vGnf67H4blYPJV4f8BAAD//4OHUh0TP21GAAAAAElFTkSuQmCC"
     data-sizes="auto"
     width="1648" alt="A scatter plot graph, with a red trend line over the top outlining the graph&#39;s curve."
     loading="lazy" />



  </a><figcaption>New scatter plot display with KDE line, and save buttons.</figcaption></figure>

<p>For example the tool now outlines scatter plots using a <a href="https://towardsdatascience.com/kernel-density-estimation-explained-step-by-step-7cc5b5bc4517/">kernel density estimate</a> curve.
I added save buttons for the images, and there are print styles that make it easy to print into a PDF.
Hopefully all those changes will make it easier to share the results.
I only bothered to make those changes because AI made it easy to add them.</p>
<p>That process was aided by having had a reasonably good structure to the code I wrote in earlier editions.
And I did check all the new work, but keeping tabs on 200 lines of new code from one prompt is a challenging exercise at times.
The code base needs some additional refactors still to deal with some of the bloat it picked up.
I don&rsquo;t care that Claude and Copilot assure me all cleanup already been handled, the 2000 line <code>index.js</code> tells me otherwise.</p>
<p>You can find the full code my <a href="https://github.com/acrosman/simple-project-estimates">estimation tool</a> on Github.
If you have suggestions, please open an issue there and we can discuss it.</p>
]]></content:encoded> </item> <item>
      <title>Consultant vs Client</title>
      <link>https://spinningcode.org/2026/life-on-both-sides/</link>
      <pubDate>
        Sat, 31 Jan 2026 17:36:37 +0000
      </pubDate> <guid isPermaLink="false">https://spinningcode.org/2026/life-on-both-sides/</guid>  <description>Life on both sides: Some things I&amp;#39;ve learned as a client and as a consultant.</description> <content:encoded><![CDATA[<p>Lots of people working in technology have a choice between working for clients or working for consultants. We work on one side of the relationship thinking how nice it would be to have the advantages of being on the other; the preverbal grass is always seems greener.</p>
<p>I spent a little more than ten years as a client before I became a consultant. I spent just a bit longer as a consultant before becoming a client again. There are things I&rsquo;ve learned in each role that help me do the other better. To ensure a mutually beneficial engagement it is helpful to understand the perspective of the other team.</p>
<h2 id="why-is-understand-both-sides-useful">Why is understand both sides useful?</h2>
<p>The goals of a consultant and a client organization are misaligned. That doesn&rsquo;t mean you can&rsquo;t do great things together, but if you don&rsquo;t understand the goals of your partner you are likely to step on each other&rsquo;s toes.</p>
<h3 id="the-goals-of-clients">The goals of clients</h3>
<p>Client looks to consultants for one of two primary reasons:</p>
<ul>
<li>Add to team capacity</li>
<li>Solve a problem</li>
</ul>
<p>We either need to complete a project that our team does not have the time to tackle, or we need expertise it does not make sense for us to keep on staff. Sometimes we&rsquo;re looking to reduce costs by having a group of part time people fill the roles of a smaller number of fulltime team members.</p>
<p>I like to have my team&rsquo;s staffing level sufficient to complete all day-to-day tasks and to bring in outside help to take on special projects. Other people like to have consultants around consistently to provide the outside perspective and the diverse expertise that consultants bring. Both of those strategies are foundationally aimed at those two needs.</p>
<p>A smart client wants to spend the money needed to be successful, but not more. We want the most value for our money we can possibly get.</p>
<h3 id="the-goals-of-consultants">The goals of consultants</h3>
<p>Consultants have a different pair of primary goals:</p>
<ul>
<li>Record billable hours and/or ensure profit margin</li>
<li>Have a happy client who refers more business</li>
</ul>
<p>Some consultants will protest that they have the goal to solves client&rsquo;s problems through good work. My perspective is those are way to achieve those two goals. Some clients are happy when you do good work (but not all). All clients are paying to have a problem solved (see above).</p>
<p>Profit motive isn&rsquo;t evil or wrong – even when supporting nonprofits and other socially beneficial institutions (having spent much of my career in nonprofits, we think about this <em>a lot</em>). Consultants need to make money to stay afloat. A consulting firm has people to pay, overhead to manage, and founders/investors to reward. Independent consultants need to eat, pay their mortgage, and so on. The larger the firm, the more pressure there is for larger profit margins.</p>
<p>To get new clients, consultants need &ldquo;referable&rdquo; clients. That means having clients who are so happy with the work done they will serve as a reference. I wish that always meant creating the best solution possible. What it means in practice is building the solution that makes the client happy. As a consultant I gave clients my best advice, and when they disagreed and insisted on a different solution, we build that instead. If they ran out of money along the way we still tried to keep them happy, even if we had the duct tape the last bits.</p>
<p>In the end, consultants build what clients pay for, and that&rsquo;s not always the best solution.</p>
<h2 id="finding-the-balance">Finding the balance</h2>
<p>With consultants trying to make the most money they can, and clients trying to get a successful solution for the least money, there is an inherent tension in the system. Still, there is a balance to be had, where everyone wins, and great things happen. The trick is to make it a healthy tension that forces everyone to be better. Finding that balance doesn&rsquo;t <em>require</em> that everyone involved has spent time on the other side the relationships, but it certainly helps.</p>
<p>When you understand the needs and goals of the other side of the relationship you can adjust your approach to make sure everyone is aligned to win.</p>
<h3 id="lessons-to-take-from-being-a-client">Lessons to take from being a client</h3>
<p>One of the things I learned along the way was that a lot of the advice given to new consultants contradicts what I knew from being a client. Spending time as a client gives you insights into how to best serve customers that many pure consultants don&rsquo;t understand.</p>
<h4 id="be-the-consultant-you-want-to-hire">Be the consultant you want to hire</h4>
<p>When you work at an organization that hires consultants you see different approaches taken by different firms. You learn your preferences about what you like and don&rsquo;t like in a consulting partner. While no one style is the best fit for everyone it&rsquo;s unlikely that you are so unique that there aren&rsquo;t lots of other people who like that same style.</p>
<p>Default to the Golden Rule: treat clients the way you wanted to be treated by consultants.</p>
<p>You can&rsquo;t always do that 100% of the way – sure as a client I want everything free, but that&rsquo;s not reasonable. But by approaching the client the way I would have wanted to be treated consistently went a long way to helping smooth over challenges.</p>
<p>Start there, and over time you&rsquo;ll learn to adapt your approach when specific clients prefer a different style.</p>
<h4 id="be-honest-about-your-limitations">Be honest about your limitations</h4>
<p>Do. Not. Lie. To. Me.</p>
<p>Do not guess without admitting it. If I wanted made up answers, I&rsquo;d ask an AI.</p>
<p>Consultants always want to appear to be the expert in the room, and so they feel they have to answer every question. Too often that leads to consultants making up answers to show how smart they are; clients will catch you eventually.</p>
<p>One of the best ways to build trust with a client is admit when you don&rsquo;t know the answer to a question, and then come back later with the answer. Do not say &ldquo;I don&rsquo;t know&rdquo; and leave it there, go for some form of &ldquo;I will need to go look that up/ask around/figure that out.&rdquo;</p>
<p>Great consultants find solutions, they don&rsquo;t always have the answer right away. We can wait for you to do some research when we stump you. That is a lot easier to explain than when you have to walk back having given us the wrong answer.</p>
<h4 id="focus-on-what-the-client-needs-to-succeed">Focus on what the client needs to succeed</h4>
<p>Clients should always have an outcome in mind that supports their work. Consultants are focused on the solution they are building. When everything is going well, that solution <em>is</em> what the client needs to support their work. If those stop being the same thing you have a very big problem.</p>
<p>Both clients and consultants can easily forget to consistently re-check that alignment. As a client and as a consultant I&rsquo;ve been part of projects where the delivered solution didn&rsquo;t solve the actual problem – even when it fulfilled the spec and SOW. These moments frequently lead to energetic discussions that often become loud. No one wins when that happens.</p>
<p>Regularly check with the client, and with yourself, to see if the solution will solve the client&rsquo;s problem. When you see misalignment raise your hand early and often.</p>
<h3 id="lessons-to-take-from-being-a-consultant">Lessons to take from being a consultant</h3>
<p>Of course consultants know and learn stuff that isn&rsquo;t obvious to any given client. Consultants bring wider experiences, different perspectives, and a different energy to a project. That is part of what makes them valuable. Clients should hire a consultant they trust, and listen to their consultant. Think hard before deciding you know better.</p>
<h4 id="always-learn-new-things-even-if-they-arent-important-today">Always learn new things, even if they aren&rsquo;t important today</h4>
<p>As a client we tend to learn deeply about the tools we use and our work. Consultants work on a lot of projects with a lot of clients. Along the way they use a lot tools, and see at lot of ideas. That creates a culture and need for constantly learning. Often they are learning about things that don&rsquo;t seem useful right away.</p>
<p>The higher the role you have as a consultant, the more you are expected to be at least conversant about technology you haven&rsquo;t used yet. You also need to be conversant about the work of your clients. That&rsquo;s a <a href="/2025/thoughts-on-professional-development/">lot of learning</a>.</p>
<p>I had good learning habits going in to being a consultant. They served me extremely well as a consultant, and are serving me well again as a client.</p>
<p>The broad knowledge of a consultant is extremely useful and everyone benefits from more people knowing more stuff. Having that breadth of knowledge also helps when you do run into the places where you don&rsquo;t know something. It gives you the confidence that you <em>can</em> go learn the next thing you need to know quickly (see <a href="#be-honest-about-your-limitations">Be honest about your limitations</a> above).</p>
<h4 id="know-how-to-work-to-a-deadline">Know how to work to a deadline</h4>
<p>Consultants are always working within time and budget constraints – usually tight ones. That forces them to learn to be efficient. Sometimes that means they cut corners (see next section) usually that just means they move fast. Good consultants have a high degree of dexterity with their tools, they learn to line up their work to knock out tasks, and they learn what&rsquo;s needed and what&rsquo;s just nice to have.</p>
<p>New consultants often feel like they are sprinting all the time, but experienced consultants learn to balance the sprints with jogging. The pace is nearly always high (at least if sales are going well), but it still ebbs and flows. Consultants learn to hit their deadlines, but rarely are ready to deliver early.</p>
<p>As a consultant if a deadline was far in the future it gave me time to do careful work, balance other clients, do research, or just time off. Far off deadlines gave me time to recover from sprints and make sure I had the energy for high intensity moment. That intensity is important to driving client success – but hitting the deadline is more important.</p>
<p>Hitting deadlines is also important for a client to do. Consultants need you to hit your deadlines so they can balance their workload to hit their deadlines. They may also have penalties embedded in the contract (see <a href="#read-and-understand-the-contract">Read the Contract</a> below) that could cost you time or money over the course of your project.</p>
<h4 id="perfect-is-the-enemy-of-the-good">Perfect is the enemy of the good</h4>
<p>Okay, <a href="https://en.wikipedia.org/wiki/Perfect_is_the_enemy_of_good">this isn&rsquo;t something just consultants know</a>, but it is something consultants often learn to deal with the hard way.</p>
<p>Consultants need a solution that meets the requirements, fits in the budget, and pleases the client. They are not there to create a solution that is perfect, or even elegant. In any project there is a balance to be had between carefully polished, and just barely good enough to be successful. Consultants learn to thread that needle. As long as the project is successful that&rsquo;s a good thing.</p>
<p>I have seen developers spend hours, days, even months, trying to build to the perfect level of abstraction, with the perfect naming conventions, and drive for the perfect code, only to have the project fail because it&rsquo;s overdue, over budget, and was outmoded by someone who worked twice as fast.</p>
<p>Yes, we all want good solutions to our technical problems. But no solution is going to be perfect. You should aim for perfection and know you are going to miss. When you learn to accept that, it&rsquo;ll be easier to move forward and be successful.</p>
<h2 id="things-everyone-should-know-regardless-of-role">Things everyone should know regardless of role</h2>
<p>For all there are things that each side brings something to the table, there are habits that everyone should have as part of their role. There are lessons I learned, or was taught, in both roles that are super important.</p>
<h3 id="read-and-understand-the-contract">Read, and understand, the contract</h3>
<p>Everyone on a project benefits from having working knowledge of the contract. In the end, when push comes to shove, all that matters is the words on the paper. You can usually avoid the pushing and shoving by understanding what everyone agreed to up front.</p>
<p>The biggest issues I&rsquo;ve seen on consulting projects was when one side, or the other, didn&rsquo;t pay attention to the agreement.</p>
<p>Sometimes this happens because everyone is working in good faith, and no one remembers to amend the agreement when needs changed. In those cases you can often recover by continuing to work with each other in good faith.</p>
<p>Sometimes this happens when someone signed a contract they didn&rsquo;t read and understand. I once had a client yell at me because I added a paragraph to the contract outlining the resources they were responsible for providing and he didn&rsquo;t read it before we asked him for those resources (these clauses are really standard, and the one I wrote was extremely simple).</p>
<p>If everyone on the team takes the time to read and understand the contract it greatly reduces friction. Clients who understand the bounds and assumptions in a contract are able to get the most from their vendor without creating tension. Consultants who track the required deliverables of the contract don&rsquo;t frustrate clients by skipping required elements. It doesn&rsquo;t take long. The more you read them the faster we&rsquo;ll be at reading the next one.</p>
<p>Once you have read a bunch of contracts you&rsquo;ll know what&rsquo;s normal and what&rsquo;s not. At this point, if I don&rsquo;t understand the contract language I see that as a red flag even before I send it out for legal review.</p>
<h3 id="discuss-problems-and-be-solution-oriented">Discuss problems and be solution oriented</h3>
<p>Projects go best when everyone is open about what problems exist and then pivots to solving them.</p>
<p>Technology should be deployed to solve problems. That means starting by talking about problems. Being problem focused at the start makes it easy to be hung up talking only about those problems, or about new problems that come up while solving the first problem.</p>
<p>Having a good problem statement is critical to creating good solutions. But once you have the problem outlined you need to focus on solving it. Yes, raise problems, concerns, challenges, threats, weaknesses, etc. Talk openly about all those things. Then make the pivot into problem <em>solving</em> mode once the issue is well understood.</p>
<p>The best projects come together when when everyone collaborates on finding the best solutions to the problems at hand.</p>
<h3 id="quality-matters">Quality matters</h3>
<p>Everyone needs to focus on the quality of the outcome. Consultants, for all their fast moving creation of imperfect solutions, must still do good work. Clients should hold their vendors, and themselves, to high standards.</p>
<p>Every message that goes back and forth is a chance for misunderstand that gets in the way. Every input into discovery and every deliverable is a chance for gaps to form. If anyone takes their eye off the ball mistakes can happen and the solution no longer threads the quality needle correctly.</p>
<p>Mistakes will happen, and everyone will have to help course correct. But the higher the quality of the work done before the mistake, the faster it will be to recover and better and overall solution the client will get.</p>
<h2 id="the-grass-is-greener">The Grass <em>is</em> Greener</h2>
<p>One final note on the way out. If you are trying to decide between being a consultant or being a client, I recommend the switch – whichever you are today try being the other if you haven&rsquo;t yet. Not everyone loves both roles, and different roles have been right for me at different times.</p>
<p>As a client I loved what I did. We were helping make the world better. I was pushing things forward and helping the organizations succeed. But eventually the things they needed me to learn, and the pace I wanted to grow, weren&rsquo;t aligned to the organization&rsquo;s needs.</p>
<p>I&rsquo;d been there a decade, I left on great terms, but it was time to go.</p>
<p>When I first became a consultant it was exciting. I got to work on a variety of projects, with more  technologies than any one organization generally needs. The pace was higher and I was frequently pushing myself in new directions. Consulting gave me insights into how different organizations worked (for both better and worse). And I made more money.</p>
<p>Interesting work, exciting environment, more money, great!</p>
<p>As a consultant I spent less time in positions, the billable grind was exhausting, I missed being focused. When I returned to the client side, I got to focus again. I have one org to worry about, one set of organizational politics to understand, and so on. I get to learn the work of the organization deeply again  and really understand the market we serve. In my case I, again, got more money – but that was at least partially luck as much as anything; consultants are often paid better than in-house team members.</p>
<p>Focused work, no billable hours target, calmer work environment, great!</p>
<p>Each really does have it&rsquo;s advantages. But so does understanding what it&rsquo;s like to be the person on the other side the relationship. Try them both, learn from both, decide what&rsquo;s the best fit for you.</p>
]]></content:encoded> </item> <item>
      <title>Thoughts on Professional Development</title>
      <link>https://spinningcode.org/2025/thoughts-on-professional-development/</link>
      <pubDate>
        Sat, 05 Jul 2025 01:00:00 +0000
      </pubDate> <guid isPermaLink="false">https://spinningcode.org/2025/thoughts-on-professional-development/</guid>  <description>We all have to constantly be learning. These suggestions are more or less in the reverse direction of importance. Keep reading.</description> <content:encoded><![CDATA[<p>Ongoing professional development is a fact of life for people who want a long-term career in technology. That means finding ways to learn new skills above and beyond what you&rsquo;re paid to do. We all need to strike a balance between having a life outside of work, and making sure we&rsquo;re learning new work-related skills. Your professional development should not take over your personal life, but if you only learn on the job you will limit your options over time and be bound to the generosity of your employer.</p>
<p>I changed jobs recently. In the process of leaving my old job I was asked a lot of questions about how I&rsquo;ve built up a wide-array of skills and knowledge. During those discussions I tried to give the best advice I could on the fly to a question I was asked cold. Now I&rsquo;ll try to assemble a set of more carefully considered advice.</p>
<p>These suggestions are more or less in the reverse direction of importance: the more you read the more valuable I think the suggestion is.</p>
<h2 id="directed-learning-job-related-learning">Directed Learning (Job Related Learning)</h2>
<p>By &ldquo;Directed Learning&rdquo; I mean learning that is supported or encouraged by your employer. This can be certification preparation, employer provided trainings, or research into an emerging technology, even building tools that directly support your work. Into this category goes anything that can lead to higher pay, advancement, or even just keeping your current job.</p>
<p>Some employers are really good about this. Over time I&rsquo;ve been sent to trainings, had course fees covered, and other direct support. The job I just left even provided financial incentives (cash) for us to acquire select certifications of value to the company. Other employers have published a list of what they wanted people to have – without direct incentive. But most often I&rsquo;ve had to figure this out on my own which is not ideal of anyone involved.</p>
<p>This type of growth has a few benefits. First, it can help with your reputation (and hopefully pay) with your employer: &ldquo;Oh, Aaron is certified on <code>[interesting product]</code> we can assign him to <code>[high profile project]</code>.&rdquo; Second, it helps make sure you are growing in alignment with your employer&rsquo;s needs. That can be helpful when they are forced to make cuts: &ldquo;We should keep Aaron, he&rsquo;s the only team member with <code>[rare certification]</code> and Salesforce wants us to have that on the team.&rdquo;</p>
<p>In my life as a Drupal developer this looked like creating modules for internal use, or <a href="/2017/01/drupal-8-plugins-are-addictive/">learning new techniques</a>. But it boils down to the same thing: learning stuff your employer needs you to know.</p>
<p>The downside of only learning what your employer needs is that you miss chances to grow beyond their needs. That limits your future mobility – your best chances will be for another job like you have today. If you want a <em>better</em> job or a job doing something different, you need skills your employers doesn&rsquo;t think they care about.</p>
<h2 id="personal-learning-side-projects-and-other-self-directed-research">Personal Learning: Side Projects and Other Self-Directed Research</h2>
<p>To learn things your employer does not care about you will likely need to put in your own time. You should focus this kind of learning on something that interests you – make it fun. My experience is that this kind of learning goes best with side projects.</p>
<p>Side projects allow us chances to test and practice the ideas we&rsquo;re learning. I use them to learn programming languages, frameworks, and techniques that interest me but not directly useful to my work. <a href="https://github.com/acrosman/Salesforce2Sql">Sometimes they come around to being useful in my work</a>. Sometimes they just give me a chance to learn interesting things. <a href="https://github.com/acrosman">My Github account</a> is full of examples.</p>
<p>An early professional mentor told me to <a href="/2022/10/thinking-about-languages/">learn a new programming language every year</a>, and so over time I taught myself a bunch of programming languages. These days I generalize that advice a bit and try to learn a new platform, framework, or technique every year – and sometimes a new language. That meant when Salesforce rolled out LWCs to replace Aura Components, I was ready to learn them quickly. It also means when a friend started to talk about using <a href="https://wails.io/">Wails</a> I could related from my experiences using <a href="https://www.electronjs.org/">Electron</a>. My experience creating <a href="/2022/01/project-estimates-tool-2-0/">a project estimation tool</a> helps me discuss estimation techniques with project teams.</p>
<p>This blog is an example of a side project. Every post gives me practice at writing. To keep posts accurate I include research as part of my writing process. That research teaches me things I wouldn&rsquo;t learn otherwise. The act of writing forces me to clarify my thinking on topics. All of that is useful to me and helps me be better at my work. I also know this blog as been read by colleagues, employers, and potential employers all of whom are useful audiences when getting new work.</p>
<p>When I give talks about <a href="/tags/writing/">communication skills</a> I tell people what they do for practice doesn&rsquo;t matter: <em>what matters is that they practice</em>. Same is true for side projects. What project you tackle isn&rsquo;t important. What is important is that you do something that forces you to learn new things.</p>
<p>Side projects help us <a href="/2016/08/different-angles/">look at our work from different angles</a>, and therefore test our limits and grow.</p>
<h2 id="develop-learning-routines">Develop Learning Routines</h2>
<p>It&rsquo;s easy to get lazy or to put your professional development aside – it feels like there will be time later. So you should create a routine that works in your life.</p>
<p>I like to have a routine to make sure I&rsquo;m steadily doing some form of professional development – it&rsquo;s a marathon not a sprint. For me that generally looks like job-related learning for about an hour after my formal work day and working on a side project on weekends. Attaching your learning to your work day allows you to more easily block the time in your mind and with family.</p>
<p>I know people who like to do their study before work because that&rsquo;s when they are fresh and study gets their brain into the right gear for the day. Other friends tell me they like to do research or study after their kids go to bed because it gives them more time with the most important people in their lives. All of those are great patterns because they are tailored to their life.</p>
<p>Whatever routine works for your life is a good one. The important part is to making learning a regular activity.</p>
<h2 id="share-what-you-know">Share What You Know</h2>
<p>One of the best ways I know to learn is to teach. Giving talks, writing blog posts, and mentoring all give me a chance to share what I know with other people.</p>
<p>Sharing can be intimidating. I have been writing this blog for nearly 10 years. I gave me first conference talk more than 10 years before that. And still, every time I take on a new topic I&rsquo;m nervous I&rsquo;ll <a href="https://health.clevelandclinic.org/a-psychologist-explains-how-to-deal-with-imposter-syndrome">be found to be a fraud</a>.</p>
<p>I try to leverage the fear I feel to help me assemble the best content I am able (at least within my time and resource constraints). When I am writing, or preparing a talk, I also do a lot of fact checking. Since I never want to put anything into the world that I can&rsquo;t back up later, I do my best to make sure I&rsquo;m right. In the process I also learn more about the topic. That even means correcting information I was preparing because my initial understanding was wrong.</p>
<p>On the flip side I try not to let the <a href="https://en.wikipedia.org/wiki/Perfect_is_the_enemy_of_good">perfect be the enemy of the good</a>. I require myself to post on my blog once a month – limiting my editing time. Similarly conference talks have a hard deadline. Those deadlines force me to complete content on a schedule, not when it&rsquo;s perfect. So be it.</p>
<p>When you share what you know people start to see you as an expert. That can lead them to ask you questions that push you to learn <em>more</em>.</p>
<p>All that can lead you to <em>be</em> an expert.</p>
<h2 id="make-friends">Make Friends</h2>
<p>Making friends is easier for some of us than others. And maintaining <a href="https://www.gse.harvard.edu/ideas/usable-knowledge/24/10/what-causing-our-epidemic-loneliness-and-how-can-we-fix-it">friendships in our current society is extremely hard</a>. But friendships are super important. They help keep us healthy, mentally fit, and happy. Friends also teach us really important things about the world around us.</p>
<p>If you have read this blog much you are used to seeing me make references to my friends as sources of information. They are my greatest resource for learning (and a bunch of other things too). Friends know stuff we don&rsquo;t know. Even better, they will <em>tell</em> you things you don&rsquo;t know. Good friends don&rsquo;t judge you for your gaps, but are happy to help you fill them.</p>
<p>I value the input and perspective that friends share with me. We don&rsquo;t have to agree on everything. We don&rsquo;t have to be interested in the same technologies. In fact both of those conditions help me understand things I wouldn&rsquo;t know about otherwise.</p>
<p>I cite my friends in my writing because they are important. They deserve credit when they teach me things. Processing ideas with my friends helps me test them for quality. Often they point out errors in my thinking. Those are all good things.</p>
<h2 id="be-curious">Be Curious</h2>
<p>This is one of the most important lessons I learned from <a href="/2023/12/goodbye-mom/">my mom</a>. She was a deeply curious person and that rubbed off on my sister and I. We both remember her dragging us to <a href="https://dfwi.rpi.edu/outreach/lecture-series">lectures at the RPI Freshwater Institute in Bolton&rsquo;s Landing, NY</a> (it&rsquo;s fun to discover those still happen – I highly recommend if you&rsquo;re in the area). And the time she took us to a ranger talk at a National Park where the ranger offered a postcard to anyone who asked a question he couldn&rsquo;t answer – she promptly earned all his postcards with questions she genuinely wanted answered. She would stop and talk to keepers at the <a href="https://www.philadelphiazoo.org">Philadelphia Zoo</a> to learn more about the animals (a habit my wife and I both now share).</p>
<p>Because of her constant interest in, well just about everything, I have been to historic sites, factory tours, art and science museums, zoos, and many other places. My wife – a curious person herself with her own curious parents – and I continue those kinds of adventures. We go places, we ask questions, and we learn things.</p>
<p>We also read widely, both in our professional fields, and about the world in general. Long drives often involve several hours of listening to podcasts featuring experts in a variety of fields. I&rsquo;ve previously talked about those as <a href="/2022/08/my-ongoing-liberal-arts-education/">my ongoing Liberal Arts education</a>.</p>
<p>If you aren&rsquo;t someone who was trained to be curious by your family, it turns out you can do things to <a href="https://bigthink.com/the-learning-curve/5-habits-increase-curiosity/">increase your curiosity</a>. And yes, I found that article cause I was curious to know if curiosity is trainable – there are <a href="https://link.springer.com/article/10.1007/s12144-022-03107-w">deeper articles on curiosity</a> out there too.</p>
<p>The value in being curious is that it causes you to learn things you might otherwise have missed. Some of those things just make you smarter about your world – and the world needs more smart people. Others will suddenly pop up in your work and make you better at your job. They might come up in random conversation with a new friend and deepen your connection to another person.</p>
<p>Learning new things is never a bad idea.</p>
<h2 id="always-learn-more">Always Learn More</h2>
<p>All this advice boils down to this central idea: <em>always being learning something new</em>. It&rsquo;s <a href="https://www.health.harvard.edu/mind-and-mood/train-your-brain">good for your brain</a> and good for your life (oh yeah, and career).</p>
<p>Reading through all of this commentary on professional development you might think: &ldquo;Wow, that takes a lot of time!&rdquo; But if you put yourself into a mindset of always trying to learn something new much of that times starts to overlap with other activities in life. And when it&rsquo;s not <em>all</em> dedicated directly to work it doesn&rsquo;t burn you out the way constant study of one technology of platform can.</p>
<p>Push yourself forward. Find things that are interesting to you. Nothing new is a waste of your time.</p>
]]></content:encoded> </item> <item>
      <title>My Self Documenting Code Doesn&#39;t Need to be in Git: and Other Lies Salesforce Developers Tell Themselves</title>
      <link>https://spinningcode.org/2025/06/my-self-documenting-code-doesnt-need-to-be-in-git/</link>
      <pubDate>
        Sun, 01 Jun 2025 00:00:00 +0000
      </pubDate> <guid isPermaLink="false">https://spinningcode.org/2025/06/my-self-documenting-code-doesnt-need-to-be-in-git/</guid>  <description>Developers love to lie to themselves. Herein you&amp;#39;ll find some of the worst lies Salesforce developers use on themselves.</description> <content:encoded><![CDATA[<p>One of the things that consistently surprises me as a developer in the Salesforce eco system are the lies developers are comfortable telling themselves. Some lies (like that their code is self-documenting) are common developer myths. Others (like not needing git) are Salesforce community specific.</p>
<p>So, as a public service to the community, I provide here a list of common lies and a sentence or two about why you should stop telling them.</p>
<h2 id="my-code-is-self-documenting">My code is self-documenting</h2>
<p>Not once in my career have I heard a developer say this and found their code to be &ldquo;self-documenting&rdquo;. Never. Nope. (If we&rsquo;re friends: yeah, not even yours.)</p>
<p>Developers who <em>claim</em> to write self-documenting code seem to solve problems in the least-obvious way available. Or at least it feels that way to me. Maybe if they left comments explaining <em>why</em> they used their approach it would seem brilliant. I don&rsquo;t know; it&rsquo;s never come up.</p>
<p>Self-documenting code doesn&rsquo;t mean following a variable naming convention and having <em>no comments at all</em>. You still need doc comments. You still need good functional decomposition. You still need comments to say <strong><em>why</em></strong> your code does things. Sure, I can usually figure out <em>what</em> it does, but not why.</p>
<p>If you still want to argue with me make sure you read <a href="https://web.eecs.umich.edu/~weimerw/2018-481/readings/mythical-man-month.pdf">Chapter 15 of Mythical Man Month</a> before calling.</p>
<h3 id="see-also-nobody-else-needs-to-understand-this-code-im-the-only-one-working-on-it">See Also: Nobody else needs to understand this code; I’m the only one working on it</h3>
<p>Just because you are the only one working on it right now, doesn&rsquo;t mean that will be true 4 years from now. I recently had to update code that had been running happily without attention for 5 years. By the time I was working on it, everyone had forgotten it <em>existed</em> let alone how it worked.</p>
<p>And don&rsquo;t forget <strong><em>you</em></strong> might be that person who needs to remember these details 5 years from now. Guess who I called first when we realized that code needed updating? Yup, the guy who wrote it. No, he didn&rsquo;t remember why he had made important choices either.</p>
<p>The only time I am <em>not</em> disappointed in the person who committed code in my name 6 months ago is when he wrote me really good comments to explain what he was thinking. When he didn&rsquo;t do that: that guy was an idiot.</p>
<p>Future you, your colleagues, friends, clients, strangers, they all will thank you for explaining yourself. Doesn&rsquo;t that feel better than having them all hate you?</p>
<h2 id="i-dont-need-to-use-git">I don’t need to use Git</h2>
<p><strong>Yes.</strong>
<strong>You.</strong>
<strong>Do.</strong></p>
<p>It’s 2025. Bell Labs <a href="https://en.wikipedia.org/wiki/Source_Code_Control_System">invented source control in 1972</a>. “I don’t know how to use it” isn’t a valid excuse. If you’ve been putting off learning to use these tools, it’s time you admit they aren’t going away.</p>
<p>Just because the code exists in a Salesforce sandbox org does <em>not</em> mean you don’t benefit from tracking its history, knowing who (including you) changed what when (and if <a href="https://xkcd.com/1296/">they wrote good comments</a> why!). The first time it saves you because another developer overwrote your code, it’ll have saved you all the time setup required and more.</p>
<p>I can setup a new repository, with Salesforce configuration, in 90 seconds. It takes 10 seconds to do a commit. Sure, you can have merge problems sometimes – that usually happens when two people make conflicting changes. When do you need source tracking the most? When two people make conflicting changes.</p>
<p>When you see two sandboxes with two different versions of code, how do you know which is right? On my projects it&rsquo;s the one that matches Git, cause Git is always canonical.</p>
<p>There really is no <em>good</em> argument against putting every line of code into a repo. Just because you <em>have</em> an argument does not mean you have a <em>good</em> argument. It&rsquo;ll take you less time to start using Git than it will take to argue with me.</p>
<h3 id="see-also-ill-just-comment-out-this-section-of-code-for-now-and-delete-it-later">See also: I’ll just comment out this section of code for now, and delete it later</h3>
<p>No you won&rsquo;t. Nope, stop kidding yourself. I&rsquo;ve seen your 200 line blocks of commented out &ldquo;stuff&rdquo; (without notes about why it was there in the first place, or why it&rsquo;s commented out). You want to keep it for 3 or 4 minutes while you test a change – okay sure. But this is part of what source control does for you. Deleted something you want back? Okay, go get it out of your source control system. Delete your block of commented out code before your next commit.</p>
<h2 id="i-will-fix-this-hard-coded-id-later">I will fix this hard-coded ID later</h2>
<p>If it&rsquo;s easy to fix, just do it now.</p>
<p>If it&rsquo;s going to be a bunch of work later, you know as well as I do that you&rsquo;ll find excuses not to bother at that point either.</p>
<p>Either write the query to get the Id you need now, or move it to custom metadata/setting/environment variable/whatever now. It&rsquo;ll take probably take 5 minutes to do it right now, and 20 minutes to <em>find</em> the stupid thing later (and 10 minutes to fix it cause you&rsquo;ll be tired from the 20 minute hunt).</p>
<h2 id="my-invocable-action-doesnt-need-to-be-bulkified">My invocable action doesn’t need to be bulkified</h2>
<p>Sure, damn near every example invocable action only processes the first record in the list. Yes, that encourages us to think it&rsquo;s okay to write code that way. And yes, bulkifying code is hard sometimes.</p>
<p>You might <em>think</em> that your record triggered flow will only need to deal with one user-entered update at a time. And then someone loads a 100,000 records and your action breaks the whole process.</p>
<p>And sure, you always <em>feel</em> like your action is only getting used in that one Screen Flow. But 9 months from now when someone realizes they can get the inputs other ways and call your action with the screens and puts it in a record triggered flow your code will still work.</p>
<p>There <em>exist</em> settings where the screen flow thing is true. They are rare, but I&rsquo;ve seen them. Use this measure to determine if it applies to your project: if you cannot write a rigorous proof which is good enough for your high school geometry/trig teacher (college CS or Math Professors will also count here) to accept showing this code will only ever be run in a one-record context – you better plan for 200 records.</p>
<h2 id="i-will-convert-this-test-setup-to-use-a-data-factory-when-i-have-more-tests">I will convert this test setup to use a data factory when I have more tests</h2>
<p>Why? Why would you think you will take the time to do this conversion later? When you arrive at “later” you will just need one more object added to your setup. Or maybe 2. And you can copy-paste it into the next test setup method. Then may add 2 more objects. And then <a href="https://www.neverjust.net/">you’ll just</a>…</p>
<p>If you don’t lay down good patterns up front, you won’t convert to them later. Starting a <a href="https://trailhead.salesforce.com/content/learn/modules/apex_testing/apex_testing_data">test factory class</a> doesn’t take a lot of time. Just do it now, and thank yourself later when you realize you’ve slowly built a factory that’s supporting 5 different test suites and hundreds of tests.</p>
<h2 id="ill-move-my-business-logic-out-of-the-trigger-once-its-working">I’ll move my business logic out of the trigger once it’s working</h2>
<p>Once your code is working you have almost no incentive to clean it up. Chances are you&rsquo;ll just deploy your code and wash your hands of it. It wont be until you&rsquo;re neck deep in a conflicting sets of requirements that you&rsquo;ll decide it&rsquo;s time to refactor this mess – and then you&rsquo;ll wonder what each conditional was for in the first place (see self-documenting code above).</p>
<p>Even during a recent technical interview, I took the 15 seconds needed to create the trigger and have it call a service class. I didn&rsquo;t plan to keep that code for more than 15 minutes and I still bothered. I really think it took 15 seconds. Bing, bang, done. Sorting it out later is so much harder then just doing it on the first pass.</p>
<h2 id="as-longs-as-i-hit-the-test-coverage-requirement-my-tests-are-good-enough">As longs as I hit the test coverage requirement, my tests are good enough.</h2>
<p>Automated test coverage is not about hitting a certain number of lines run – that&rsquo;s the minimum threshold. Good automated tests ensure you code works <em>correctly</em>. Good test coverage now means that when you revise the code later you know if your revisions broke something.</p>
<ul>
<li>Do not play games with getting the coverage percentage up.</li>
<li>Do not have tests with no assert statements.</li>
<li>Do not decide that 75% is just fine because to get to 90% you&rsquo;d have to write three more tests – write the three tests!</li>
<li>Do not let test coverage meaningfully changes when someone auto-formats your code.</li>
</ul>
<p>Write tests that ensure your code meets specifications, not tests that make the deployment process happy.</p>
<h2 id="i-dont-need-automated-code-standards-enforcement">I don’t need automated code standards enforcement</h2>
<p><a href="https://developer.salesforce.com/docs/platform/salesforce-code-analyzer/overview">Salesforce Code Analyzer</a> is a free tool you can install right now and will help ensure you don’t do stupid stuff in your code. It will also make sure you team follows the same habits. These tools have been around for Salesforce developers for years, but for some reason we don’t all consistently turn them on.</p>
<p>This is standard fare for professional developers. What makes you special that you don&rsquo;t need to follow standards? Why would you think you can enforce standards on a team without automation?</p>
<p>Every time I have to do a commit to reformat code to be consistent with all the other code on a project, a [insert sad thing here] happens. This pretty much only comes up with people who don&rsquo;t have auto-formatting of their own. Their code had blends of tabs and spaces, different line endings within the file, off-by-one spacing error (dear God I hope no one uses 3 on purpose), and all kinds of things that cause other editors to sputter and complain.</p>
<p>If you don&rsquo;t like Salesforce&rsquo;s default analyzer rules, you can setup your own. It&rsquo;s just enforcing ESLint and PMD patterns. I have extremely little interest in debating code standards – <em>just have some!</em></p>
<h2 id="special-thanks-for-shared-salesforce-developer-lies">Special Thanks For Shared Salesforce Developer Lies</h2>
<p>The following people sent me lies to include in this list, and I appreciate their shared pain. My rants about each are mine alone.</p>
<ul>
<li><a href="https://www.linkedin.com/in/peter-churchill-bfc/">Peter Churchill</a></li>
<li><a href="https://www.linkedin.com/in/michelleelizabethhansen/">Michelle Hansen</a></li>
<li><a href="https://www.linkedin.com/in/raul-iii-roque/">Raul Roque</a></li>
</ul>
]]></content:encoded> </item> <item>
      <title>Writing for Developers and Consultants: Guides and Resources</title>
      <link>https://spinningcode.org/2025/05/writing-for-developers-and-consultants-guides-and-resources/</link>
      <pubDate>
        Sat, 31 May 2025 00:00:00 +0000
      </pubDate> <guid isPermaLink="false">https://spinningcode.org/2025/05/writing-for-developers-and-consultants-guides-and-resources/</guid>  <description>Some guides and suggestions to improve your writing and communication skills as a developer or consulting.</description> <content:encoded><![CDATA[<p>Last year I wrote several pieces on writing for Developer and Consultants (the <a href="https://spinningcode.org/category/writing">writing category</a> will bring them up). That series became a talk on broader communications skills that I gave at Dreamforce 2024, and other settings – including twice this month. Part of that talk includes a series of books and similar resources that weren’t part of the original series. I figured it was time to add them in here.</p>
<p>I want to be clear, these are not the <em>only</em> resources to help you be a better communicator. They are just <em>some</em> resources that I have found useful and I hope you might also find useful.</p>
<h2 id="basics">Basics</h2>
<p>I generally list two works to help with the basic mechanics: <a href="https://www.gutenberg.org/files/37134/37134-h/37134-h.htm"><em>Elements of Style</em></a> and the <em><a href="https://archive.org/details/artofpublicspeak00esenrich">Art of Public Speaking</a></em>. Both are over a century old, and yet still commonly referenced and both still have useful advice.</p>
<h3 id="elements-of-style">Elements of Style</h3>
<p>Commonly referred to as “Struct and White”, <em>Elements of Style</em> is a short and easy to consume guide to writing well in formal English. It’s an excellent starting place for improving formal writing. But it is just that: a starting place. It is committed to helping the readers understand the formal rules – the elements. <em>Elements of Style</em> is not committed to teaching style, or even encouraging your own personal voice. For those things you will need to explore further.</p>
<h3 id="art-of-public-speaking">Art of Public Speaking</h3>
<p><a href="https://en.wikipedia.org/wiki/Dale_Carnegie">Dale Carnage</a> wrote a series of guides in the first half of the twentieth century to help people (mostly men) perform better in white collar work places. He started almost accidentally with the <em>Art of Public Speaking</em>. Many of his guides are still commonly read and referenced – almost to the point of being cliché (<em><a href="https://en.wikipedia.org/wiki/How_to_Win_Friends_and_Influence_People">How to Win Friends and Influence People</a></em> is also his). While his works are certainly somewhat dated at this point, the basic instructions on how to use your voice, organize your thoughts, and even the practice exercises it includes are still extremely useful when working on how to improve your speaking presence.</p>
<h2 id="further-explorations">Further Explorations</h2>
<p>As you gain comfort with the formal rules and techniques, you may find you struggle to find your own voice within those rules. The good news is that you don’t actually have to follow those rules all the time – <a href="https://spinningcode.org/2024/05/writing-for-developers-and-consultants-use-of-language/">just when it suits your needs</a>. But learning how to manipulate the rules gives you control and freedom over the language. You might also find you want tools beyond just words to accomplish your goals.</p>
<h3 id="test-the-limits-of-grammar">Test the Limits of Grammar</h3>
<p>Lynn Tross’s <a href="https://www.amazon.com/Eats-Shoots-Leaves-Tolerance-Punctuation/dp/1592402038">Eats, Shoots &amp; Leaves</a> helps with the first of those two goals. She has an entertaining approach to looking at how and why punctuation matters. But she also makes it clear that some uses are about style as much as clarity. She encourages her reader to both take punctuation seriously and to have fun with it. With her insights you can think about how to bend, twist, and even break the rules outlined in guides like Stuck and White. I know several people who found her guidance helped them take more control over all parts of their writing.</p>
<h3 id="dont-only-use-words">Don’t Only Use Words</h3>
<p><a href="https://www.youtube.com/watch?v=84lVphpwFYg">Dan Roam’s</a> <a href="https://www.amazon.com/Blah-What-When-Words-Dont/dp/1591844592/">Blah, Blah, Blah</a> provides ideas for how to handle the second of those challenges: what to do when words alone don’t work. It provides an overview of why and how to use images to help improve your presentations and writing. Like all the others it can give you ideas and inspiration. Where you go from there should be your own interpretation of those ideas and suggestions.</p>
<h2 id="keep-going">Keep Going</h2>
<p>Reviewing materials that are meant to train you in basic techniques is necessary, but not sufficient. You need to take the time to see how other experts use those techniques in practice. The good news is that just about anything on a technical topic can be helpful here.</p>
<h3 id="more-readings">More Readings</h3>
<p>For reading on technical issues I tend to personally suggest well known works. Books because well know, because they are good (usually). Books stay important because they have important ideas – even if we have moved away from the details.</p>
<p><a href="https://archive.org/details/mythicalmanmonth00broo">Mythical Man Month</a>, for example was often required reading for developers and project managers for decades. While we want to believe our field advances so fast that a book first written in the late 1960’s is ancient history, the content is surprising relevant. It has held on so long because Fred Brooks covered important ideas and because he expressed them well.</p>
<h3 id="speeches-and-keynotes">Speeches and Keynotes</h3>
<p>Listening to speeches, watching videos of great talks can be excellent as well. The obvious choice here is to watch <a href="https://www.ted.com/">Ted Talks</a>. The only down side to those is they can be intimidatingly good. They have an extremely high production quality, world renowned speakers, and a well trained team to make it all happen. While I find that content excellent and inspiring, I would never try to match their production quality for a talk I’m giving at a local user group meeting.</p>
<p>For that I look to more simplistic content. When I commuted by train many years ago I would listen to talks published on the <a href="https://archive.org/details/conversationsnetwork_org">old Conversations Network</a> because they were interesting, audio only (so good for public consumption), and sometimes flawed – I could imagine myself giving talks like that. More recently I’ve taken up listening to podcasts from the <a href="https://freakonomics.com/podcasts/">Freakonomics Radio Network</a> and other places that are polished and high quality, but not so much that you can’t imagine reaching their level. Particularly shows outside their flag-ship Freakonomics are a little rougher around the edges while still being a good listen with interesting ideas.</p>
<h2 id="practice">Practice</h2>
<p>All of these resources are only useful if you put them to work. I’ll talk about this more in a future article, but to really get good at this you’re going to need to practice. Nearly everything in life improves through practice, including your communication skills. To really get good at this, plan to put in some work. And expect to fail sometimes. It’s how we all learn and grow.</p>
<p>As I said in <a href="/2024/02/writing-for-developers-and-consultants-editing/">my first post on this topic</a>, communications skills for developers and consultants is an enormous topic. The plan for this series is evolving as I go. If you have suggestions or requests feel free to leave me a message.</p>
]]></content:encoded> </item> <item>
      <title>Tips for Salesforce Exams Part 2 – Taking the Exam</title>
      <link>https://spinningcode.org/2024/10/tips-for-salesforce-exams-part-2-taking-the-exam/</link>
      <pubDate>
        Sat, 05 Oct 2024 18:36:35 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=2236</guid>  <description>&lt;p&gt;This is a second in a two part series on taking Salesforce Certification Exams. We&amp;rsquo;ll be talking here about taking the exam. You might also find &lt;a href=&#34;https://spinningcode.org/2024/09/tips-for-salesforce-exams-part-1-studying/&#34;&gt;part 1 on studying&lt;/a&gt; useful.&lt;/p&gt;
&lt;p&gt;For this discussion I&amp;rsquo;m assuming you have picked your exam, studied as best you can, and now it&amp;rsquo;s time to take the exam.&lt;/p&gt;
&lt;h2 id=&#34;scheduling-a-salesforce-exam&#34;&gt;Scheduling a Salesforce Exam&lt;/h2&gt;
&lt;p&gt;In my article on studying I recommended scheduling your Salesforce exam a week or two after you had prepped your flash cards. Of course it&amp;rsquo;s not exactly that straight forward. You need to pick the location and timing that works to your best advantage.&lt;/p&gt;</description> <content:encoded><![CDATA[<p>This is a second in a two part series on taking Salesforce Certification Exams. We&rsquo;ll be talking here about taking the exam. You might also find <a href="/2024/09/tips-for-salesforce-exams-part-1-studying/">part 1 on studying</a> useful.</p>
<p>For this discussion I&rsquo;m assuming you have picked your exam, studied as best you can, and now it&rsquo;s time to take the exam.</p>
<h2 id="scheduling-a-salesforce-exam">Scheduling a Salesforce Exam</h2>
<p>In my article on studying I recommended scheduling your Salesforce exam a week or two after you had prepped your flash cards. Of course it&rsquo;s not exactly that straight forward. You need to pick the location and timing that works to your best advantage.</p>
<h3 id="location">Location</h3>
<p>Salesforce exams can be taken in a testing center or from home. Before COVID I took my exams in-person at a local testing center located at a university – it was re-assuring that if there were issues I could discuss it with staff in person, although it never came up. When COVID arrived, like everyone else, I had to move online – and my local testing center never re-opened to non-students for first health and now security reasons. Currently I&rsquo;d have to drive over an hour to reach an in-person location so I continue to take mine online. All that is to say I have done both, and both can work just fine.</p>
<p>The exact rules for at home tests have shifted a few times, but generally they have all been reasonable (at least since they dropped the two camera requirement). I do get interrupted by support if there is an internet connection flutter, or if an hour or so in my mind – and more importantly eyes – start to drift a bit. But on the whole my home is less distracting than dealing with the challenges of driving, parking, getting checked in, and all the other logistics of an in-person location. If you have potential distractions in your home, like kids home from school, bad wifi, lack of a room you can close off, and other things those in-person logistics might be a great trade for you.</p>
<p>On the whole, I prefer taking tests from home. That said, the most important thing about the location is that you are comfortable enough about the setting that you can stay focused on the test.</p>
<h3 id="time">Time</h3>
<p>The location you select will drive the dates and times available to you, but both have limited options. Plan ahead if you want a specific time and day – I&rsquo;ve had to put off exams a week or two just to find a reasonable time of day to take the exam.</p>
<p>For online exams I have found there are 5 times of year to avoid: late December, and late in a Salesforce quarter. December that&rsquo;s because people who work at partners often have to take one a year and procrastinated. As for the quarters, I think that&rsquo;s because those same partner companies have exam vouchers that are about to expire so they push people to use them up, and Salesforce staff are meeting performance deadlines. Sometimes, I have no idea what&rsquo;s driving the demand, but there will suddenly be no open slots.</p>
<p>Generally, you want a time when you&rsquo;ll be awake and sharp. If taking the test from home, that should also mean it&rsquo;s a time your home is quiet. Pick a time when your partner, or school district, can watch the kids – or everyone else is sleeping. If you are a night owl, and like taking exams in the middle of the night (US-time at least), you&rsquo;ll have more choices. Personally I like late morning: I&rsquo;m through my coffee, dealt with whatever fires have started me day, and still have lots of energy.</p>
<h2 id="remember-your-basic-test-skills">Remember Your Basic Test Skills</h2>
<p>Most of us took lots of standardized tests in school. The test taking skills you should have been taught for those apply to Salesforce exams. Salesforce exams are, fundamentally, the same things as objective standardized tests you took in school – who knew all those test taking skills would actually be job skills?</p>
<h3 id="change-answers-carefully">Change Answers Carefully</h3>
<p>Turns out that the thing about <a href="https://journals.sagepub.com/doi/10.1177/009862838401100303">never changing answers is wrong</a>. But that doesn&rsquo;t mean second guess yourself. Change the answer when you know it&rsquo;s wrong, if you&rsquo;re still just guessing move on. Sometimes as you proceed through the exam you&rsquo;ll notice later questions that give away the answer to one you guessed at – that&rsquo;s a great time to go back if you marked it or have the time to find it.</p>
<h3 id="eliminate-wrong-answers-and-guess-wisely">Eliminate Wrong Answers and Guess Wisely</h3>
<p>Depending on the exam you will have 3 or 4 answers available to you – you are looking for the best fit to the details of the question. Writing wrong answer is incredibly hard, usually some of the wrong answers are really bad. So if the answer isn&rsquo;t immediately obvious look for a few giveaways to bad answers:</p>
<ul>
<li>Products that don&rsquo;t exist. If part of the answer is not a thing – that&rsquo;s not the right answers.</li>
<li>Not being part of a pair. Sometimes there are a pair of answers that are very similar, in my experience it&rsquo;s one of those two so ignore the others. In those pairs the difference is usually from a detail of the question. Go scan for a condition that would trigger one or the other.</li>
<li>Answers leveraging information that&rsquo;s not part of the exam outline: Right answers must be part of the exam outline, wrong answers can include other things. If you&rsquo;re taking an exam where Person Accounts aren&rsquo;t part of the outline – the answer with Person Accounts in it is wrong.</li>
</ul>
<p>If you can cut out the bad answers, and get yourself to a 50/50 guess you&rsquo;re in a good place on most exams as long as you are not always guessing. Your goal is to pass, a few mental coin tosses that keep you moving will keep you in range. You don&rsquo;t need 100% to pass, so don&rsquo;t worry about a few wrong answers. As long as your guesses are rare and you&rsquo;ve eliminated a few answers, you&rsquo;re golden.</p>
<h4 id="answer-every-question">Answer Every Question</h4>
<p>If you have no idea about a question, guess randomly. Just pick an answer that sounds plausible and move on. This is not the SAT where you can lose points for the wrong answer. A right answer is one point. A wrong answer is zero points. A blank is always wrong – and still zero.</p>
<h3 id="read-the-answers-first">Read the Answers First</h3>
<p>I don&rsquo;t do this for all questions, but some questions are long, and include extra detail you don&rsquo;t need to select the right answer. When I see I long question I read the answers, try to eliminate at least one, and then scan the question for details that matter to the remaining answers. Even if I still read the whole question I am extracting the important bits not all the details of why Cloud Kicks wants to encourage adoption or improve security. More than once I&rsquo;ve been able to eliminate all but one answer, select it, and move one without even reading the question.</p>
<h3 id="know-your-timing">Know Your Timing</h3>
<p>Like with so many things in life, timing is important. Before the test starts know how many questions you have and what&rsquo;s your total time. The test will tell you when you start, but you want to have a sense going in how fast you need to be moving.</p>
<p>Most exams have 60 questions and give you 105 minutes (1 hour 45 minutes). That&rsquo;s a whopping 1 minute 45 seconds per question (for context on the SAT allots 1 minute 11 seconds for the reading and writing questions, GRE it&rsquo;s 1 minute 30 seconds). So pace yourself.</p>
<p>The test&rsquo;s clock, which you can and should hide, is in hours and minutes not total minutes. If you aren&rsquo;t great at time math on the fly, give yourself markers about where you should be at the 20 (&gt; 1:10 remaining), 30 (&gt;52 minutes remaining), 40 (&gt;35 minutes remaining) question points. I slow down as the test proceeds, so I actually like a larger margin earlier in the test so I can be running over time in late questions.</p>
<h3 id="note-your-weaknesses">Note Your Weaknesses</h3>
<p>You are given a scratch pad for the exam: either a physical piece of paper in a testing center, or a text box online. As soon as you sense you are struggling use it to record your weaknesses. No details, not whole questions, just topics to study later.</p>
<p>You aren&rsquo;t allowed to keep or copy the notes directly, so you need tags you can use to memorize enough information to go augment your study later. I usually haven&rsquo;t needed it, but when I took Integration Architect recently I realized a few questions into the exam there were multiple references to things I hadn&rsquo;t studied – oops. In my case it was <a href="https://developer.salesforce.com/docs/atlas.en-us.api_streaming.meta/api_streaming/pushtopic_events_intro.htm">PushTopics</a> and <a href="https://developer.salesforce.com/docs/atlas.en-us.change_data_capture.meta/change_data_capture/cdc_intro.htm">Change Data Capture</a>. I wrote just that much in the notes, so when I got to the end I could quickly memorize the need to create flash cards covering those topics to my deck. I failed my first attempt, augmented my flashcards with the topics I&rsquo;d missed in my study, and passed easily on the second attempt.</p>
<p>On several other exams where I was close to the line, noting those topics helped me stay calm because I had a plan if I needed to do more prep.</p>
<h2 id="salesforce-exam-specific-skills">Salesforce Exam Specific Skills</h2>
<p>The biggest thing I&rsquo;ve found that&rsquo;s Salesforce specific is thinking about the context of the exam to help guide guessing. When guessing, try to think like Salesforce, and know some basic rules for the exam you&rsquo;re taking:</p>
<ul>
<li>Admin Exam: never say you&rsquo;d contact support, and always say you&rsquo;d check the App Exchange.</li>
<li>Platform App Builder: never say you&rsquo;d write code, pick the declarative answer.</li>
<li>Platform Developer: You still aren&rsquo;t calling support, never have a DML in a loop.</li>
<li>Architect Exams: use a recent – but not latest – Salesforce technology to solve the problem.</li>
<li>AI Exams: Be ethical.</li>
<li>Advanced Exams (Advanced Admin, PD II, etc): You might need to contact support to enable features or change settings in rare use cases. Generally know your negative use cases – when not to do something you&rsquo;d select on the basic exams.</li>
</ul>
<p>Most Salesforce exams have a similar pattern that can help you guess. Ask around your network for people who have taken the exam you&rsquo;re attempting.</p>
<p>Generally there are some overall messages Salesforce wants people with that certification to have secured in their heads. Figure out what those messages are, and leverage them to help drive success.</p>
<h2 id="good-luck">Good Luck!</h2>
<p>That&rsquo;s the advice I have to offer. Good luck on your next Salesforce Exam. And if for some reason you don&rsquo;t pass the first time, pick yourself up, dust yourself off, and schedule the retake. There&rsquo;s no way through but forward.</p>
]]></content:encoded> </item> <item>
      <title>Tips for Salesforce Exams Part 1 – Studying</title>
      <link>https://spinningcode.org/2024/09/tips-for-salesforce-exams-part-1-studying/</link>
      <pubDate>
        Wed, 25 Sep 2024 01:59:25 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=2234</guid>  <description>Suggestions about how to prepare for the first, or next Salesforce Exam.</description> <content:encoded><![CDATA[<p>Salesforce certification exams are a fact of life for many of us in the eco system. Whether you are a consultant who needs to add at least one a year or taking your first exam it&rsquo;s important to have a plan for how you approach your next test. Getting through Salesforce Exams generally requires a mix of memorization, understanding key concepts, and good test taking skills.</p>
<p>Currently I hold 13 Salesforce certifications and have survived 12 exams to get there (there are a couple two-for-ones to be had among the Architect exams) and I passed all but one on the first try. This is by no means makes me exceptional – my current manager holds somewhere between 35-40 certifications, I lost track a test or two ago – but it does mean I&rsquo;ve taken enough to develop a routine that works pretty well.</p>
<p>What I&rsquo;m offering here is an outline to what I do. From talking with friends who have mimicked my routine it seems to work well for others as well.</p>
<p>I should note: I am <em>not</em> a Salesforce Certified Technical Architect (CTA). This guide is <em>not</em> meant to help you pass the CTA exam or project, although it should help you with everything that comes in earlier phases of that journey. If I ever decide to put myself through the CTA process, I expect I&rsquo;ll write a bit about that process, but in the meantime I&rsquo;m not qualified to speak to it. I am also <em>not</em> currently on an exam advisory panel – take the exams not write them.</p>
<h2 id="choosing-a-salesforce-exam">Choosing a Salesforce Exam</h2>
<p>Before you can study for an exam, you need to decide which one you&rsquo;re taking. You want to study for the right exam after-all. When picking exams there are many considerations, but let me dispel a couple myths:</p>
<ul>
<li>There is no one exam that will land you a job. Certification is useful, and for some jobs essential, but employers are looking for more than <em>just</em> certification. So a specific certification might help, but it&rsquo;s not enough by itself.</li>
<li>There is no one path through the collection of certifications. I think historically there might have been a reasonable path through the certifications that made default sense. But at last count there were more than 40 certifications out there. Salesforce adds several a year.</li>
</ul>
<p>You need to figure out what certification benefits you the most. The benefit could be helping improve you resume. It could be helping your employer land new deals (but make sure they give you tangible credit for helping land those deals). Sometimes your employer told you have to take one this year and just need a pass.</p>
<h3 id="salesforce-exam-career-tracks">Salesforce Exam Career Tracks</h3>
<p>Salesforce organizes certifications by career track. There are exams for admins, developers, consultants, architects, and more. You don&rsquo;t need to confine yourself to any one of those areas – I have certifications from four categories. The career track the exam is aimed at helps you understand the kind of information you can expect and it&rsquo;s level of complexity. But you should not use it as your sole guidance.</p>
<p>Administrators are expected to know how to do the work of setting up Salesforce, so the questions are focused on which settings enable which features.</p>
<p>Architects are expected to make strategic decisions about which features to use, so the questions are focused on understanding the when to use a feature based on its technical characteristics. Consultant exams are similarly focused on when to recommend features, but are generally easier that architect exams although they do add in information about understanding the role of a consultant. The nonprofit and education consultant exams also expect you to know information about how those kinds of organizations work.</p>
<p>Developer exams expect you to read and understand Salesforce-related programming languages, know how the code will operate, and what errors to expect. Except for Platform Developer II, which requires a super badge, they do <em>not</em> currently expect you to write code.</p>
<h3 id="salesforce-exam-difficulty-and-pass-thresholds">Salesforce Exam Difficulty and Pass Thresholds</h3>
<p>When you select an exam, you need to understand the intersection of difficulty and the passing threshold. Some exams are just plain harder than others. But Salesforce has internal expectations about ensuring that a reasonable number of people who attempt the hard exams also pass those exams. While I don&rsquo;t know what those numbers are, the place they are most obvious is when you look at passing threshold.</p>
<p>Each exam has a defined percentage score to pass. When it is in the 70-80% range, you&rsquo;re looking at an exam where the questions are right about on target for the audience taking that exam to pass at the rate Salesforce wants. When you see thresholds in the 60% range, the test is much harder – so Salesforce lowered the bar instead of making the questions easier.</p>
<p>If you know an area really well, and see a low passing threshold, that&rsquo;s a great exam to target if you just need to pass one. If you don&rsquo;t know that area well, be warned that&rsquo;ll be a hard exam. Conversely, an exam with a high pass threshold has easy questions, which many lull you into a false sense of security as you take the exam.</p>
<p>Associate Exams are designed to have high pass rates. Architect exams are designed to have a lower pass rate. With most exams falling between those two points.</p>
<p>Understanding the required pass threshold can help determine how, and how long, you need to study.</p>
<h2 id="preparing-for-a-salesforce-exam">Preparing for a Salesforce Exam</h2>
<p>Salesforce exams are a lot like standardized tests from high school: nearly all multiple choice and conquerable if you memorize a bunch of information. It helps to understand <em>why</em> the platform does certain things to support guessing, but mostly you need to know <em>what</em> the system does.</p>
<p>Knowing that, once I&rsquo;ve selected a Salesforce exam to take, I prepare in two phases:</p>
<ol>
<li>Review official materials and create flash cards</li>
<li>Study the flash cards</li>
</ol>
<p>Salesforce provides a break down of the content of each exam in both the exam guide and the official Trailhead Trailmix. In theory they include everything in those you will need to pass the exam – mileage here will vary. The lower the exam level, the better this material. For the architect level exams sometimes there are gaps you&rsquo;ll need to fill to understand what information they are testing.</p>
<p>My first step in preparing for an exam is to review the exam guide, and all the information on the trailmix. I make my own flash cards from that information and then my second step is to study those flash cards until I take the exam. That&rsquo;s all there is to it – memorize a bunch of stuff.</p>
<h3 id="exam-outline">Exam Outline</h3>
<p>The most important part of the official materials is the Exam Outline. Test creators are required to make sure these outlines are correct. There may be extra information or gaps in the Trailmix, but the outline is required to be complete and correct. Use the outline to help guide you as you create your flashcards.</p>
<h3 id="what-about-3rd-party-study-materials">What About 3rd Party Study Materials?</h3>
<p>There are several sources for 3rd party study materials. Usually these services cost a few dollars, and they have what my friends at Salesforce call &ldquo;disturbingly good&rdquo; information about the exam content. It&rsquo;s disturbing to Salesforce cause sometimes it&rsquo;s often good enough to imply someone violated the rules while taking the exam. These third party materials typically come in three forms: courses, practice exams, and flash cards.</p>
<h4 id="courses">Courses</h4>
<p>If the support of a course helps you, great. They don&rsquo;t help me, like most students I can easily disengage when in online courses. For me, they are a waste of money – and as far as I can tell the success rate of people using just a course to prep is very low.</p>
<h4 id="practice-exams">Practice Exams</h4>
<p>Practice exams can be extremely helpful. Until I switched to making my own flash cards I used to use these a lot. Practice exams give you a chance to see questions similar to those you will see on the exam itself. More importantly good practice exams, like the ones from Focus on Force, will give you reference information for where the answer came from in the source documentation. That helps you understand why you were wrong.</p>
<p>You should plan to take the practice exams several times – maybe a dozen or more – before you&rsquo;re ready for the real thing. You need to take them until you are 10-20% above the pass threshold of the exam. While these exams are often good, they also often a little behind the current Salesforce exam – so you should expect a performance gap between what you scored on the practice exam and what you will score on the real thing.</p>
<h4 id="flash-cards">Flash Cards</h4>
<p>Flash cards are, in my opinion, the best solution. I know, we all hate flash cards: they were boring in high school and they are boring now. <a href="https://www.brainscape.com/academy/are-flashcards-effective/">What they are is effective</a>. If your goal is to pass an exam that requires memorizing a bunch of &ldquo;stuff&rdquo; flashcards are where it&rsquo;s at!</p>
<h3 id="make-your-own-flash-cards-yes-really">Make Your Own Flash Cards: Yes Really!</h3>
<p>I make my own flashcards for most exams. And with one exception I passed on the first try. That exception: I accidentally skipped a section of the prep materials and so was missing several cards I needed.</p>
<p>There are a few reasons I make my own flashcards:</p>
<ol>
<li><strong>They are cheap:</strong> a <a href="https://www.staples.com/staples-3-x-5-index-cards-narrow-ruled-white-100-pack-tr50993/product_296608">pack of 100 note cards</a> costs $0.89 at Staples right now. I usually need two packs because I generally create about 120 cards and make a dozen mistakes writing them out so we&rsquo;re taking $1.78 + tax per exam. The <a href="https://focusonforce.com/administrator-certification-study-guide/">Focus on Force Admin Study Guide</a>,which has their flash cards, currently costs $24 – not at all unreasonable but also way more than a buck seventy eight.</li>
<li><strong>Writing them out helps me remember what I&rsquo;m reading:</strong> This is actually the bigger factor than costs. <a href="https://stackoverflow.blog/2022/11/23/why-writing-by-hand-is-still-the-best-way-to-retain-information/"><em>Writing things down helps us remember stuff.</em></a> By putting in the effort to figure out what cards I need, and writing them out, I remember the information better. Also a few times I used sets from Focus on Force (they were good), and it was tiring to write theirs out so I printed them – which added costs and effort.</li>
<li><strong>Writing your own allows you to personalize:</strong> the sets from Udemy, Quizlet, and elsewhere reflect what anyone might need to learn. When you create your own you include what <em>you</em> need to learn. Sometimes I add a few cards that are things I find along the way that I need in my work and aren&rsquo;t likely to be on the exam. I almost always leave out some information I already know very well.</li>
</ol>
<h4 id="risks">Risks</h4>
<p>Creating my own flash cards brings it own risk. I do not have the level of insight that the 3rd party content creators have when they create their content. I also risk including extra material I don&rsquo;t need for the exam <em>or</em> my work, which wastes my time memorizing. Still, on the whole, I favor creating my own flashcards over buying someone else&rsquo;s.</p>
<h3 id="the-right-amount-of-studying">The Right Amount of Studying</h3>
<p>Salesforce Exams are pass-fail. A pass is perfect, and failure is disaster – there is nothing between those two points. That means the ideal amount of studying is when you study just enough to pass the exam by one question.</p>
<p>No one wants to fail an exam because they were unprepared. No one should waste time over studying – we have better ways to spend our time.</p>
<p>I have actually threaded this needle a couple times and passed by a hair&rsquo;s breath. That is a scary feeling because any good test taker knows generally how it&rsquo;s going as they proceed. When you&rsquo;re right on the line it&rsquo;s hard to know which side you&rsquo;re on.</p>
<p>I used to study <em>a lot</em>, particularly when I used a practice exam based approach. It worked, but it took a lot of time to take all those practice exams. With the flash-card based approach I take as long as I need to create my flash cards, and once I&rsquo;m convinced my deck is complete I schedule the exam for a week or two out. For exams with a high pass threshold, or are in an area where I am weak, I give myself two weeks. For exams with a lower pass threshold, particularly if it&rsquo;s an area of strength for me, one week is plenty. During that time I run through the deck once or twice a day.</p>
<p>By exam day, I&rsquo;m ready to go. As long as my deck has what I need, I&rsquo;m good to go.</p>
<h2 id="taking-a-salesforce-exam">Taking A Salesforce Exam</h2>
<p><a href="/2024/10/tips-for-salesforce-exams-part-2-taking-the-exam/">Part 2</a> focuses on exam day, taking the exam itself, and recovering from failure when needed.</p>
]]></content:encoded> </item> <item>
      <title>More Advice from a College Professor&#39;s Spouse</title>
      <link>https://spinningcode.org/2024/08/more-advice-from-a-college-professors-spouse/</link>
      <pubDate>
        Mon, 05 Aug 2024 22:48:27 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=2221</guid>  <description>Advice from a college professor&amp;#39;s spouse about how to succeed in college. Based on my own observations and my own conclusions.</description> <content:encoded><![CDATA[<p>Two years ago my sister&rsquo;s oldest child went off to college. As a marker for that occasion I wrote up <a href="/2021/08/college-advice-from-a-professors-spouse/">some thoughts on what I think college student&rsquo;s should know</a>. In a little while my sister&rsquo;s youngest child is headed off to college as well; so I decided it&rsquo;s time to write part two.</p>
<p>Since my wife <em>is</em> a college professor, and I&rsquo;m framing my understanding as being her husband, I need to be clear: these are my thoughts. They are not hers. They are not those of her colleagues, or any of our other friends who are college professors. Yes, my ideas are influenced by being friends with those folks, and I hope they agree with me. But in the end, this advice is mine. If you want advice from a college professor &ndash; well college students have easy access to those and should politely ask them directly.</p>
<p>Also, for some strange reason it turns out that older child actually reads this blog (despite complaints that the posts about work are boring &ndash; love you too bud, they get the most traffic). So, Ben, open invitation to write a rebuttal or addendum to support your sibling and any other college students who stumble in here.</p>
<h2 id="read-the-syllabus">Read the Syllabus</h2>
<p>While most of this post covers new ground, this point deserves repeating. It was top of mind two years ago, and is top of mind now. When professors talk about things their students do wrong <em>this</em> is what they talk about the most. Yes, the syllabus is boring &ndash; trust me I know, I&rsquo;ve edited plenty of them. Yes they are often oddly long. But they are critical to success, and contain important information like what books to buy, when to read them, and what your deadlines are. So suck it up, and read them! There do exist courses and professors where you can get away without doing this, but it will never hurt you, costs you 15 minutes a course at most, and could save your tail.</p>
<h2 id="take-a-variety-of-things">Take a Variety of Things</h2>
<p>Use college as a time to explore new ideas and different fields of study. When I think about the courses I took in college, it&rsquo;s hard to know how I would have predicted which were going to be valuable to me still 20 years on.</p>
<p>I took a course of censorship taught by a <a href="https://www.hamilton.edu/academics/our-faculty/directory/faculty-detail/frank-sciacca">Russian language professor</a>. That course forced me to think about ideas of self-expression, our laws, and forms of protest. It also gave me ongoing interest in the impact of the work of <a href="https://www.mapplethorpe.org/">Robert Maplethorpe</a> and other controversial American artists. And that interest has left me space for my understanding to grow and change over time.</p>
<p><a href="/2016/10/what-i-learned-by-getting-a-degree-from-a-liberals-arts-college/">Ceramics helped me learn to think critically</a> about my own work. It&rsquo;s a class I cite frequently when working with less experienced developers to help them improve their work.</p>
<p>Non-required CS courses taught me skills I use almost every day at work; more than most of the required courses.</p>
<p>Religious Studies courses forced me to write in a formal way about creative ideas; a skill that serves me well on a regular basis.</p>
<p>I wouldn&rsquo;t have told you any of that was the important take away when I registered for those classes. I took other classes expecting great things, but that failed to deliver for me. So if the class looks vaguely interesting, consider taking it, even if you don&rsquo;t expect it&rsquo;ll help you later.</p>
<h3 id="pay-attention-to-courses-you-cant-take-later">Pay Attention to Courses You Can&rsquo;t Take Later</h3>
<p>There are a few things I didn&rsquo;t take, like English Comp., because they were only open to first and second year students. I wanted to take some of those classes late in my time at <a href="https://hamilton.edu">Hamilton</a>, but was locked out. It was totally my fault because I didn&rsquo;t plan ahead. Plan ahead!</p>
<h2 id="dont-use-all-your-accommodations">Don&rsquo;t Use All Your Accommodations</h2>
<p>This is probably my most controversial piece of advice: Don&rsquo;t use all your learning accommodations.</p>
<p>I want to be clear, I support forcing colleges to provide needed accommodations. Learning accommodations are critically important to the success of many students, and colleges should make everything available to all students who are entitled to have them. But that&rsquo;s the college&rsquo;s side of the relationship. While college&rsquo;s should provide them, students should think critically about which they leverage.</p>
<ul>
<li>Some accommodations are absolutely critical to all who need them.</li>
<li>Some accommodations are critical to some students in some courses.</li>
<li>Some accommodations are offered because we don&rsquo;t teach kids good learning techniques when they struggle.</li>
</ul>
<p>If your accommodation is in the second group reflect on whether or not accommodations in the courses you&rsquo;re taking will support deep learning. When your accommodation is in that last set, seek out better ways to overcome the challenges. You can tell the difference, in part, by asking yourself how the accommodation actually helps you learn better, not just complete an assessment better or <em>feel</em> like you&rsquo;re learning <em>faster</em>. Use the support you <em><strong>need</strong></em> not the support that makes learning <em>feel</em> easy or comfortable. <a href="https://theemotionallearner.com/2019/09/06/why-learning-should-be-difficult/">Learning <em>should</em> be hard</a>. A little friction in the learning process helps you learn better.</p>
<p>Understand that when you finish your BA the number of accommodations available to you will drop significantly. Typical work places are held to a very different standard than educational institutions. Again I believe they should meet their legal obligations, but deadline extensions or &ldquo;extended time&rdquo; may come with consequences for just asking. And graduate programs rarely offer any for non-physical disabilities (just because the law says they should, doesn&rsquo;t mean they do so without consequences).</p>
<p>To thrive after college you will need to find tools of your own to overcome many of the challenges that lead to adjustments being offered in a classroom setting. You might as well start looking for those now.</p>
<h2 id="learn-how-to-learn">Learn How to Learn</h2>
<p>The most important thing to learn in college is how to learn!</p>
<p>The exact facts and figures you learn in college aren&rsquo;t really the point the exercise. They are interesting, and can provide you important insights, but the details won&rsquo;t last. If you go on in a field you&rsquo;ll deepen your knowledge, and likely replace large portions as the field advances. If you don&rsquo;t go on in a field you aren&rsquo;t likely to use exact facts, figures, and formulas. The take aways longer term come in the form of general concepts and stories to help you, hopefully, remember deeper truths.</p>
<p>We live in a world of constantly advancing knowledge. You will need to learn some of that new information after you graduate. You will need to learn some it without the benefit of formal instruction. Make sure you know how to learn independently, without support of professors or formal direction.</p>
<p>You also need to know how to sort good information from bad information. In college your professor will do a lot of this for you. Later it&rsquo;ll be your job. Good information doesn&rsquo;t always agree with you, good information sometimes reveals truths that deviate from your world view. Sometimes what&rsquo;s true forces us to rethink how we act, think, and vote. Be sure you know how to sort the good from the junk.</p>
<h2 id="say-yes-to-things">Say &ldquo;Yes&rdquo; to Things</h2>
<p>When in doubt, say yes to offered experiences. Try things you&rsquo;re unsure about, go places you worry will be boring, listen respectfully to speakers who offend you, go to concerts of artists you&rsquo;ve never heard of, and generally take advantage of opportunities that present themselves.</p>
<p>One of the most memorable talks I attended in college was by <a href="https://en.wikipedia.org/wiki/Oliver_North">Oliver North</a>. No one made me go (that Russian professor made me go see <a href="https://en.wikipedia.org/wiki/Stanley_Fish">Stanley Fish</a>, which I&rsquo;m also glad I did even though he was painfully boring and I disagreed with his pro-censorship argument), it just seemed like I should attend. Listening to him try to justify his crimes was insightful for me. Not because he convinced me of his views, but because it helped me understand the signs of failure; 20 years after his disgrace it was all he talked about. He had supporters in the room, but that was all they were interested in too. It was a night focused on a disgraced past.</p>
<p>The same was true, although to a lessor extent, of <a href="https://en.wikipedia.org/wiki/F._W._de_Klerk">F.W. de Klerk</a> who I got to listen to as he justify his role in apartheid before he became a reformer. <a href="https://en.wikipedia.org/wiki/Desmond_Tutu">Desmond Tutu</a>&rsquo;s talk was a stark contrast as he focused on his then-recent work and how to build on it, not the work that had earned him a Nobel Prize &ndash; that was old news to him. <a href="https://www.cartercenter.org/about/experts/jimmy_carter.html">Jimmy Carter</a>&rsquo;s talk was fascinating (and somehow also almost as boring as Fish), and like Tutu looked forward not back. Hearing all those talks gave me insights I wouldn&rsquo;t have had if I&rsquo;d just heard Tutu and Carter (the ones I agreed with) speak. All North had to cling to was defense of his past, trying to repaint his image. And because it lacked the semi-redemption of de Klerk, his failures rang out all the louder from his defense.</p>
<p>So go try things you don&rsquo;t know if you&rsquo;ll like. You might discover new interests, enlarge your world view, and generally make your life richer.</p>
<h2 id="thats-my-advice-in-this-moment">That&rsquo;s my advice in this moment</h2>
<p>Take it or leave it, that&rsquo;s up to you.</p>
<p>Good luck with college. Go, have fun, and learn great things. The world <em><strong>needs</strong></em> more people who are ready to learn what&rsquo;s coming next.</p>
]]></content:encoded> </item> <item>
      <title>Knowing When to Ask for Help</title>
      <link>https://spinningcode.org/2024/06/knowing-when-to-ask-for-help/</link>
      <pubDate>
        Sat, 29 Jun 2024 01:53:33 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=2199</guid>  <description>&lt;p&gt;One of the skills everyone needs to have is asking for help. Whether that&amp;rsquo;s in our work, our education, or our personal lives, we all need help from time to time. We are focused on work here, but this same basic rules apply in all aspects of our lives.&lt;/p&gt;
&lt;p&gt;The right time to ask for help is, like so many things, a balancing act. Struggling through a complex issue can be a great way to learn something new. But often we can short cut that learning by simply asking the right questions at the right time.&lt;/p&gt;</description> <content:encoded><![CDATA[<p>One of the skills everyone needs to have is asking for help. Whether that&rsquo;s in our work, our education, or our personal lives, we all need help from time to time. We are focused on work here, but this same basic rules apply in all aspects of our lives.</p>
<p>The right time to ask for help is, like so many things, a balancing act. Struggling through a complex issue can be a great way to learn something new. But often we can short cut that learning by simply asking the right questions at the right time.</p>
<p>On the flip side, if we ask too early not only do we risk missing a chance to build deep understanding, we also risk frustrating colleagues by asking them to do our job.</p>
<p>One short cut for when you need to ask for help is if another team member asks if you have already asked. Generally, I want to have called for support before my PM suggests it. By then they are frustrated that I haven&rsquo;t already solved whatever the issue is solo.</p>
<h2 id="signs-you-might-need-help">Signs You Might Need Help</h2>
<p>Given my current role and skill set, I&rsquo;m often the person who gets called when a project goes sideways. That means I see a lot of places where someone didn&rsquo;t call for help until they were in crisis. While that&rsquo;s going to happen to us all from time to time, it&rsquo;s better to call for help when the problem is small. If you want until the project starts burning down around you, it&rsquo;s way too late.</p>
<p>You might need help if:</p>
<ul>
<li>You have absolutely no idea what to do next.</li>
<li>You are about to re-design a large portion of your project to get around a challenge.</li>
<li>You have spent more than a day pounding on a problem without success.</li>
<li>You are avoiding working on a task, because you don&rsquo;t know how to get started.</li>
<li>You are about to use a mode/tool/technique that everyone says is a bad idea.
<ul>
<li>In Salesforce that can mean things like:
<ul>
<li>loading data in serial mode</li>
<li>setting batch size to 1</li>
<li>using view all data in your tests.</li>
</ul>
</li>
<li>In Drupal that can mean things like:
<ul>
<li>hacking a module</li>
<li>loading data in the theme layer</li>
<li>writing raw SQL queries</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="what-to-do-before-asking-for-help">What to do Before Asking for Help</h2>
<p>As I said before, asking for help is a balance: you can wait too long, or you can ask too soon. The real trick is hitting the sweet spot.</p>
<p>There are several things you should always do before taking another person&rsquo;s time.</p>
<ul>
<li><strong>Google It!</strong> I kinda can&rsquo;t believe I have to say that, but not everyone bothers.</li>
<li><strong>Make sure you can explain the question clearly.</strong> If you don&rsquo;t know where you got stuck, how can I help you get unstuck? And thinking it through might make the answer obvious.</li>
<li><strong>Develop a theory.</strong> When asking for help, it can be useful to pose a theory about an approach. Even if you&rsquo;re wrong it may help me understand your thinking.</li>
<li><strong>Try a few things.</strong> Experimenting with what&rsquo;s going wrong can help you formulate your question, and may help me short cut my research if you have eliminated obvious issues.</li>
<li><strong><a href="https://en.wikipedia.org/wiki/Rubber_duck_debugging">Explain the problem</a></strong> to your dog, cat, rabbit, stuff animal, etc. As someone who spends time being a human rubber duck, I can often tell when someone tried to explain it once already.</li>
</ul>
<h2 id="wherewho-to-ask-for-help">Where/Who to Ask for Help</h2>
<p>For me, the hardest part is knowing who to ask.</p>
<p>As a consultant I try to avoid asking questions in places clients may see it. Our clients pay for us to be experts, they do not want to see us asking questions in public – particularly if the question has a simple answer.</p>
<p>As a Salesforce MVP, one of my favorite perks is the MVP Slack channel, where we ask each other questions that run the full range of complexity. While access to a community that hard to access, and that advanced, is a privilege there are other ways to find similar groups like your local user group.</p>
<p>I love having a good internal network of people to ask for help. Most of the places I have worked at as a consultant have had some kind of information place to ask questions and help each other out. If you work in a consultancy find or create such a back channel.</p>
<p>If concerns about being seen by clients isn&rsquo;t relevant to you, check out this list of <a href="https://www.salesforceben.com/7-salesforce-slack-communities-to-join/">7 Salesforce Communities to Join</a> recommended by Salesforce Ben.</p>
<h2 id="help-build-a-helpful-community">Help Build a Helpful Community</h2>
<p>The final thing to know about asking for help, is that it&rsquo;s important to offer help as well. A good question can be valuable to someone else who has the same issue in the future. A good answer is helpful to both the person who asked the question and the person who looks again in the future.</p>
<p>But offering answers, even if not perfect answers, is a great way to learn and encourage others to seek help. Any time I post a question on <a href="https://stackexchange.com/">Stack Exchange</a>, I try to hunt around for one or two to answer as well. That both allows me to <a href="https://www.imdb.com/title/tt0223897/">pay it forward</a>, it also helps encourage the tone that people can be experts in one thing while still needing help in another.</p>
<p>Smart people need help, and should be comfortable asking for it.</p>
]]></content:encoded> </item> <item>
      <title>Tool Building Mindset</title>
      <link>https://spinningcode.org/2024/05/tool-building/</link>
      <pubDate>
        Wed, 22 May 2024 00:15:29 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=2171</guid>  <description>&lt;p&gt;Earlier this month, at &lt;a href=&#34;https://midatlanticdreamin.com/&#34;&gt;Mid Atlantic Dreamin&amp;rsquo;&lt;/a&gt; in Philadelphia, I gave a talk titled &lt;strong&gt;Software Super Heroes: Building the tools you wish you had.&lt;/strong&gt; My goal with the talk was to convince people that should, can, and in fact do, built tools for themselves. If you work with technology, and your job involves repetitive tasks the same applies to you too.&lt;/p&gt;
&lt;h2 id=&#34;what-do-i-mean-by-tool-and-tool-builders-mindset&#34;&gt;What do I mean by &amp;ldquo;Tool&amp;rdquo; and &amp;ldquo;Tool builder&amp;rsquo;s mindset&amp;rdquo;?&lt;/h2&gt;
&lt;p&gt;I like to use a very expansive definition of tool: &amp;ldquo;A tool is anything that makes a task easier which would be repetitive, hard, or impossible without it.&amp;rdquo; In that sense just about anything you make that simplifies you work can be considered a tool: a project estimation spread sheet, a good set of directions for a complex task, a flow for a Salesforce admin, a piece of code to normalize a large collection of files, and more.&lt;/p&gt;</description> <content:encoded><![CDATA[<p>Earlier this month, at <a href="https://midatlanticdreamin.com/">Mid Atlantic Dreamin&rsquo;</a> in Philadelphia, I gave a talk titled <strong>Software Super Heroes: Building the tools you wish you had.</strong> My goal with the talk was to convince people that should, can, and in fact do, built tools for themselves. If you work with technology, and your job involves repetitive tasks the same applies to you too.</p>
<h2 id="what-do-i-mean-by-tool-and-tool-builders-mindset">What do I mean by &ldquo;Tool&rdquo; and &ldquo;Tool builder&rsquo;s mindset&rdquo;?</h2>
<p>I like to use a very expansive definition of tool: &ldquo;A tool is anything that makes a task easier which would be repetitive, hard, or impossible without it.&rdquo; In that sense just about anything you make that simplifies you work can be considered a tool: a project estimation spread sheet, a good set of directions for a complex task, a flow for a Salesforce admin, a piece of code to normalize a large collection of files, and more.</p>
<p>My intention with that expansive view is to help encourage people to take on a tool builder&rsquo;s mindset.</p>
<p>To be a digital tool builder does not require knowing how to write complex software, it just requires you to do what you already do now, but with intention. When we use a broad definition of tools, it&rsquo;s easier to see ourselves as tool builders, even if we&rsquo;re just talking about a spreadsheet or a Salesforce flow meant to handle an administrator&rsquo;s daily tasks. When we see ourselves as tool builders we are more likely to make something worth using more than once.</p>
<h3 id="why-does-this-matter">Why does this matter?</h3>
<p>When we approach problems with a tool building mind set, instead of insurmountable challenges caused by gaps in our tooling, we see opportunity to create something new to make the impossible possible. Instead of facing hours of boring repetitive tasks, we have chance to build a more interesting special purpose solution.</p>
<h2 id="fight-the-tool-building-excuses">Fight the Tool Building Excuses</h2>
<p>There are several excuses I commonly hear from people when I encourage them to build their own tools. They range from concerns about not having the right skills, to assuming someone else already built that tool or that the time required isn&rsquo;t worth the effort.</p>
<p>My general response to these concerns is that while people should indeed look around for tools that already solve their problem, and that some problems are very hard to solve completely, if you start to chip away at a complex problem you often will find that you can create tools that are good enough to save you time and effort.</p>
<p>Don&rsquo;t try to build the perfect tool that solves all possible edge cases on your first go. Create a tool that takes out some annoying and repetitive task. Then create a tool that solves for another task, or builds on your first time. Chip away.</p>
<p>I often tell developers who are early in their career that I should never see them doing rote repetitive tasks for hours on end. Instead once they understand how a repetitive task is done, they should start thinking about how to build a tool to take over. But that&rsquo;s not just advice for developers: we invented computers to do repetitive asks (calculating <a href="https://en.wikipedia.org/wiki/ENIAC">artillery firing tables</a> and <a href="https://en.wikipedia.org/wiki/Colossus_computer">cracking codes</a>), let them do that.</p>
<h2 id="pick-your-tool-building-path">Pick Your Tool Building Path</h2>
<p>When you set out to create a tool you have two main options: use something you already know, or use tool building as a chance to learn something new. I&rsquo;ve used tool building as was to teach myself new features of Excel, Google Sheets, Salesforce Flows, Git, and <a href="/2022/10/thinking-about-languages/">several programming languages</a>. This can be a great way to learn how to use the tool that&rsquo;s just right for the job. But learning a new tool or technique takes time, and if you have a deadline you may need to move faster.</p>
<p>Personally I try to take both paths from time to time. I use things I know when: they are exactly the right tool, I am under time pressure, or I want to keep my skills sharp. I will take the time to learn something new when: it&rsquo;s something I need to learn anyway, I am building on my own time, or it&rsquo;s exactly the right tool for what I need to do.</p>
<p>Neither path is correct 100% of the time. By using them both I am able to create the tools I need, and broaden my skills over time.</p>
<h2 id="just-start-building">Just Start Building</h2>
<p>The next time you&rsquo;re faced with a task that is repetitive or hard with the tools you have: create yourself something new. Don&rsquo;t get hung up on being perfect, just create something that&rsquo;s better than what you have at the start.</p>
<p>Then save your tool to use again later. Share it with colleagues, friends, or as an open source project.</p>
<p>When in doubt, just start building.</p>
]]></content:encoded> </item> <item>
      <title>Salesforce Nonprofit and Education Scratch Orgs</title>
      <link>https://spinningcode.org/2023/11/salesforce-nonprofit-and-education-scratch-orgs/</link>
      <pubDate>
        Mon, 13 Nov 2023 01:53:48 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=2108</guid>  <description>How to create scratch org config files for Salesforce Nonprofit Cloud and Education Cloud</description> <content:encoded><![CDATA[<p>During the recent <a href="https://help.salesforce.com/s/articleView?id=sfdo.Contribute_to_OSC.htm&amp;type=5">Open Source Commons</a> sprint in Chicago, I tried to create scratch orgs for nonprofit and education clouds. Despite having some of the best people in the market in the room, including two Salesforce Solution Engineers, two levels of their bosses, and of course Google, I couldn&rsquo;t figure it out.</p>
<p>As a follow up to a conversation there, <a href="https://www.linkedin.com/in/larryfontillas/">Larry Fontillas</a> sent me links to <a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_scratch_orgs_def_file_config_values.htm#so_fundraising">the help docs</a> that contain what I consider partial answers. While I&rsquo;ve sent feedback to help improve those articles, I am posting my current solution to this challenge.</p>
<h2 id="my-example-scratch-config">My Example Scratch Config</h2>
<p>On Github <a href="https://github.com/acrosman/Salesforce-NpcEdu-Scratch">I created a repo</a> that contains two scratch org configuration files:</p>
<ul>
<li><a href="https://github.com/acrosman/Salesforce-NpcEdu-Scratch/blob/main/config/education-cloud.json">education-cloud.json</a></li>
<li><a href="https://github.com/acrosman/Salesforce-NpcEdu-Scratch/blob/main/config/nonprofit-cloud.json">nonprofit-cloud.json</a></li>
</ul>
<p>Each is my attempt to create a definition that works for the named cloud. If are new to scratch orgs, I suggest you start with the <a href="https://trailhead.salesforce.com/content/learn/projects/quick-start-salesforce-dx">Trailhead Salesforce DX Quick Start</a>. With a Devhub setup, and connected to your sf cli, you can easily create these scratch orgs from my settings with one of the two following commands:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>sf org create scratch -d -f config/nonprofit-cloud.json -a npc-org
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>sf org create scratch -d -f config/education-cloud.json -a edu-org
</span></span></code></pre></div><h2 id="industry-org-scratch-config-breakdown">Industry Org Scratch Config Breakdown</h2>
<p>The two new clouds leve re-usable components Salesforce built, licenses, and deploys across different markets. Salesforce does not currently provide one master switch you must use. Instead you need to know what features to include and tell the Devhub which collection to enable.</p>
<p>That is done in two major parts of the configuration file. In <a href="https://github.com/acrosman/Salesforce-NpcEdu-Scratch/blob/main/config/nonprofit-cloud.json">my Nonprofit cloud config file</a> there are several sections, but two are critical: <code>features</code> and <code>settings → IndustriesSettings</code>. The features list includes Salesforce components to enable. In this case I included the nonprofit specific Fundraising, Program Management, and Grantmaking modules, but also OminiStudio, Accounting Subledger, and more because they included with NP Cloud by default. Under Industries Settings you&rsquo;ll also see I enable Grantmaking and support for Program Management.</p>
<p>The <a href="https://github.com/acrosman/Salesforce-NpcEdu-Scratch/blob/main/config/education-cloud.json">Education Cloud config file</a> has even more detail. That&rsquo;s because Salesforce as made more available for Education Cloud. The Industries settings section includes more flags as well for the same reason. As I Followed the setup guide for Education Cloud, I further adjusted some of the base-line object permissions.</p>
<p>Here are the features I know you need to include for each cloud:</p>
<p><strong>Feature<strong><strong>NP Cloud</strong></strong>Edu Cloud****Notes</strong><a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_scratch_orgs_def_file_config_values.htm#so_accountingsubledgergrowthedition">AccountingSubledgerGrowthEdition</a>OptionalOptionalStarter Edition is also available<a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_scratch_orgs_def_file_config_values.htm#so_accountingsubledgeruser">AccountSubledgerUser</a>OptionalOptionalAnalyticsQueryServiceYesOptionalThis is listed in the docs under Fundraising, but I have not yet found a direct description.<a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_scratch_orgs_def_file_config_values.htm#so_assessments">Assessments</a>YesYes<a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_scratch_orgs_def_file_config_values.htm#so_educationcloud">EducationCloud</a>NoYes (requires a quantity parameter)Main Education Cloud objects, but only a sliver of the features.<a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_scratch_orgs_def_file_config_values.htm#so_enablesetpasswordinapi">EnableSetPasswordInApi</a>YesYesAllows the cli to set the password, you always want this.
<a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_scratch_orgs_def_file_config_values.htm#so_fundraising">Fundraising</a>YesOptional<a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_scratch_orgs_def_file_config_values.htm#so_grantmaking">Grantmaking</a>YesOptional (Rare)<a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_scratch_orgs_def_file_config_values.htm#so_industriesactionplan">IndustriesActionPlan</a>NoYesIndustriesSalesExcellenceAddOnYesYesThis is listed in the docs under Fundraising, but I have not yet found a direct description.IndustriesServiceExcellenceAddOnYesYesThis is listed in the docs under Fundraising, but I have not yet found a direct description.<a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_scratch_orgs_def_file_config_values.htm#so_lightningscheduler">LightningScheduler</a>NoYesLightning Scheduler gives you tools to simplify appointment scheduling in Salesforce.<a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_scratch_orgs_def_file_config_values.htm#so_lightningserviceconsole">LightningServiceConsole</a>OptionalYesAllows the Lightning Service Console and access features that help manage cases faster.<a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_scratch_orgs_def_file_config_values.htm#so_marketinguser">MarketingUser</a>YesOptionalProvides access to the Campaigns object.OmniStudioDesignerYesYesListed in lots of samples, but I have not yet found a direct description. But clearly needed for OmniStudio.OmniStudioRuntimeYesYesMore for OmniStudio.<a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_scratch_orgs_def_file_config_values.htm#so_outcome_management">OutcomeManagement</a>YesNo<a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_scratch_orgs_def_file_config_values.htm#so_personaccounts">PersonAccounts</a>YesYesWe all love Person Accounts now! Technically this is optional, although the assumption is it your default.<a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_scratch_orgs_def_file_config_values.htm#so_programmanagement">ProgramManagement</a>YesNoEnables the NPC Program and Case management features.<a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_scratch_orgs_def_file_config_values.htm#so_publicsectoraccess">PublicSectorAccess</a>NoYesNot entirely sure about this one, but some of the features for Education Cloud seem to leverage these objects and settings.</p>
<h2 id="feedback-please">Feedback Please!</h2>
<p>I have tested these configurations to the degree of seeing that they work as a basic level. But I have not, yet, used them for a serious project. I am confident other people will find details that are missing, or just wrong. <em>Please</em> <a href="https://github.com/acrosman/Salesforce-NpcEdu-Scratch/issues">file an issue on Github</a> or leave me a comment here with suggested changes.</p>
]]></content:encoded> </item> <item>
      <title>Mid-Career Resumes</title>
      <link>https://spinningcode.org/2023/08/mid-career-resumes/</link>
      <pubDate>
        Sun, 13 Aug 2023 00:29:16 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=2075</guid>  <description>As we exit the Great Resignation, application materials are increasingly important again. Make your mid-career resume shines.</description> <content:encoded><![CDATA[<p>As we exit the Great Resignation, and move back to more traditional hiring patterns, application materials are increasingly important again. Over the course of my career I’ve been involved in a lot of hires, and read a large number of resumes. I know what I like to see, what I don’t like, and I have a bunch of friends in a similar position (although their likes and dislikes are sometimes different).</p>
<p>Recently, I realized that much of the advice online about resume writing is for people early in their career. That’s fair; they are the people with the least experience and need the most help. But as someone who is now mid-career, and reading resumes for other people who are also mid-career, I am noticing resumes from people who seem to still follow the early career advice.</p>
<p>So a few weeks ago I reached out to my friends who, like me, sometimes review mid-career resumes. While none of us are a full-time recruiter, we are the people who you need to impress if you want a job on our team. This post is a combination of my take, and the input I got from those people.</p>
<h2 id="there-are-no-hard-rules-about-resumes">There are NO Hard Rules About Resumes</h2>
<p>Resumes are not a regulated industry. There are no hard and fast rules. Any advice you see is just a set of suggestions. In the end, you have to decide what makes you look good and guess at what is effective.</p>
<p>Studies are rare, and even the best are poorly done. That is not the researchers’ fault. You cannot double blind a job hire. You cannot have 1,000 managers at different companies all hire for the same job from the same pool of applicants. Any one who knows a researcher is watching them work, likely changes their behaviors. Any study that finds bias creates legal risk for companies that participate which in turn limits participation and openness to data publication. List of problems with studying the process goes on and on.</p>
<ul>
<li>Anyone who tells you there is one best way to create your resume, is wrong.</li>
<li>Anyone who is entirely focused on the hiring manager, risks failing to give advice to beat automated filters.</li>
<li>Anyone who is entirely focused on beating the automated filter, ignores that nearly <a href="https://www.jpmorganchase.com/institute/research/small-business/small-business-dashboard/economic-activity">½ of the jobs in America are at small companies</a> and unlikely to use such filters.</li>
</ul>
<p>Write the best resume you can. Ask friends, particularly those who do hiring, for feedback. Consider paying a resume writer for help. But don’t expect even paid experts to be correct all the time.</p>
<h2 id="mid-career-resumes-should-highlight-your-experience">Mid-Career Resumes Should Highlight Your Experience</h2>
<p>The biggest mistake I see in resumes of people in mid-career, or even late career, is failing to highlight their experience. People who were at one employer for a long time struggle with this the most, but I’ve seen resumes for people with 15 years of experience that read like a recent graduate.</p>
<p>Your experience should be front and center. Everything about your resume should say “this is an experienced person.”</p>
<p>I like some form of summary at the top. Tell me what kind of employee and colleague you are. Not an objective section, but a summary of who you are. It can come in many forms:</p>
<p>a short paragraph:</p>
<blockquote>
<p>Salesforce MVP, developer, administrator, and consultant with 20 years of experience in the nonprofit and higher education sectors. Seven Salesforce certifications, experience in more then 20 programming languages. Proven experience leading teams and working closely with non-technical clients.</p>
</blockquote>
<p>list of titles, or key phrases</p>
<blockquote>
<p>Salesforce MVP, Technical Architect, Nonprofit Fundraising Expert</p>
</blockquote>
<p>After that, your job experience and skills are next. How exactly you do this can vary. Some people like skills in a sidebar. Some people put a list at the top. Some people put that list after their job experience. Frankly, as a reader, I don’t care. But I want to be able to find your list of skills and your <em><strong>relevant</strong></em> job history <strong><em>fast</em></strong>.</p>
<p>Your currently valid certifications should be included near your skills. But only those the reviewer will find relevant.</p>
<h2 id="think-about-your-audience">Think About Your Audience</h2>
<p>Likely the person reading the resume of an experienced person <em>is</em> an experienced person. We have habits, routines, and work styles that are built on experience. We also have things like aging eyes, old printers, out of date external monitors, and other things that it are tempting to ignore.</p>
<p>Text should be high contrast, print well in black and white (there is a huge exception here for graphic designers, who benefit from showing off graphic design skills), and be generally easy to read. I don’t want your pretty three color graph, head shot, or blue text that prints light gray.</p>
<p>If I am reading a handful or resumes, I’ll do that on a screen and I can zoom in if I need. But if I’m digging through a big pile, I’ll print them. I will print them on my 20+ year old laser jet, blank and white, printer. When I last worked in an office and reviewed resumes, I used the office’s even older laser jet black and white printer. Your shaded background might make the whole thing unreadable on those devices. Besides, you should have too much experience to waste space on a picture (and that’s before we talk about companies trying to avoid identity based biasing who might not want reviewers to know what you look like too early in the process).</p>
<p>I strongly recommend going for simple, clean, classic, design approaches.</p>
<h2 id="mid-career-resumes-should-be-more-than-one-page">Mid-Career Resumes Should be More Than One Page.</h2>
<p>I haven’t used a one page resume in more than 20 years. I don’t know who is still saying one page is the magic number. A new graduate <em>might</em> benefit from the one-pager, but if you have 10-30 years work experience, and you only need one page to tell me, it better be the most amazing page of text you&rsquo;ve ever created. When I see a one-page resume, before I see the words I see a person with limited experience.</p>
<p>Personally, I like the two pager. Two <em>very</em> full pages. I want to see that you were forced to edit and format aggressively to make it fit on two pages. You want me to think you have 5 pages of content, but you compressed it effectively.</p>
<p>Two pages gives you plenty of room to show off, without wasting my time. It shows me you can edit and filter content. Ideally, it’ll leave me wanting more information, that gives me questions I can ask in your interview.</p>
<p>Some people like longer. When I spoke with friends who hire, most people liked two pages. But some were open to 3-4. Beyond four you are into academic CV land, which is a different thing entirely.</p>
<h2 id="connect-the-dots">Connect the Dots</h2>
<p>You have experience, you are showing it off well, good. But are you showing off the right experience? One of the most consistent pieces of feedback I got from friends who do hiring is that we want to know you know who we are as an employer.</p>
<p>No every detail, but tell us what your public persona is. Is there a values statement in the job ad? Reflect some of that language back in a cover letter. Do we work in a specific market? Make sure to include some experience that connects you to that market.</p>
<p>When I worked at a nonprofit, we wanted people excited by the work we did. Which means they needed to find ways to tell us in their resume, cover letter, application, and interview they knew something about that work. Since becoming a consultant, I’ve been consistently amazed that people will send resumes and come to interviews that don’t know what kind of customers we have.</p>
<h3 id="write-a-cover-letter-whenever-invited">Write a Cover Letter whenever Invited</h3>
<p>This applies not just to mid-career applicants, but everyone else too. Not all jobs accept a cover letter, but when given the chance to say more: say more.  The numbers I can find on resume review suggest an average of 6-7 seconds. I think that’s low in practice (see comments on studies), I know when I dig through a large stack I find ways to filter out some <em>very</em> fast, and others get more careful review. So an average will likely be far from my median or modal times.  Even so, a resume that isn’t tossed out because it’s an applicant who is wildly unqualified, will get 15-30 seconds in my first pass.  You add a cover letter, now I’m spending more time reading. You could double, or even triple, the time you get in the first review 45-90 seconds – that’s huge.</p>
<p>It also means you can connect some additional dots for me. If your resume includes experience that you consider related, but that might not be obvious, you have a couple sentences now to tell me that story. Are you career pivoting? Tell me what about your old career makes you better than your experience suggests. Do you volunteer in your community? Tell me what about that helps you understand our work, or support our company values.</p>
<h2 id="in-mid-career-resumes-the-basics-still-matter">In Mid-Career Resumes the Basics Still Matter</h2>
<p><strong>Details matter:</strong> fix your typos, use consistent formatting, etc. I saw a resume recently with a red-line through their summary line. That’s a bad first impression.</p>
<p><strong>Write resumes you want to read:</strong> If you have read resumes as part of your job, think about the ones that impressed you and mimic those.</p>
<p><strong>Get feedback from a friend:</strong> You probably have friends and professional contacts who will give you blunt feedback. Ask for it. I did as part of writing this post.</p>
<p><strong>Consider hiring an expert:</strong> There are people who do this for a living. Some of them are really good. When you ask your friends for feedback, ask them for references to services they used.</p>
<p><strong>Not everything is needed:</strong> Edit down your experience. Keep the stuff that says you’re awesome, cut stuff that’s not relevant to the hiring manager.</p>
<h2 id="references-for-more-thoughts-on-mid-career-resumes">References for More Thoughts on Mid-Career Resumes:</h2>
<p>The internet is full of advice on resume writing. Most for beginners, but some for people with more experience.  Here are a few things I found useful:</p>
<ul>
<li><a href="https://www.indeed.com/career-advice/resumes-cover-letters/mid-career-resume">https://www.indeed.com/career-advice/resumes-cover-letters/mid-career-resume</a></li>
<li><a href="https://www.topresume.com/samples/resumes/mid-career-professional">https://www.topresume.com/samples/resumes/mid-career-professional</a></li>
<li><a href="https://hbr.org/topic/subject/resumes">https://hbr.org/topic/subject/resumes</a></li>
<li><a href="https://hbr.org/2008/05/the-ethics-of-resume-writing-2">https://hbr.org/2008/05/the-ethics-of-resume-writing-2</a></li>
</ul>
]]></content:encoded> </item> <item>
      <title>The Queries Part 3 of 3</title>
      <link>https://spinningcode.org/2023/07/the-queries-part-3-of-3/</link>
      <pubDate>
        Tue, 25 Jul 2023 00:31:59 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=2067</guid>  <description>More questions you can use to challenge your team to improve your migration game.</description> <content:encoded><![CDATA[<p>This is the third and final post in <a href="/tags/queries-on-queries/">a series of posts</a> to break down the questions from my Queries on Queries talk. <a href="/2023/06/queries-on-data/">The full talk is available here</a>.</p>
<h1 id="is-your-solution-reusable">Is your solution reusable?</h1>
<blockquote>
<p><em>Migrations feel like one off processes, but teams that migrate once usually migrate again.</em></p>
<p>Have you ensured that as much of your solution as possible can be reused? Do you have a shared library of migration tools that your whole team can access? When you create new functionality are you thinking about ways to make it usable in your next project?</p>
</blockquote>
<p>On any technology project you will generally benefit from designing for re-usability. I mentioned in my comments on the question about repeatability that people get tempted to see migration work as fundamentally one-off, but you need to plan for many runs. That question is focused on repeating the same project, this is about recycling parts of this project in another.</p>
<p>To a consultant, the value of reuse should be obvious: we like to sell projects to new clients based on successful projects for another client. For that I want libraries of tools the developer designed for rapidly assembled to meet a new client’s needs.</p>
<p>But even when I <em>was</em> the client, I was moving similar data into the same systems over and over. I created API libraries, and rough interfaces, to handle some of that work so I didn’t have to do the same tedious work again and again.</p>
<p>In both cases those libraries are only useful if whoever needs them knows they exist, has access to them, and can figure out how to leverage them.</p>
<h1 id="is-your-migration-testable">Is your migration testable?</h1>
<blockquote>
<p><em>All good processes are rigorously tested.</em></p>
<p>Do you have an automated testing solution that validates your process? Can you tell if the data migrated accurately after each test run? Do your tests cover the positive and negative cases?</p>
</blockquote>
<p>Testing migrations is hard. Testing software is hard. The testing tools that developers are most familiar with are unit testing tools, test one very small thing at a time. Multi-system data comparison is not their forté. The tools that do exist for such work tend to be quite expensive and/or so complex the task of creating tests is nearly as hard as the task of creating the migration jobs themselves.</p>
<p>But just because testing is hard does not mean you shouldn’t do what you can do within the budget and time you have. When you cannot use something like MuleSoft’s MUnit you can still create queries that sanity check the migrated and generated data. You select records for spot checking that cover edge cases you are aware of, and some that represent primary use cases. You can look for records that create invalid data states that would violate your new validation rules.</p>
<h1 id="is-your-work-fixable">Is your work fixable?</h1>
<blockquote>
<p><em>Migrated data often needs to be updated after the jobs have all run.</em></p>
<p>Do you have a plan to fix your data if errors are found post migration? Does your plan include ensuring you have external Ids, or other connections, to be able to update all records of every type? Have you validated this plan will work in practice?</p>
</blockquote>
<p>When you do a data migration, because everything is determinant, you feel like perfection is possible. But when you’re moving millions of records that were entered by humans, extracted by humans, mapped by humans, validated by humans, and represent human behaviors, there is a lot of room for human error.</p>
<p>You can either pretend your process is good enough to squeeze out the error, or build a process that allows you to fix the errors that slip through. Obviously I don’t believe the first is possible, so I encourage the second.</p>
<p>Make sure you can go back and update anything. If you’re migrating into a database that allows for a lot of easy changes – great. If you’re migrating into a financial system – make sure you understand the rules for editing.</p>
<p>Planning for mistakes you don’t want to have makes it far easier to recover from those mistakes when they appear.</p>
]]></content:encoded> </item> <item>
      <title>The Queries Part 2 of 3</title>
      <link>https://spinningcode.org/2023/07/the-queries-part-2-of-3/</link>
      <pubDate>
        Mon, 17 Jul 2023 13:32:00 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=2055</guid>  <description>More questions you can use to challenge your team to improve your migration game.</description> <content:encoded><![CDATA[<p>This is the second in <a href="/tags/queries-on-queries/">a series of posts</a> to break down the questions from my Queries on Queries talk. <a href="/2023/06/queries-on-data/">The full talk is available here</a>.</p>
<h2 id="is-your-work-repeatable">Is your work repeatable?</h2>
<blockquote>
<p><em>You will need to do this more than once.</em></p>
<p>Is your process designed so you can run it over and over without error? Can you easily erase test attempts and start over from a clean slate? Do you have the capacity to do all the practice runs you need to complete your project successfully and on schedule?</p>
</blockquote>
<p>Because a migration is fundamentally a one-way operation, designed to move data once, it’s tempting to build the whole process as a one-off affair. I’ve seen (even used) migration processes that required hours or days of hand polishing data to get it to load – this is a terribly way to do the job.</p>
<p>A good migration process should be automated. To automate anything you need to test it. If you test something you should expect it to fail many times before it works. And when it fails you need to run it again and again until it works.</p>
<p>By their very nature data migrations create data – in a target system no less – and so you need a way to roll back your changes to migration to a pre-run state for each subsequent test. I like to use a staging database for the main complex parts of my migrations. I created <a href="/2022/05/getting-started-with-salesforce2sql/">Salesforce2Sql</a> just to make that so easy no one would be tempted to skip that step. When I create processes in an ETL, I like to have jobs start by deleting data from the staging database related to the job, so I can make <a href="https://developer.salesforce.com/blogs/engineering/2013/01/implementing-idempotent-operations-with-salesforce">Idempotent jobs</a> as much as possible. Run, test, adjust, repeat. If you know how many times you ran your migration process, you didn’t run the jobs enough.</p>
<h2 id="is-your-work-measurable">Is your work measurable?</h2>
<blockquote>
<p><em>To know you moved all the data, you must know how much data is going in and how much should come out.</em></p>
<p>Can you accurately predict your output data volume based on the input size? Do you have valid estimates of the running time required for each stage based on the data volumes? Are the estimates of expected data set size from a reliable source?</p>
</blockquote>
<p>It seems like knowing how to measure your work should be obvious, but in truth most interesting migrations are not a simple record-in, record-out – they involve splitting records, combining tables, filtering data, converting tables to fields, fields to tables, and other similar adjustments. But the only way to know if you got it all to work out right is to work out the math wherever you can.</p>
<p>It’s also important to know how long a process will take. Sometimes a few thousand records here or there doesn’t matter much, but sometimes that is a matter of hours. Particularly when running samples it’s important to know the average running time. I’m working on a project right now where we know that the first 3 million records will load in about 6 hours, the last 45,000 records will take 12 hours.</p>
<p>In that project we’ve worked out those running times, and we have a good understanding of total records counts. In other projects we thought we knew, only to discover the person giving us the source record counts was talking about the per-year instead of total expected migration size. But with per-record estimates we can adjust expectations quickly when information changes.</p>
<h2 id="do-you-scope-your-data-migrations-carefully">Do you scope your data migrations carefully?</h2>
<blockquote>
<p><em>Limiting bad data in your system allows for better decisions in the future.</em></p>
<p>Do you only load data into the new system that you truly need? Can you easily spot the difference between new and old records? Are there data points getting loaded that have no use case or maintenance plan in the target system?</p>
</blockquote>
<p>Everyone wants to keep all their data. My entire career I have understood that storage is cheap, and big data is king. AI driven data analytics have been around for a few years, and now we have all the attention on generative AIs, both benefit from large data sets.</p>
<p>These all tools are great, but they aren’t magic.</p>
<p>Big data processing, whether it be AI driven or not, is all about correlations. If you give a correlation engine bad data, it will give you bad results. Garbage in is still garbage out.</p>
<p>You only want to migrate data that’s good.
You only want to migrate data that’s useful.
You only want to migrate data that you will maintain.</p>
<p>So before you start a migration make sure you know your data will fall into those categories. Organizations can always archive data they don’t migrate.</p>
<p>There are other reasons more data isn’t always better.</p>
<p>If your system, or data archive, is ever breached that presents a risk to an organization. Privacy laws are steadily tightening, increasing the chances you will have to admit to your audience you were the cause of their information falling into the hands of bad actors.</p>
<p>Also, old data is often bad data. Colleges often have the email address used by their applicants squirreled away in their alumni systems.  How useful do you think the AOL address I used in 1997 is to Hamilton College today? If they use it, they will fail to reach me. It provides them no value, but does provide them the chance to make mistakes. Same is true of old phone numbers, addresses, and more.</p>
<p>Keep the good stuff, let go of the stuff you don’t need.</p>
]]></content:encoded> </item> <item>
      <title>The Queries Part 1 of 3</title>
      <link>https://spinningcode.org/2023/07/the-queries-part-1-of-3/</link>
      <pubDate>
        Mon, 10 Jul 2023 13:00:00 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=2050</guid>  <description>Questions you can use to challenge your team to improve your migration game.</description> <content:encoded><![CDATA[<p>This is the first in <a href="/tags/queries-on-queries/">a series of posts</a> to break down the questions from my Queries on Queries talk. <a href="/2023/06/queries-on-data/">The full talk is available here</a>.</p>
<h2 id="are-your-tools-good-enough">Are your tools good enough?</h2>
<blockquote>
<p><em>Our migrations live and die by our tools.</em></p>
<p>Are your tools built for the scale of your project? Do they empower you to do your best work or impede rapid progress? Would a new tool serve you better now or in the future?</p>
</blockquote>
<p>Having <a href="https://www.hseblog.com/importance-of-selecting-the-right-tools-for-the-job/">the right tools</a> is critical to any job. In data migration we primarily talk about ETLs ( <strong>E</strong> xtract, <strong>T</strong> ransform, and <strong>L</strong> oad): tools like <a href="https://www.jitterbit.com/">Jitterbit</a>, <a href="https://www.informatica.com/">Informatica</a>, <a href="https://www.mulesoft.com">Mulesoft</a>, <a href="https://www.talend.com/">Talend</a>, etc. We also use additional tools to help support the process: a task tracker like <a href="https://www.atlassian.com/software/jira">Jira</a>, a Data Modeler like <a href="https://www.lucidchart.com/pages/">Lucidchart</a>, staging database prep like <a href="/2022/05/getting-started-with-salesforce2sql/">Salesforce2Sql</a>, and more.</p>
<p>It’s easy to say that <a href="https://thecontentauthority.com/blog/what-does-it-is-a-poor-workman-who-blames-his-tools-mean">it’s a poor carpenter who blames his tools</a>, but anyone who has spent time with actual carpenters knows they care a great deal about what tools they use. They might be able to make due with poor tools, but they will do their best work with the right tools for the job.</p>
<p>Each tool you use needs to meet your team’s needs. It should play to your strengths, supports the kinds of projects do you do, and has an eye to the future. A tool that works great for a team of declarative Salesforce consultants might drive developers crazy. A tool that works great for 10’s of thousands of records might struggle with millions; a tool scaled for 10s of millions of records may be overly complex for a project of 30,000.</p>
<p>Make sure you’re using the tools that let you do your best work, now and in the future.</p>
<h2 id="do-you-make-the-data-atomic-for-processing">Do you make the data atomic for processing?</h2>
<blockquote>
<p><em>Smaller pieces of data are easier to track, manipulate, and test.</em></p>
<p>Do you divide the source data into its constituent parts? Can you process individual pieces of data easily and cleanly? Can you stop your process after each stage to validate the results?</p>
</blockquote>
<p>It can be tempting to process data as it comes: handling whole rows of data in the form they were provided and treating fields as a single data point. In practice exports may have extra rows or columns to deal with related records. Organizations may have encoded multiple points of data into fields like ticket names including a show name, date, and time into the name field. Fields can also contained semi-structured data, like Joomla’s use of arbitrary JSON blobs.</p>
<p>To process this data it is often easier and clearer to extract it from these structures prior to direct processing. It’s not always needed, and rarely required, but doing this clean up of structure – like creating interstitial database tables or predictable data objects – can greatly ease the rest of your job.</p>
<p>Like many problems in software engineering, it’s easier to do good work when you are operating on atomic pieces. Think about the right ways to pull your data into constituent parts when they aren’t there already.</p>
<h2 id="can-you-process-samples-of-your-data-set">Can you process samples of your data set?</h2>
<blockquote>
<p><em>When you have lots of data you need to test small parts to be sure your process works.</em></p>
<p>Do you know how to create and run small segments of your total input? Are your segments made up of complete and valid samples? Does your sample include all the errors and edge cases your data set will throw at your process?</p>
</blockquote>
<p>If you are working with small data sets your sample can be all the data. But when you have a large data set you need to test your process with samples. When you have a multi-step migration you likely need to test the second phase while the first phase is still under construction – again a sample data set is critical.</p>
<p>Having valid test data, that covers all your edge cases, is critical to making sure you have a working solution.</p>
<p>A few years ago I worked on a project that involved a two stage migration for a membership organization with some 600,000 active contacts. Every one of them needed to be migrated into Salesforce and then into Drupal. To test the Drupal migration we needed samples of all the types of membership statuses we would see, which involved hand creating several hundred records. At the next Salesforce Commons Sprint I raised the idea of needing a better tool for this kind of work, that question eventually helped lead to <a href="https://www.linkedin.com/in/paulprescod/">Paul Prescod</a>&rsquo;s <a href="https://developer.salesforce.com/podcast/2021/07/episode-89-snowfakery-data-generation-with-paul-prescod">creation of Snowfakery</a>. Snowfakery will build you testing data sets of any size and complexity to make sure your processes will succeed.</p>
]]></content:encoded> </item> <item>
      <title>Queries on Queries: Improve your data migration</title>
      <link>https://spinningcode.org/2023/06/queries-on-data/</link>
      <pubDate>
        Fri, 30 Jun 2023 00:05:52 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=2045</guid>  <description>Queries on Queries presents opinionated questions to help you evaluate and improve your data migration process and practices</description> <content:encoded><![CDATA[<p>Last week I gave my <a href="/2021/07/sc-dug-july-2021-queries-on-queries/">Queries on Queries talk</a>, intended to help you improve your data migration process, as a webinar for <a href="https://attainpartners.com/">Attain Partners</a>.  It’s a revised and improved version from the last time I gave it.</p>
<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
      <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/HfxGiHlzACE?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
    </div>

<p>These questions aren’t like the <a href="https://www.joelonsoftware.com/2000/08/09/the-joel-test-12-steps-to-better-code/%5D">old Joel Test</a> (which is still useful) where the right answer is “yes”. These questions are designed to point you in a direction but allow you to change your answer over time. I generally answer this questions with a paragraph not a word. Use these questions as a challenge to make you and your team better.</p>
<p>Over the next few weeks I’m planning to <a href="/tags/queries-on-queries/">publish a series</a> that will include each query and why I think it’s useful in helping you think about how to improve your process.</p>
]]></content:encoded> </item> <item>
      <title>Take Good Notes</title>
      <link>https://spinningcode.org/2023/05/take-good-notes/</link>
      <pubDate>
        Mon, 29 May 2023 18:37:59 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=2035</guid>  <description>&lt;p&gt;A good set of notes is how we build a memory of what happened.&lt;/p&gt;
&lt;p&gt;Good note taking is important in nearly any white collar job, particularly consulting. If we have a long conversation with a client and have to re-ask them about all the details, they will rightly be annoyed. They may demand to know what they paid for the first time we talked.&lt;/p&gt;
&lt;h2 id=&#34;why-we-take-notes&#34;&gt;Why we take notes&lt;/h2&gt;
&lt;p&gt;In school we are taught to take notes. Teachers expect students to remember information to pass tests, write papers, and other evaluations of learning. Too often teachers will try to convince students to take notes in specific way. They may make note taking into an assignment and assessment of its own. My wife sees college students who decide that they don&amp;rsquo;t need to take notes because she does not grade them. These students do not do well. These students missed the point of taking notes. The form of the notes is not important, but the existence of them is.&lt;/p&gt;</description> <content:encoded><![CDATA[<p>A good set of notes is how we build a memory of what happened.</p>
<p>Good note taking is important in nearly any white collar job, particularly consulting. If we have a long conversation with a client and have to re-ask them about all the details, they will rightly be annoyed. They may demand to know what they paid for the first time we talked.</p>
<h2 id="why-we-take-notes">Why we take notes</h2>
<p>In school we are taught to take notes. Teachers expect students to remember information to pass tests, write papers, and other evaluations of learning. Too often teachers will try to convince students to take notes in specific way. They may make note taking into an assignment and assessment of its own. My wife sees college students who decide that they don&rsquo;t need to take notes because she does not grade them. These students do not do well. These students missed the point of taking notes. The form of the notes is not important, but the existence of them is.</p>
<p>When we leave school notes serve two main purposes:</p>
<ol>
<li>Record events of a meeting so there is a shared record later.</li>
<li>Help us remember what happened so we can do our work.</li>
</ol>
<p>Every important meeting should have someone charged with creating the first of those. How you do that task assignment is work place and team specific, but it needs to happen. Doing this well is an important skill, and every team, board, religious community, and so on needs people who do this well. But the second type of notes are often more important for day to day work; they are an important how the participants remember what needs to happen.</p>
<p>This second category of notes is why there is nearly always a notepad near me when I&rsquo;m working. I scribble down thoughts, tasks, key points, and anything else I need to remember later. The notes I take are messy, disorganized, and useless to anyone but myself. None of that matters as long as I remember what I need to know.</p>
<h2 id="why-take-notes-yourself">Why take notes yourself</h2>
<p>Lots of people hate to take their own notes. I have colleagues who treat note taking as a task to be avoided. Heck, I dislike being the official note taker when it&rsquo;s my turn. People often fall back on the &ldquo;official&rdquo; notes of meetings instead of keeping their own. I have heard people go so far as to declare additional notes are just a waste of effort. I have had colleagues claim this &ldquo;wasted&rdquo; effort is somehow costing the client money (not true, they were in the meeting anyway).</p>
<p>Writing notes encourages us to engage with the content. There are no shortage of <a href="https://scholar.google.com/scholar?q=note+taking+and+memory">studies on the impact of note taking and memory formation</a>. The research clear indicates that if you engage actively with information you will retain it better. Any form of note taking that encourages you to engage is a good start. That engagement can be exhausting, but that does not justify avoiding the work.</p>
<p>Even when in a meeting with an official note taker, our clients are best served by everyone on our team taking notes. That helps us all learn about the client needs, to contribute to the project work, as well as offer edits to official notes after a meeting wraps up.</p>
<h3 id="can-an-ai-note-taker-do-just-as-well">Can an AI note taker do just as well?</h3>
<p>The recent public emergence of generative AI has captured a great deal of attention. We are thinking of all the places that a machine can take over tasks we thought required a human – particularly those we dislike. There are already services like <a href="https://otter.ai/">Otter.AI</a> which will attend virtual meetings and generate notes for you.</p>
<p>My experience suggests that, right now, they are pretty terrible at their main job. The automated transcripts they require are adequate at best; their note taking ability is worse. The samples I&rsquo;ve seen from meetings I was in were basically useless. Worse yet, <a href="https://medium.com/geekculture/why-chatgpt-lies-4d4e0c6e864e">AI tools will lie</a> (or more accurately they generate believable, but false, information), <a href="https://www.bbc.com/news/world-us-canada-65735769">which is getting people into trouble</a>. After all those issues, you will need to deal with the privacy and security implications of allowing a system listen into your meetings.</p>
<p>One day these systems will likely be pretty good for official meeting notes, but that&rsquo;s not today. Even at that point, those AI&rsquo;s will not help you engage with, or retain, the information.</p>
<p>Do yourself a favor, no matter who or what else is taking notes, take your own.</p>
<h2 id="what-makes-good-personal-notes">What makes good personal notes</h2>
<p>Fundamentally what makes good personal notes is whatever you can use to accurately recall what happened. If you are able to recall the details when you need them, your notes were good enough. If you cannot not, your notes aren&rsquo;t good enough. That&rsquo;s true during your education (unless a teacher is grading your notes, then play along with their instructions), that&rsquo;s true in the work place.</p>
<p>There are <a href="https://research.com/education/digital-notes-vs-paper-notes">several formal patterns</a> for note taking to help you structure the information. If you are struggling to take useful notes, I recommend trying one or two to see if they work for you. Those patterns do not work well for me, and I have bad memories of being made to outline lectures, and other patterns as the &ldquo;one true&rdquo; solution for taking notes.</p>
<p>Later in my education I picked up the metric I use now: do they work. I found I retain information best when I am summarizing bits and pieces to trigger my memory. My own notes are often just a few words to draw my brain back to key points. I will write out a major decision, pronouncement, or useful quote from time to time – that extra detail emphasizes to me later that I thought was a major point at the time.</p>
<p>Find your own style of note taking, but do not pretend you do not need them.</p>
]]></content:encoded> </item> <item>
      <title>Salesforce Data Migration Lessons</title>
      <link>https://spinningcode.org/2023/03/salesforce-data-migrations/</link>
      <pubDate>
        Wed, 29 Mar 2023 14:00:00 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=2012</guid>  <description>Three lessons I wish I knew on when I started doing Salesforce Data Migrations.</description> <content:encoded><![CDATA[<p>Last week I was part of <a href="https://attainpartners.com/event/data-migration-for-education-institutions-and-nonprofits/">a webinar for Attain Partners</a> talking about Salesforce data migrations. One of the questions the moderator, <a href="https://www.linkedin.com/in/ericmagnuson/">Eric Magnuson</a>, asked was the three lessons I&rsquo;d learned doing data migration work.</p>
<p>The answers I chose weren&rsquo;t so much from my first data migration projects, as from more recent projects. Those early migrations were tiny by my current standards. Back then, I was mainly the consumer of migrated data. When I did migrations they were small and manual. The intellectual process was similar but the scale meant I had lots left to learn about large data projects. The lessons I chose are focused on what I wish I knew when doing the migration for clients with vastly larger data sets. When I became the producer of migrated data.</p>
<p>My three lessons:</p>
<ol>
<li>Manage expectations from the start.</li>
<li>Don&rsquo;t be a hero.</li>
<li>Understand your tools, and use them well.</li>
</ol>
<h2 id="manage-expectations-from-the-start">Manage Expectations from the Start</h2>
<p>This still surprises me, but it&rsquo;s true: one of the biggest reasons data migrations get into trouble is bad expectations.</p>
<p>People tend to think data migrations are easy. You create a map from the old system to the new, run some processes to convert the data, load into Salesforce. But in practice, that map might involved thousands of details. Those conversions are hard to get right for every variation of the old data. And loading large amounts of data is never as easy as it looks.</p>
<p>When people think something is easy, and then the outcome is less then perfect, they get mad.</p>
<p>The problem is, data is always messy. We do migrations when we replace systems. We replace systems when the old one has problems. Problems in a system, lead to data errors.</p>
<p>That reality is made worse by the reality of big system switches. The freshly migrated data lands in a system the primary users are still learning. Those factors lead to confusion, mistakes, errors, and misunderstandings.</p>
<p>From the very first conversation I tell our clients to expect migration errors. Our first mock run of the migration is messy – sometimes very messy. The whole point is to find errors. The second mock run will be much better, but still imperfect; we&rsquo;ll find more errors. No matter how many times we do test runs, there is only some much we can do with imperfect inputs.</p>
<p>We can make your data better then it is, but we can&rsquo;t make it perfect. If you expect perfect data, you will be disappointed. I want you to be thrilled by your new system, and that means you need to understand your migrated data will have flaws.</p>
<h2 id="dont-be-a-data-hero">Don&rsquo;t Be A Data Hero</h2>
<p>When I first did data migrations I was often a one-person show. I was responsible for figuring out all the details, implementing the process, reporting to the client, and fixing all the flaws. It&rsquo;s a common story for people doing migrations.</p>
<p>We find ourselves up late at night, working through piles of detail, trying to make sure the client is satisfied. It encourages a hero mentality: I&rsquo;ll make the project successful through shear will.</p>
<p>And most of us can do it. Being a data hero isn&rsquo;t that hard if you put the hours in. It is, however, miserable.</p>
<p>People doing migrations need, and deserve, support. Now that I&rsquo;m leading a team of people doing migrations I have added the support I should have had. I created a space for us to come together and talk about our projects.</p>
<p>We ask each other for help and suggestions. We offer ideas for how to improve our processes. We talk about ways to address client concerns. And yes, we complain to one another. But mostly what we do is make sure that no one is alone. Everyone, myself included, has support and back up.</p>
<p>A team is stronger than a person. We don&rsquo;t need to be heroes. We do better work, and are happier people, when we support one another. Good work, by happy people, makes for successful projects.</p>
<h2 id="understand-your-migration-tools">Understand Your Migration Tools</h2>
<p>Data processing tools are code generators – understanding that allows you to use them well.</p>
<p>Both parts of that make sense once you say it:</p>
<ul>
<li>Tools that allow you to design an arbitrary process that takes inputs and generates outputs are obviously writing code at some level.</li>
<li>If you understand any tool better, you will use it better. That&rsquo;s true of a hammer, a screw driver, or a piece of software.</li>
</ul>
<p>I learned how to migrate data from people who weren&rsquo;t formally trained developers. They were using the tools the best way they knew how, but didn&rsquo;t have the background to apply software development best practices.</p>
<p>When I combined the tool usage they taught me, with the software engineering practices I already knew, I created vastly superior solutions. Our team now creates processes that are easier to setup, run faster, and allow us to fix all errors (even if we missed them until after launch).</p>
<h2 id="apply-lessons-our-salesforce-data-migrations">Apply Lessons our Salesforce Data Migrations</h2>
<p>I apply these lessons to the Salesforce data migrations I lead in my work at Attain Partners. I combine that with my <a href="/2021/07/sc-dug-july-2021-queries-on-queries/">queries on queries</a> review process, and am constantly building better solutions for our clients, our team, and myself.</p>
]]></content:encoded> </item> <item>
      <title>Do Not Consult Like Col. Flagg</title>
      <link>https://spinningcode.org/2022/12/do-not-consult-like-col-flagg/</link>
      <pubDate>
        Sat, 31 Dec 2022 17:18:08 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=1987</guid>  <description>Consultants get a lot of good tactical advice. But if we take things too far we are only slightly less clueless than Flagg.</description> <content:encoded><![CDATA[<p><a href="https://mash.fandom.com/wiki/Colonel_Sam_Flagg?file=Flagg-quo_vadis.jpg"><figure>
  <a href="https://static.wikia.nocookie.net/mash/images/9/99/Flagg-quo_vadis.jpg" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    <img class="rcf-image external-image" src="https://static.wikia.nocookie.net/mash/images/9/99/Flagg-quo_vadis.jpg" loading="lazy" />

    </a>

  
  
</figure></a></p>
<p>Sometimes we learn best from counter examples. <a href="https://mash.fandom.com/wiki/Colonel_Sam_Flagg">Col. Flagg</a> was an recurring character on M*A*S*H. He was a CID man with Army Intelligence, and spent much of his time bloviating about his suspicions about everyone while threatening to kill people for fun.</p>
<p>Flagg seemed to have taken every piece of tactical advice he was ever given to absolute extreme. It leads him apply his most aggressive techniques – like threats of torture, or attempts at bribery – to every situation he encounters.</p>
<p>Consultants get a lot of good tactical advice about how to address our clients and our work. But if we take things too far we are only slightly less clueless than Flagg.</p>
<h2 id="col-flaggs-over-generalization">Col. Flagg&rsquo;s Over-Generalization</h2>
<p>Probably the best example of Flagg&rsquo;s constant misapplication of techniques by generalizing their use is in <a href="https://www.imdb.com/title/tt0638421/">The Abduction of Margret Houlihan</a> from season 5. Chief Nurse Margret Houlihan hurries off late at night to deliver a baby in a nearby village, telling only the guard, Kilnger, who promptly goes to bed. When no one can find her in the morning, Potter calls for help searching for her. The army&rsquo;s answer is to send Col. Flagg. He arrives, dressed as Mussolini, claiming to look like a Chinese double agent (if that agent chose the same get up), and proceeds to request the provisioning of several items clearly planning to torture someone.</p>
<p>Flagg spends the day wondering around, threatening everyone he talks with, trying to get information about Houlihan. He never finds anything of use, but does get in a number of good one-liners.</p>
<p>Finally Houlihan, who was never in any danger, returns to camp unaided. Flagg declares victory, throws himself out a window – so know one will see him leave – and breaks his leg.</p>
<p>Anyone who had been a consultant long enough can find parallels between Flagg&rsquo;s useless bloviating, and consultants who try to address every client project as interchangeable.</p>
<h2 id="col-flagg-consulting">Col. Flagg Consulting</h2>
<p>Good advice often is context specific – you need to know when and how to use it.</p>
<p>Anytime I am in a meeting with a client, and I recognize that a piece of stock advice may apply, I try to reflect on the context of the moment. Does the advice <em>actually</em> apply, or would a different approach be better.</p>
<p>For example, consultants are often told to never say &ldquo;I don&rsquo;t know&rdquo; in front of a client when asked a question we are unsure how to answer. Instead we are taught to say &ldquo;I need to get back to you about that&rdquo; or &ldquo;let me verify with another team member before I respond.&rdquo;</p>
<p>Up to a point this makes sense. We are paid experts; clients don&rsquo;t want hire someone who does not know how to complete the job. Often making a space to make sure you are correct <em>is</em> the right response to an unknown. It&rsquo;s far better than making up wrong answers. And, more often, better than making a client nervous because you haven&rsquo;t had 30 seconds to Google the answer.</p>
<p>But clients can also smell something is fishy if you always claim to know everything. When I was a client, I never trusted consultants who pretended that they had seen and done everything. I knew they were lying to me because no one knows everything – leaving me to sort truth from fiction. That never ended well for the consultant.</p>
<blockquote>
<p><em><strong>&ldquo;Nobody gets the truth out of me. I keep myself in a constant state of confusion.&rdquo;</strong></em></p>
<p>Col. Flagg</p>
</blockquote>
<p>Consultants who cannot track context and adjust their approach accordingly, risk consulting like Col. Flagg.</p>
<h2 id="mash-consulting">M*A*S*H Consulting</h2>
<p>If you didn’t know, or can’t guess from context, my wife and I are M*A*S*H fans. We grew up with it. We bought the DVDs as they Fox released them. It’s our go-to for something comforting to watch. It’s entertaining, and full of great lines and moments to borrow for life examples. As part of marking the show’s 50th anniversary this is the second in a short series of posts using consulting lessons from characters in M*A*S*H.</p>
]]></content:encoded> </item> <item>
      <title>Consult like Father Mulcahy</title>
      <link>https://spinningcode.org/2022/11/consult-like-father-mulcahy/</link>
      <pubDate>
        Wed, 23 Nov 2022 01:31:38 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=1974</guid>  <description>Balancing the ideal and the practical is one of the challenges in consulting. Try to find Father Mulcahy&amp;#39;s balance.</description> <content:encoded><![CDATA[<p><a href="https://mashwiki.fandom.com/wiki/Father_Mulcahy">Father John Patrick Francis Mulcahy</a> (aka Father Francis John Patrick Mulcahy depending on the season), spent 11 seasons of <a href="https://www.imdb.com/title/tt0068098/">M*A*S*H</a> trying to balance his two realities. He was a priest, opposed to violence (aside from boxing), thrust into a war zone. As the 4077th chaplain he was responsible for the spiritual and emotional care of more or less everyone else. Father Mulcahy spends many scenes helping in OR. He supports the doctors however he can; he brings supplies and drinks to the staff; offers prayers for the dying; even assisting in surgeries at times.</p>
<h2 id="mulcahys-balance">Mulcahy&rsquo;s Balance</h2>
<p>Throughout the show his story is one of a man struggling to find balance – sometimes he does it well, sometimes he misses. The writers make his goal most clear in the <a href="https://www.imdb.com/title/tt0638328/quotes">episode Heroes.</a> A former boxing champion has come to came on a USO tour stop and has a stroke that is eventually fatal. As the boxer lays in a coma, he explains the influence the champ had had on his world view.</p>
<p>Mulcahy talks about his struggle with the idealism in Plato and his desire not to be beaten up at school. He tells the story of the first professional fight he’d seen. The now dying champ, had asked the ref to stop the fight so he didn’t hurt his opponent too badly.</p>
<blockquote>
<p>“And I realized for the first time, that it was possible to defend myself and still maintain my principles. … That was when I made up my mind to keep one foot in the ideal plane and the other foot in the real world.”</p>
<p>Father Mulcahy</p>
</blockquote>
<h2 id="mulcahy-consulting">Mulcahy Consulting</h2>
<p>Consulting is, obviously, less challenging than Father Mulcahy&rsquo;s world. But M*A*S*H has a lot of useful ideas to use to inspire us in our lives. If you aren’t familiar with the show, I highly recommend it (although new viewers might start in Season 2 or 3 since it took them a season to find their feet).</p>
<p>Balancing the ideal and the practical is one of the challenges in consulting. We can often see an ideal solution for a client, but the client doesn’t have the time or budget to reach that ideal. Our job is then to find a balance between that ideal solution and meeting deadlines and controlling budget. We need to keep one foot on the ideal technical plane, and the other in our practical world.</p>
<p>Like Mulcahy, sometimes we get frustrated that we can’t do our best work for doing for reasons that feel short-sighted. Finding ways to work on personal projects or other things that allow you to be technically purest can help keep skills sharp and scratch itches can help. Unlike Father Mulcahy, leave the choice to charge into other people&rsquo;s battles to [rescue a wounded soldier](<a href="https://mash.fandom.com/wiki/Mulcahy%27s_War_(TV_series_episode)">https://mash.fandom.com/wiki/Mulcahy%27s_War_(TV_series_episode)</a> to the properly trained.</p>
<p>We may sometimes error in the other direction. Like Mulcahy trying to write the perfect sermon during a visit from a cardinal, and miss the place we should really be (hopefully we can pull it together <a href="https://www.youtube.com/watch?v=vvLH22RSpaY">as well as he does</a>). It’s easy to get focused on our own goals, and miss a client’s needs go in a totally different direction.  But it’s our job as consultants to course correct and deliver on our obligations.</p>
<p>In the end try to consult like Father Mulcahy would.</p>
<h2 id="mash-consulting">M*A*S*H Consulting</h2>
<p>If you didn’t know, or can’t guess from context, my wife and I are M*A*S*H fans. We grew up with it. We bought the DVDs as they Fox released them. It’s our go-to for something comforting to watch. It’s entertaining, and full of great lines and moments to borrow for life examples. As part of marking the show’s 50th anniversary this is the first in a short series of posts (not sure how many yet – at least two maybe more) using consulting lessons from characters in M*A*S*H (likely avoiding some of the obvious choices like the doctors for things we can take from others).</p>
]]></content:encoded> </item> <item>
      <title>Thinking About Languages</title>
      <link>https://spinningcode.org/2022/10/thinking-about-languages/</link>
      <pubDate>
        Mon, 31 Oct 2022 01:05:43 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=1965</guid>  <description>If you’re a developer, go learn a new language. If you’re not a developer, go learn something different from what you use every day. It’ll force you out of your comfort zone and get you to learn more than you expect.</description> <content:encoded><![CDATA[<p>I’ve been thinking about languages a lot lately.</p>
<p>Mostly the kind I encounter in my work, programming languages, but also human languages and the intersection between the two.</p>
<p>My thinking runs parallel to what I talked about <a href="/2022/09/what-i-brought-from-drupal-to-salesforce/">bringing from my Drupal experience to my Salesforce work</a>. I have been considering what I’ve taken from work on one programming language that made me better in others.</p>
<p>A few weeks ago I asked some friends in various professional circles about their thoughts on programming languages. &ldquo;What&rsquo;s your personal theory about learning new languages? Have you ever learned enough? How often should you learn a new one? How do you count languages you last used 5+ years ago? What&rsquo;s reasonable to expect of other developers?&rdquo;</p>
<p>The responses ranged widely, but generally all agreed we benefit from learning more languages throughout our careers, but particularly when we are starting out. Not surprisingly the clarity of thinking ranged as well with more experienced programmers being clear about the value they had taken from different languages they had used over time.</p>
<h2 id="my-experience-with-languages">My Experience with Languages</h2>
<p>During my first job after college Frank Weber, an <a href="https://afsc.org">AFSC</a> volunteer who served as a mentor of mine, suggested that I should learn a new language every year. As I work with developers who are earlier in their career than I am, I have been trying to decide how important Frank’s advice was: I’ve settled on extremely important.</p>
<p><figure>
  <a href="/wp-content/uploads/2018/05/AHC_5076-234x300.jpg" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    
    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2018/05/AHC_5076-234x300.jpg" alt="Portait of Kahlil Gibran" loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2018/05/AHC_5076-234x300.jpg 234w"
     data-src="/wp-content/uploads/2018/05/AHC_5076-234x300.jpg"
     src="data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDIBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAKQAgAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AODiq1b/AHz/ALpqtCBkA9K3IdNtFUObpV3r3rh9qe4ZkfWpcir/APZtin/L6ppY7Kx/5&#43;hS9qP2pn1LV/7Baf8AP4n50v2Gx/5/E/Otfah7Uz6K0PsunD/l8FHk6d/z8isvah7Uz6K0PK0sf8vJpP8AiUj/AJbt&#43;VHtQ9qUKK0PM0f/AJ6P&#43;VH2jRv&#43;ej/lR7UPamfRV/7RpX95/wAqjN5pXo/5Ue1MvakP/LOoq0bKfTr24S1QPuPtUGo26Wl80KfdWn7UDjRqTnjbXonh/QYda8PiV2IkU4U15aDyK9m&#43;HkmdBI/2qzxulPQzORudHntZ2jd0UA9SaYLJv&#43;e0X5103iCJJMlk/iNYAt0/55isaVP2iF7QZ/Zy4/4&#43;Y6I9OXvcx1Y8iLH3RSxwRZ/1YrX6sHtSMabD/wA/cf5Uv9n2/wDz8r&#43;VWytrbx75Aq1Vk1ewjOPL/Sj6sZ&#43;1EfTIe1yv5VH9gg/5&#43;R/3zVmC7tLn7irU3kx/3BR7IPalT7Bb/wDPyv8A3zS/YrT/AJ&#43;B/wB81a8pP7lSeSv/ADzFHsg9qUvsVt/z8D/vmoWs4G&#43;RJtz/AErT2L/dFVXUC4TAx1rX6sHtS1otmsNxE7Ab81R1qT/ibS1r2H/H5D9axdY/5Cs31rKl/ENKR56M5Fez/Dr/AJADf71eOP1FevfDo/8AEgf/AHqMd/DCmTa/jyf&#43;BmsHtW1rf3H/AN&#43;sDPNGF/hmdUlqWMVFv9qWEO0wHqa6TIhls59Um8pXCRR/eY1VudDhjQqm&#43;Vh/FmtPXp0tI4LK2/1jnc5Wqss91aaawIILH&#43;KtQMVYjB80eeDzXUWMguLZH7iszT7YTWF1IeXUbqt6CcwMPeioZF8jB6UeZ2qWQe1ReXWRqRGqz/8AHwn0NWpBg1Ud/wDSB9DQBpaf/wAfcf1rE1T/AJCM31rb0/8A4&#43;I6xNTP/Exm/wB6ual/FO6kcE/UV618OD/xKZB715LXqvw5P&#43;gy/hRjv4ZlSLWvdJf9&#43;ud5zXTa1HvEv&#43;/XOkYNZYX&#43;GFUlUdKtQx5kGOtVY60NMj8&#43;8RewruOYLjSc3kcsn31Gar67btJbA7TtHfNbWqTET7oxuCDbWBGrajcvCXYgHpTqCplfS5EtrC7eT7rpsX61Hocvls4NaV5pdwY9pQRwL096yvsN1A5eNHYf3sUjM6DzM9qKo2c8jQ4kGHq6DxQagY&#43;KzOPtn4Gr00r7TWamTOfpWYGlZ/8AHytYd9/yEZf96tyx/wCPpP8AdNYV8f8AT5fqaypfxTupHEV6h8Nj/olx&#43;FeXnpXpnw1/1M/0FGO/hGVI2dd&#43;5Lj&#43;9XNA8V0evSbFl&#43;tcohMhrLC/wgql6OTPFaukhyWKD5ulYmRGOtdT4eVRbmTG411UjmqF2aGOK2MZwZHHNU9L0hLB3uGbcXPFSkv9rbf1br7Cr1jH9sugsfMKferQyL1rpgnHnXfzD&#43;FauNbW6wlPKQAD0qwAAoA6Cs69udkc49FrM1OW1uCCFllgACt6VnRtkZzWvdW5udP3f3UzXORyERY9DQBYl&#43;4aqRY&#43;0N9KleTgVWU/6S30oBF&#43;yz9qX8awb4/6ZN/vGtyzk/0tf901gXf/AB9Sf71ZUv4h6VI5CvTPhr9yf6V5nJxXo3w1k4n/AN2jHfwjmpG74ixiX6iuY47V0fiNP3cr59K5OOQk4rLC/wAMKpoWlqbudIuTk16PZ6XHaaYEQcjrWZ4P0MJb/a50yzcrXSPIFuDAejCuk5jG1TTCti08P3ytWtJtfsOjhz/rHGWrUmiD25jqrNwqRjoDUAShisCL61jX/Ny0X98VsSP8yCsi8TOqI&#43;egrQBbqKODTzH6pivPl3pdzQ9lNeh6j&#43;8tWP8AdFedXMvl6mf9qtAJZO1VRn7U3&#43;7VqU1Vjf8A0iXjsKyqhTLtj/x9j/drFu/&#43;PqT/AHq2rE/6W3&#43;7WBJ&#43;9vp037eazpHdSOVlr0H4c9ZfpXn0v&#43;sau8&#43;HJ/fyfSjFfwjL/l4dH4mz9nl/CuPg/wBYufWu18RDNvL&#43;FcaOKywv8MKp65YTNDpdsVcKnl1VmvkuJgUlG5axdEvDqWmpaM5/d8N9K1orOLcFRcLjGa6vZHMb6S&#43;bEjZz8tRE5k21T0mfMckOfmjbFWOfMZ6QA3Eq&#43;1ZEp8/WVGegrS8zM&#43;z2rMjKRa0xc444qANG&#43;hzaOB6V5JrbPb3m3&#43;61euX8vl2r4&#43;b5c149rskkk0juh&#43;9mumkBcEpkhR6IMefL9BVbT5fNtFqWPiSX8KyqhSLtkf8AS2/3awI/3moT9etb1h/x8v8A7hrCtz/ptx9TRhf4h3HM3IxO9dv8Oz/pbjP8Ncbe/wDHw1db8PD/AMTF&#43;f4ayxP8IP8Al6dlr/8AqJfoK42uu1s/JN9BXLVlhf4ZlVOx8HWvl6fNP/eNX21iyt5BvnjXZ97LVzFvrf2XTFtIW2s&#43;dxrnprJp53GTh&#43;pJrq9oZHc6J4ns7nXbiMSKiN91s9a6yF1uA5VgQD1FeU6Z4TjvQwt7grIn8QrRtrnxB4cdkRGnhH8WMij2ZmegnEc7n/Zrn9Sk/wBMjcf3hVS08a296/l3SeTJ054qyirdyF42DqpzRUA27g7rce4rzzxTCEjPC/hXfzn9wPpXH&#43;IIxJZP8vNaIDmNL&#43;S1qz/z1/CiyixarQPvy1lVCkT2X3pf9w1zscv2e5l3qfmNb1q5/ff7tYEhy7Z9azpHcZOo/wCvrp/AB/4mh/3a5nUv9fXReBDjVT/u0Vf4QP8AiHaa4cB/92uU8ziuq1oGVXAHOyuTjtLkH7jflWWG/hnNVHx9c10X2J59PQwoOV&#43;Zq57y5h/yzb8q6fQbtmsngYEbR3rpMjY8N2otdMb5Rlj1res0QQAMoIb1rM09447DBPNWra4X7OPmFRcDK17w7pl1JH&#43;6Ecjt95a5qGC88LasfMkMlq1djq8oWCOUHJVgapapBFqVsCcZxV0wKzeJbB4i5nUexrnb/WbS6R40k6&#43;9UNd8NyOFMBwO4FczJp89tJsBLGtQOmimCR7AeKiikyZa5&#43;O7urU7HUmtbTrgyQSuRzRV/hhSNK1k/dz8fw1zbn52&#43;tbcEn7u4/3KwieTXNSO6kVdS/1lbvgUgaouTgVhaiCduBmq9tc3VqcwMUNa1KftKYVf4h7VPDBLIcn5vY1D9jj9T&#43;deTDXtSB/1z1J/wkepf893rl&#43;rVDP2h6r9gj/vGgWKLna7D6V5X/wk&#43;q/89jT/APhJ9U/57NT&#43;rVRe0PT/ALI44Er4&#43;tH2WQf8tX/OvMf&#43;Er1H/ns9Sf8ACWah/wA9GpfVqge0PSjayMMGdyPej7PJjHnNXmv/AAmGof32qT/hL9Q/v0fVqoe0PRTYuw5nJ/Cqp0dScllP/Aa4T/hM7/8AvUf8Jnf/AN6n7OqP92d0dAhk5JT/AL5qlqGg&#43;Tbu8BH0UYrkx42vx/FT/wDhNL5lwTkelHs6orUy1CCsdwD121hnqavnV0uI3Ji2u4xWfXTSVjWkSkA9eaTaPQUtFZnUM2LnpUn2eP8Au03vU46UXFYj&#43;zxf3RR9nj/u1LRWgWIPs0X92j7PFj7tS0dqzuzGxV&#43;zxf3aZ5EfpVio60Myt5CZ6UeQnpUneigCIwR4&#43;7SwooPSnnpSQ9TWgybAooooA//Z"
     data-sizes="auto"
     width="234" alt="Portait of Kahlil Gibran"
     loading="lazy" />


</a>

  
  
</figure>This portrait of <a href="https://en.wikipedia.org/wiki/Kahlil_Gibran">Kahlil Gibran</a> I saw on display at the <a href="https://www.telfair.org/">Telfair Academy</a>. His writings influenced my thinking about language and poetry, but always in my native language not his.</p>
<p>As a kid I was taught and learned a small number of languages like BASIC, Logo, and HyperTalk. In college, I learned several more including 8 in the course of a 16 week semester – a rough but useful experience. After college, when Frank told me to learn a language a year, I did that for several years. My career has largely centered around languages I taught myself basically on my own post-college.</p>
<p>As a result, at one point or another, I have written programs in more than 20 different programming languages. I can learn new languages quickly, in part because it is rare for me to encounter a language that has constructs I haven’t used previously. Along the way I discovered I can even help people use a language I don’t know just based on the patterns I know from other languages.</p>
<p>On the other hand, I have tried to learn three human languages in addition to English: French, Russian, and Spanish – all went terribly. And my inconsistent attempts to learn some ASL have fallen in the middle: I had some success, but never put in enough effort to learn it well.</p>
<p>That dichotomy makes it tempting to emphasize the differences between these two types of language. In ways they are very different. Human languages evolve naturally over time; machine languages have rigidly defined rules. Human languages try to help us express the full range of our experience; machine languages are designed to get a machine to do complete tasks.</p>
<p>But many concepts connect the two sets. Machine languages, like spoken languages, are tools created by people to express themselves. We label their structures as grammar in both, because we stole the formalization concepts from traditional languages when we invented programming languages. They both evolve over time. At this point they both borrow concepts from one another.</p>
<h2 id="growing-language-understanding">Growing Language Understanding</h2>
<p>The thing that shifted for me recently was listening to a Hidden Brain episode <em><a href="https://hiddenbrain.org/podcast/watch-your-mouth/">Watch Your Mouth</a></em> about human languages. The first section featured <a href="https://scholar.google.com/citations?user=8mm3GBsAAAAJ&amp;hl=en">Lera Boroditsky</a> talking about the impact spoken languages have on how people think. She cites examples of cultural understanding of ideas around direction and gender. There are similar <a href="https://hiddenbrain.org/podcast/decoding-emotions/">ideas about our emotions</a> that are also linked with the language we use to describe our emotions.</p>
<p><em>That</em> had very direct correlations to programming. Hearing those discussions catalyzed the thinking I was already doing.</p>
<p>How I see and solve a problem in code can vary greatly with the language and platform I’m using. A Python application running on a server can use a radically different approach from a solution built in Apex on Salesforce. JavaScript running in a browser requires different solutions and details from solving that same problem in JavaScript running in a Node environment. Java largely frees you of worrying about memory handling, while many languages in the C-family force you to consider the storage implications of nearly every byte. At times when trying to work through a problem in one framework it can help think of how I’d solve it in another better suited to the task.</p>
<p>The second half of the <em>Watch Your Mouth</em> episode included a discussion of how languages change over time. It’s an interview with <a href="https://twitter.com/johnhmcwhorter">Linguist John McWhorter</a>, and his work at looking at how language changes over time. He pushes back on the notion that we should all use the version of English someone tried to teach us in school:</p>
<blockquote>
<p>“It&rsquo;s a matter of fashion, pure and simple. People do need to be taught what the socially acceptable forms are. But what we should teach is not that the good way is logical and the way that you&rsquo;re comfortable doing it is illogical. It should just be, here is the natural way, then there&rsquo;s some things that you&rsquo;re supposed to do in public because that&rsquo;s the way it is, whether it&rsquo;s fair or not.“</p>
<p>John McWhorter</p>
</blockquote>
<p>Programming languages have fashions and patterns – and they are rarely fair. A new language like Go will become popular in part because it’s new and used by a popular company. An older language will go out of fashion like C++ or Java, because newer languages feel more graceful even if there are technical trade-offs for that grace. They evolve, more formally than English but less formally than people pretend. Just because there is a standards committee does not mean that committee is purely selecting the “best” solution.</p>
<h3 id="technical-intersections-between-languages">Technical Intersections Between Languages</h3>
<p><a href="https://xkcd.com/1726/"><figure>
  <a href="https://imgs.xkcd.com/comics/unicode.png" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    <img class="rcf-image external-image" src="https://imgs.xkcd.com/comics/unicode.png"alt="XKCD with an Engineer thinking he can control the flow of languages"  loading="lazy" />

    </a>

  
  
</figure></a></p>
<p>There is also a point where all these languages intersect: Unicode. Unicode tries to give us ways to express human languages in machine form – all written language. <a href="https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/">Every developer should understand how language is stored in files</a> because our code is stored in that format, our servers talk to each other in that format, and humans will express themselves to our applications in that format.</p>
<h2 id="my-theory-on-programming-language-acquisition">My Theory on Programming Language Acquisition</h2>
<p>Like plumbers, electricians, doctors, nurses, and really anyone with a career: Developers need to master the tools and techniques of their trade. Programming languages are tools, and the techniques we learn from one make us better in another. We do not have to like the language designs we encounter, but we need to understand them.</p>
<p>Every developer should teach themself a new language on a regular basis, either for work or for their own education. We should pick languages that are uncomfortable to us. Some should be new and popular, some should be old and foundational.</p>
<p>So if you’re a developer, go learn a new language. If you’re not a developer, go learn something <a href="/2016/09/try-doing-it-backwards/">different from what you use every day</a>. It’ll force you out of your comfort zone and get you to learn more than you expect.</p>
<h2 id="languages-ive-written-one-or-more-programs-in">Languages I’ve written one or more programs in:</h2>
<p>Just for fun, here’s the list of languages I can remember writing something substantive in:</p>
<ol>
<li><a href="https://en.wikipedia.org/wiki/C_(programming_language)">C</a></li>
<li><a href="https://en.wikipedia.org/wiki/C%2B%2B">C++</a></li>
<li><a href="https://en.wikipedia.org/wiki/C_Sharp_(programming_language)">C#</a></li>
<li><a href="https://en.wikipedia.org/wiki/Objective-C">Objective-C</a></li>
<li><a href="https://www.python.org/">Python</a></li>
<li><a href="https://www.ruby-lang.org/en/">Ruby</a> (with and without <a href="https://rubyonrails.org/">Rails</a>)</li>
<li><a href="https://en.wikipedia.org/wiki/Java_(programming_language)">Java</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript">JavaScript</a></li>
<li><a href="https://www.php.net/">PHP</a> (versions 3-8, which only have passing resemblance to each other)</li>
<li><a href="https://en.wikipedia.org/wiki/Active_Server_Pages">ASP</a></li>
<li><a href="https://en.wikipedia.org/wiki/Logo_(programming_language)">Logo</a></li>
<li><a href="https://en.wikipedia.org/wiki/BASIC">BASIC</a> (for <a href="https://en.wikipedia.org/wiki/Applesoft_BASIC">Apple ][</a>, and <a href="https://en.wikipedia.org/wiki/Rainbow_100">DEC Rainbow</a>)</li>
<li><a href="https://en.wikipedia.org/wiki/Visual_Basic">VisualBasic</a></li>
<li>VB.Net</li>
<li>VBScript</li>
<li>VBA</li>
<li><a href="https://en.wikipedia.org/wiki/HyperTalk">HyperTalk</a></li>
<li><a href="https://en.wikipedia.org/wiki/AppleScript">AppleScipt</a></li>
<li><a href="https://trailhead.salesforce.com/content/learn/modules/apex_database/apex_database_intro">Apex</a></li>
<li><a href="https://www.r-project.org/">R</a></li>
<li><a href="https://en.wikipedia.org/wiki/Scheme_(programming_language)">Scheme</a></li>
<li><a href="https://www.haskell.org/">Haskel</a></li>
<li><a href="https://en.wikipedia.org/wiki/Perl">Perl</a></li>
<li><a href="https://en.wikipedia.org/wiki/Prolog">Prolog</a></li>
<li><a href="https://en.wikipedia.org/wiki/SQL">SQL</a>, T-SQL, SOQL, and SOSL (sure arguably not languages which is why different flavors are listed as one)</li>
<li>HTML/CSS (together they are <a href="https://accodeing.com/blog/2015/css3-proven-to-be-turing-complete">mostly Turing complete</a>, so arguably counts)</li>
<li>XML/ <a href="https://developer.mozilla.org/en-US/docs/Web/XSLT">XSLT</a></li>
</ol>
]]></content:encoded> </item> <item>
      <title>What I Brought from Drupal to Salesforce</title>
      <link>https://spinningcode.org/2022/09/what-i-brought-from-drupal-to-salesforce/</link>
      <pubDate>
        Sat, 01 Oct 2022 01:44:14 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=1958</guid>  <description>&lt;p&gt;If you look over this blog, or know me, you will see that I&amp;rsquo;ve now have reasonably significant experience as both a Salesforce and Drupal developer. The last couple weeks I have been thinking about what from my Drupal experience supports my work as a Salesforce developer.&lt;/p&gt;
&lt;p&gt;I think there are three parallels that are encouraged in Drupal developers that helped me learn to be a good Salesforce developer quickly.&lt;/p&gt;</description> <content:encoded><![CDATA[<p>If you look over this blog, or know me, you will see that I&rsquo;ve now have reasonably significant experience as both a Salesforce and Drupal developer. The last couple weeks I have been thinking about what from my Drupal experience supports my work as a Salesforce developer.</p>
<p>I think there are three parallels that are encouraged in Drupal developers that helped me learn to be a good Salesforce developer quickly.</p>
<ol>
<li>Embrace, don&rsquo;t fight, Platform Constraints</li>
<li>Extend the Platform&rsquo;s Strengths</li>
<li>Leverage Events</li>
</ol>
<h2 id="embrace-salesforce-platform-constraints">Embrace Salesforce Platform Constraints</h2>
<p>Both Drupal and Salesforce run in constrained environments. Web applications, regardless of their purpose, have to protect themselves against bad actors and bad neighbors. There are execution timeouts and memory limits, for both platforms. Salesforce adds a variety of additional limits and governors, but they are all logical extensions about memory and time. Lots of other platforms allow developers to ignore resource use until they reach a crisis point. Don&rsquo;t believe me, just check the memory used by Chrome, Electron Apps, or any other Chromium-based application.</p>
<p>Working in resource constrained environments forces you to think through how to use the resources you do have efficiently. While these platforms aren&rsquo;t like working on hardware with highly limited resources, they still can test your resourcefulness.</p>
<p>Drupal and Salesforce both provide ways to <a href="/2019/01/drupal-8-batch-services/">run large jobs</a> across many processing contexts. New developers on both platforms often only resort to using <a href="https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_batch_interface.htm">batch</a> and <a href="https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_batch_interface.htm">queueable</a> operations as a last resort, but learning to use those solutions is critical to success on most interesting projects. When you try to avoid them you create solutions that appear to work and fail at scale.</p>
<p>Coming to Salesforce from Drupal, I already knew and understood the importance of asynchronous batch processing. So when solutions needed batch processing it was second nature to learn that part of the platform.</p>
<h2 id="extend-the-platforms-strengths">Extend the Platform&rsquo;s Strengths</h2>
<p>For all Salesforce&rsquo;s push and marketing to avoid code, Salesforce developers are often taught that once you write code you just do everything in your code. The interfaces you can use to extend the platform&rsquo;s existing solutions are treated as advanced topics. But when you work with Drupal, you are encouraged from the start to create modules that build on and extend the platform&rsquo;s existing strength. Drupal developers are encouraged to leverage the features and utilities all around them.</p>
<p>This has always been true, but even more after Drupal&rsquo;s move to leverage Symphony <a href="/2017/01/drupal-8-plugins-are-addictive/">plugins</a> and <a href="/2019/01/drupal-8-batch-services/">services</a>. As a developer used to extending the platform, I came to Salesforce looking for ways to extend the platform&rsquo;s declarative tools.</p>
<p>Often Salesforce developers create powerful solutions built purely in code triggered by record changes or simple buttons. They look passed Apex Actions that extend the Flow declarative automatons, platform events, and other tools that extend the system. But when you embrace a platform&rsquo;s basic structures you often create more flexible solutions than your could with pure code.</p>
<p>The mind set of extending a platform, which I brought with me from my Drupal work helps me create tools and solutions that are designed to adapt over time.</p>
<h2 id="leverage-events">Leverage Events</h2>
<p>Event driven architectures are not new, but their popularity continues to grow. Where platforms used to follow informal patterns that equated to event systems, now we see formal event structures being build to replace old habits.</p>
<p>Drupal and Salesforce both have had event frameworks for a long time: Drupal had hooks (events by naming convention), Salesforce had triggers.</p>
<p>Both have seen major upgrades to their event patterns in recent versions. Platform events in Salesforce, still making their full power clear to a lot of developers. Symphony brought proper events to Drupal in version 8 and continue to help push the platform forward.</p>
<p>I have learned to leverage the events systems on both platforms. Understanding them as tightly constrained state machines, and learning to push them to their limits, helps me get the most from both platforms.</p>
<p>My experience with Drupal hooks and events has made it obvious to me when to leverage Salesforce&rsquo;s Platform events. As Salesforce increases the number of places you can use them in their declarative tools, it increases the value of this approach.</p>
<h2 id="so-what">So What?</h2>
<p>As a developer, what you learn in one part of your career can make you stronger in the next. As a field we&rsquo;re not actually that creative. Even if the details are different, the concepts will often carry forward because they are built on the same fundamentals. Whatever platform you are using today, learn how to make it sing – it&rsquo;ll help you learn the next faster and better.</p>
]]></content:encoded> </item> <item>
      <title>My Ongoing Liberal Arts Education</title>
      <link>https://spinningcode.org/2022/08/my-ongoing-liberal-arts-education/</link>
      <pubDate>
        Sun, 21 Aug 2022 19:55:35 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=1917</guid>  <description>We all can benefit from being conversant on many topics and understanding their interplay. That broad understand allows us to be more informed in our lives.</description> <content:encoded><![CDATA[<p>I consider listening to good podcasts to be part of my ongoing <a href="/2016/10/what-i-learned-by-getting-a-degree-from-a-liberals-arts-college/">liberal arts education</a>. We all can benefit from being conversant on many topics, understanding their interplay, conflicts, and mutual inspiration. That broad understand allows us to be more informed voters and more flexible contributors at work. It also just makes me happier.</p>
<p>I make a point of mostly listening to things outside my field of work. I study my work 40+ hours a week already. In my spare time I like to learn other things. Right now my rotation includes shows like <a href="https://hiddenbrain.org/">Hidden Brain</a>, <a href="https://freakonomics.com/series/people-i-mostly-admire/">People I Mostly Admire</a>, <a href="https://freakonomics.com/series/freakonomics-radio/">Freakonomics</a>, <a href="https://www.npr.org/programs/wait-wait-dont-tell-me/">Wait Wait Don’t Tell Me</a>, and more.</p>
<p>I tend to listen to things in fits and starts and then suddenly in waves. If I walk the dogs alone I&rsquo;ll listen to parts of an episode. While mowing the lawn I&rsquo;ll squeeze in a couple things. But it&rsquo;s really the long drives that let me pack in a lot of information. For example, at the end of June I had to do a 12 hour drive on my own, twice. So I got caught up on some episodes that had been building up on my phone.</p>
<p>One of the things I like about listening to these shows is different perspectives on different topics. They provide me a chance to hear overlapping ideas that inspire new ideas related to my work or life. Sometimes those overlaps build on each other, other times conflicts in ideas push me to think deeper about both sides.</p>
<p>This I listened to a <em>People I (Mostly) Admire</em> <a href="https://freakonomics.com/podcast/a-million-year-view-on-morality/">interview with Philosopher Will MacAskill</a>. They talked about extreme long-term view of morality, <a href="https://www.effectivealtruism.org/">effective altruism</a>, and the limits of growth economics.</p>
<blockquote>
<p>Currently, economic growth is like 2 percent, 3 percent per year. What happens if that continues for just 10,000 more years? Well, 2 percent compounded over such a long time gets to a very large number indeed where it would mean that for every atom within 10,000 light years — so, every accessible atom within that time would have to produce the economic output of some enormously large number. I think it’s something like 10 to the power of 60. But just think trillions times trillions times trillions of amounts of output as the entire world economy today. And now, I’m not claiming I’m certain that’s impossible. The world today is magical and fantastic and would be judged as such from the perspective of people 1,000 years ago. But it seems really unlikely that every single atom is able to produce many trillion times the economic output of the world today.</p>
<p>Will MacAskill</p>
</blockquote>
<p>It was a compelling enough argument to get a <a href="https://en.wikipedia.org/wiki/Chicago_school_of_economics">Chicago Economist</a> to question his assumption that economic growth is a given.</p>
<blockquote>
<p>But it’s funny because, as an economist, I’ve been so indoctrinated into this idea that economic growth is natural, it’s good, it’s part of life, that just something should have been totally obvious to me, but wasn’t because of my indoctrination, all it took was a few lucid arguments from you.</p>
<p>Steve Levitt</p>
</blockquote>
<p>During the drives in June, I wandered through several hours of <em>Hidden Brian</em>. The episode that stuck with me was, <a href="https://hiddenbrain.org/podcast/do-less/">Do Less</a> featuring <a href="https://engineering.virginia.edu/faculty/leidy-klotz">Leidy Klotz</a> talking about the power of subtraction from designs. But it&rsquo;s not just the singular interviews that I find useful. Listening to large amounts of divergent information causes ideas to cross pollinate. The Klotz interview connected in my head with an episode of <em>People I (Mostly) Admire</em> featuring <a href="https://psychology.fas.harvard.edu/people/daniel-gilbert">Dan Gilbert</a>, <a href="https://freakonomics.com/podcast/turning-work-into-play/">Turning Work into Play</a>, which included the advice to do less, better.</p>
<blockquote>
<p><em>Well, I’m loath to give advice because I’m telling you what worked for me. And that doesn’t necessarily mean it works for anybody else.</em> But I do suspect that many, many people would be much happier if they did less, better.</p>
<p>Dan Gilbert</p>
</blockquote>
<p>That whole line of thinking has me trying to re-frame how I talk about building tools as part of my job. How can I make my work better by removing tasks? I even started to write a response piece in my head, which may come together some day.</p>
<p>As a Salesforce Developer (and a Web Developer before that, and a Nonprofit Communications staff person before that), I get encouraged to listen to a very small set of information. People assume I listen to Salesforce Podcasts and not much more. Many of us are encouraged to spend our personal time learning about our work – usually narrowly about the sub-field we&rsquo;re in.</p>
<p>My point isn&rsquo;t that they are always right, nor that I&rsquo;ve picked shows presented by people I always agree with. The guests and hosts in the podcasts often express interesting ideas, but also have view points I disagree with or ideas that conflict. For example, I find that Steve Levitt (who I mostly admire) has an overly simplistic view on gun violence. <a href="https://www.npr.org/people/137765146/shankar-vedantam">Shankar Vedantam</a> often has guests on <em>Hidden Brain</em> whose ideas conflict with other guests. My point is that listening to these ideas, letting them challenge my thinking, and building on them my life better.</p>
<p>Life is big and complicated, and involves a lot of not-work. Go find some things worth learning about that aren&rsquo;t part of your regular activities. See where it takes you.</p>
]]></content:encoded> </item> <item>
      <title>Getting Started with Salesforce2Sql</title>
      <link>https://spinningcode.org/2022/05/getting-started-with-salesforce2sql/</link>
      <pubDate>
        Sun, 15 May 2022 22:52:04 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=1875</guid>  <description>A getting started guide for Salesforce2Sql schema generator.</description> <content:encoded><![CDATA[<p>A little over a year ago I started work on <a href="https://github.com/acrosman/Salesforce2Sql">Salesforce2Sql</a> to help support people doing data work with Salesforce. Salesforce2Sql is a simple <a href="/2020/12/salesforce-electron-starter/">Electron app</a> that allows you to clone the schema of a Salesforce org into an SQL database (currently supports MySql/MariaDB and Postgres). These mirrors are useful when you want to stage data during migrations in or out of Salesforce.</p>
<h2 id="when-is-salesforce2sql-useful">When is Salesforce2Sql useful</h2>
<p>Salesforce2Sql is a tool dedicated to doing one thing very well: mirroring Salesforce <em>schema.</em> It does not attempt to extract data or convert data in any way.</p>
<p>Salesforce provides excellent APIs for data import and export, but they work best with some prep work first. Salesforce2Sql gives you a staging database that mimics your Salesforce schema. In these schema mirrors you can prepare all your data for high speed processing off-platform. Anyone who is looking to move data into or out of Salesforce at high speeds and large volumes benefits from this setup.</p>
<p>I have seen people write large complex ETL jobs meant to go right from one source system into Salesforce. These jobs can be hard to test and they are slow to run. They generally don’t give you an easy way to review the data before you push to Salesforce. By landing the data in a database clone you can break the jobs into stages, review transformations before they are loaded, and run thousands of iterations for testing instead of dozens.</p>
<h2 id="setup">Setup</h2>
<p>Salesforce2Sql is built and released for MacOS, Windows, and Linux (most testing is on Mac and Windows). You can download the installers from <a href="https://github.com/acrosman/Salesforce2Sql/releases/latest">the current release</a> and follow the standard patterns for your OS. From there start the application to get to work.</p>
<p>You will also need API access to a Salesforce org and a database to create your schema within.</p>
<h2 id="basic-salesforce2sql-use">Basic Salesforce2Sql Use</h2>
<p>As of this writing Salesforce2Sql uses the old <a href="https://help.salesforce.com/s/articleView?id=sf.user_security_token.htm&amp;type=5">security token connection</a> method. I would like to <a href="https://github.com/acrosman/Salesforce2Sql/issues/6">add OAuth2 support</a> as well  but haven’t gotten that done; contributions are welcome. So with the application running, and your security token in hand, click the big “Create New Connection” button on the left side of the main interface.</p>
<p><figure>
  <a href="https://github.com/acrosman/Salesforce2Sql/raw/main/documentation/InterfaceScreenshots/MainScreen.png?raw=true" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    <img class="rcf-image external-image" src="https://github.com/acrosman/Salesforce2Sql/raw/main/documentation/InterfaceScreenshots/MainScreen.png?raw=true" loading="lazy" />

    </a>

  
  
</figure>Salesforce2Sql Main Screen</p>
<h3 id="step-1-fetch-all-objects">Step 1: Fetch all objects</h3>
<p>Once connected click “Fetch Objects”, and the tool will download a list of every object in your org. There will be several hundred. So the next step is to select which you want to mirror. You will notice Salesforce2Sql selected defaults for you (well I did). It will select all custom objects and based on your org’s structure Salesforce2Sql guess which standard objects to select.  There is a search box at the top right to help you find any others you’d like to add but simply checking the box.</p>
<h3 id="step-2-fetch-all-fields">Step 2: Fetch all fields</h3>
<p>Click the next button to move to the Proposed Schema tab, and then the “Fetch Details” button. Now Salesforce2Sql will query every field on every object you just selected (this may take a moment but honestly I find it much faster than I expected when I first started this project). Once that is complete you can either save that schema to JSON for later re-use, or click Next to move to the “Generated Database” tab.</p>
<h3 id="step-3-generate-tables">Step 3: Generate tables</h3>
<p>This is the last step. Click “Create Tables” and Salesforce2Sql will ask you for your database credentials. Once you click okay on this final screen the tool will attempt to create all those tables for you. Again this will take a couple minutes if you have a large schema.  Once the process is complete you can also save the SQL statements for editing and/or later re-use.</p>
<p>That’s it, you now have a database with a schema that matches your org’s structure.</p>
<h2 id="preferences">Preferences</h2>
<p>There are a few preferences you might want to experiment with (although I tried to pick smart defaults) when building mirrors. For me the right choices depend on my use case.</p>
<p><figure>
  <a href="/wp-content/uploads/2022/05/Sf2SqlPreferencs-748x1024.png" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    
    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2022/05/Sf2SqlPreferencs-748x1024.png" alt="Preference screen from the application with sections for picklist settings, index settings, other defaults, and theme." loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2022/05/Sf2SqlPreferencs-748x1024_hu_78be3673b6282c29.png 680w, /wp-content/uploads/2022/05/Sf2SqlPreferencs-748x1024.png 748w"
     data-src="/wp-content/uploads/2022/05/Sf2SqlPreferencs-748x1024.png"
     src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACvCAIAAAC6pkF/AAAxwklEQVR4nOx96XMb2XXv3XoBQILiUBqNRhl7HGfiSfxcL3blS/L/f0ol9Vyxy1X2eGRbMq2RRFIkgUYvd3t1z&#43;/2ZbMBUSRFbRaPxjIENoG7nv38jvriiy&#43;Kotjd3d3b25NSrlar4&#43;Pj1WplreWcCyGm0&#43;m9e/eyLDs8PDw5OTHGeO/ZgLz3nHO8YIxxztOL4U/dgNgt9aSapsmybGdn56uvvsrzfLVaHRwcnJ6eGmOklEKI2Wx29&#43;5d55z3vixLS4QlVko554wxSinGmDHGOSeE8N475/I8x5tKKe99Xder1aqqqrZtb/cgkdJaY2V3dnayLCuIPv/8cyHEZDLBJSiKouu63d1dIYS1tq5rbM9kMsE/syzDTlhrtdbWWmwq5xwbrLV&#43;9uzZ06dPV6sVHhtdo0&#43;WFI42eEXbtsvl0jlXFMV0Op3P5957rbUxhnN&#43;586dsiy11ovFommaoii2t7eNMavVyntvjJlMJsaYw8NDYwx4mnMOG9A0zWKx4Jxba2&#43;50JAC67DWLhaL/f39qqoWi0VZlltbW9vb2zjLTdPgzM7n86IotNbL5bKu67Isu67TWtd17Zyz1u7s7AghsGGr1Uop1XVd0zRlWeLLhBCQB7eUKHDnpmmeP3&#43;&#43;JGrbdko0mUzm8znnvK7rruustVtbWzjjVVXVdZ3n&#43;Xw&#43;d85BYjvnptNpnue4DS9fvizLEjegLEul1HK57Lrufc/3gyNeFIWUMs9zHFjnnOqpLMt0op1zkBDOubZtjTFCCBxtXBTvvZRSKSWlBJOBZLbWQphrrZumqetaa33LghLxPM850VCPxN9CCLyZ3oeGk95Zf2Bd&#43;4xfQ7op5M3t6g&#43;JQ1l85Y97pT79M&#43;3T&#43;j9Hb66/eGuz&#43;IhJ4f&#43;Gh3dE62&#43;O3rn4t9ZfvDmlOzf6uo9Fwie1M26AEEISfRQTABOD2B/yRqUUWOKHTzBmMX6F0ed5XhQFxOYHTs65pPviHc55lmVlWWZZ9uGfIZhWUEbCBuAGYAJKqQ9/As45znnXdfBKpeMPG/5jGT90y8iCMAcwostMYCSZ3yUl7WvEbTD49fevR69SLt581jgxw3U&#43;E8JJjkEeJG4LVoXp4dZD04fuj1/EyPC53vvhj4bfPRQ&#43;1yPe06t&#43;OtwMjB9bkgY8fDidueF0YMpYa3HD0pJJKTE1LML1ZjFyFZ9tQPqxUmpra2s&#43;nyfTqWkaa21RFHme49bAJwq3GowvrTX8pnmed11XVVX6UbIekkG37s1Os3pzgnk4n88xyK7r4P&#43;oiUbfUpbl9vZ2lmVt21ZVpbVWSsGer&#43;u6qirsCnzyW1tbcLHALzDUAt6ExhuQ5/ne3t7Dhw/hAa2q6uTkpOu62Wy2tbWFzYAH4vj4WGtdFEWWZScnJ865e/fuzWazpmngzc7zvCxLHJ&#43;u6zB/Q4RFwQut9enp6frqXI&#43;klPP5/OHDh/Akdl2XZZn3/uXLl/Az4jHnXNd1k8kE4ZCmaRDqgIcRM1oul4lT7&#43;3tff75513XHR8f13XdNM1yuUw79CYDHqs9UsqyLGezWVEUs9nszp07Ozs7dV3jNXwJ29vbQojd3V34Tb33cOTBgXrnzp379&#43;8jWqCUstYKIfCLeZ5j5lmWMcbatlVKVVX1l7/8BV6QN5kJCM5z&#43;LLgZYH7ZDabWWuTd6RpmoODA875ZDLJ83wymdy5cyfP8yzLwGnh6IWjrG1bbEDbtvP53FpbVdX&#43;/j6UmTcc8HgDwBDatm2ahnO&#43;vb09nU4ZYzjOGJxSKs9z8FYhRNu2YKNaa8751tYWdiXFBqSUCBjAdzSbzSaTCWOsrmuwKWgvNyXbk6EALzpGwhjbJsIJODk5Sb7xoAuS42tra4sxBv4JV6NSqmma1Wo1m80gF7FJWZYdHR0lmfcmox1vgDFmsVg8ffoUq4lzgS3BfcSAEAvDdyOK0DRNVVXwV0NKayJMxhjTdR1spQkR5xxOvcVi0XXdunF7PYL/dblccs6rqsId1VpjEeu6RtjjlIgxtlwusT2LxWK5XHrvl8sleNF0Os2yDCNHFAS/DpYFbvzmAz63ARCVL1&#43;&#43;XCwWiAkfHx9DkEKWQilKOka6MYgZtG17fHycFEEcw6Q1geODR2N3Dw4OsHOnp6c3Mhmwl&#43;Vy&#43;fTp08PDQ1wFqDRa6yzL4PjCearrGvYEIqa4B1gBvAY7St5DzBQiDREUPPmGAx5vAEKM6Wbh9UibHGmByT&#43;Kh0c/GmnQQojFYnF8fIwTinN0g1oQbgCUn&#43;G3D9Vi/BMGETjtKIsgPTwyCIZzfyta0MhPhK&#43;50uQv8xiUuZQnceOOUqzLaOSjc5O&#43;cX3MIz39bdN4A3DFoCYmQyy8H2xMznw/E86880PGfYHPOU6mn9MwJJDmeYN7AHs4jJ8xfProqEK1TwNIV2Q0pJF9mjhw8n/483S90Y7tADjmoPDgtBprnHVCyjzLfBi9k0LiR0kLTtEbBFyGERv8iOMP5847Z93wUidl6Ub2QAiR5dmknMjA0B1nYRtsbwCm80RDCoMLw&#43;YMQ0qLyzj39FiWZVB&#43;IL2MMQjnCSkylTHOTFAyDHSN641/ww3I8mw6naosU2R8Qw1A6goXnBT8jDPW6c4am1afC0FrGyRvEr9ZlgXNR4p&#43;/QX5kW1iCNa6jpQoKBhvvgGc8yIv5vN5URb4PM4YEjGsNbrTEA95nkulJK0rY94YG8ZOz2FLjA7215mDjzMhZPgEbRxZNnmRBxnedkHpqipHgfEb2AAST946K5zgmcqzPPeFEKLrOh7eyLgQmVKMFt0qmxzxQc8JS2&#43;ZZ847YyzzPg92siIrIVwezoVX0jvPBQ&#43;/xYMZXJGZdlM8N3l4pAxfBOaZhzXlWndhbGTHlJMyzwtJ73tPjiDnPQu3VxBHamXHSOMsykJwcoJxlmWqLIihMSaFwP56FvTallbgGmdorAXBfOdVkARt2&#43;ZZMLjaruvattM6zzIhpehTDaMPLiwlt&#43;nUkzPLk94ZrIFOpocjtw13SJblREkZLAVyrdzI6qdowWq16rQOy8m84ELSETHk2kp6pzXh9DjvIMwGoTv6kE6DKRljIo9iXspwaaISFf94OFeuLQQ23ACwuXCU6ijNwFKiH5VE8TkKFzQcBOZjbEQpBc6YZJrzDj/t90wWRS3pYoXj042TFa8tnGFnpQxJvJlmgTPBOa&#43;bRvUe3ySrh1&#43;KM5H822H8jBEjFYw&#43;FjPCC6PDx7IbkQFDRTju/2Ah0lEd&#43;p&#43;HSxb2zxgxmEn6KOgekMN08DXep6Gz4XolTewaSYwX&#43;1bTRwWzceMTYeR&#43;fMLO/XzDybhhLSiF98DWWZJlLGpkvg/J5kRJ4QkS24ZF88RnM3K9OfIFRdc8rSu8NMMvDfKBPhMbrJTKi1xwsVqtriScz7jc637lw0nR2OANnUwm29vb8FxGlZlzbAMEAHwPndaTSTmdTgP/IcJpBU9UWVaQC0hrnRe5lIh9cnihw0L7KM2gaQfZo7umbhhnQfAVhSdu3jTNdadGZ/mDpw03IAWJnPcZOT6DegBTIM&#43;lFLrT9FMneyLRF4RVpsIfo00QFQPuRDotIkrBjCDlmltrgqLCueh9luEV45LYbroQl6fe4gtyNzDrYLRYBkNyk504MnrXbbH1izLKf9mYlJYeZZew0Tb4gto2ssewAaSJ4v0syybTaVCKmqaiwJDRpmuj10UbA87DRVA6fe8PcM61XZdlNR6zxiZD1NAGwEbDDejajpNCJeiiXCdIwIUsJvnWnWyy5a3pqmPbVIJ5ObDtsVJDs3boL0qyd/gAi5IhvMKZiywXt/n82cUZCBMx9rU22oYNaJpGGw3GAiPWkwUspaxWFUX0A2cJT0ZLMmz1UMyODPRhUnScp4Ai61lveYZ/0m7BQ7kxinsZEkqV8727//gvnz34qqvrF3/5w&#43;r5k5yZsshJ6Qw6PxbL9JRUJi64DFeHK6lg98a1iy4UcsQ4j/AGDEwsRdz6noQUiJeQo3eRzNLXb8DZnfJMyLiUMHfTj1IcJnnT0snCeg3dDGlkw8&#43;/2HE0GsyVVj98sFTlfPeLH3/z9T9/Wy0Wumvs6qR07fbWNGU9BUHGOOkLpl7VTdvgyPcRsbD8XPCoLPhwnHul3&#43;NSSiHzIi/LEpIMtzaYSuQyyItiNp0KuiV1XbfNRbGmDTIAwchgajOuTRhnXHFi1kgaAI&#43;OykyvsDZN3TbtxrD7G6/spYnMWetsGLi1jv4zLholxCXEmV2Cs00vpKCsFpJC4QAS5yNeEzYjzNQwR&#43;&#43;CiUG/oJ8K0QfXyLFuGck85RU07ItpfAOUUrPZbPez3TzPrbEdohNIVCHmFgxdpXx0PDhIGkszPl0ouFPen5IXLmx9evTDoz80q1XXrF7&#43;7S/N4rizXVevoMIJOv6JQ8KjJaTABkALGKYVIyyjTfjjwseTKRcMMimHTkb4wVxYh4Y3TV2roMdbBG0uKwMiIxPRTaaNdtaKsPSc2B/9r3d5hq0Ozwt8ddQyIRLeH3lr9PL4&#43;Mnv66OnYS1Oj/RqybztWt5rKgwbcBZKInfF8EOGPBPyNoVfhrI6Psn7m9TL9uivlpL3hYsXDHhDTLhaVtY6XCvciXMudWJEvXUeBgA3FmNcB71IX88ivyninOWSzXO&#43;VXJj2HHNq6CVUTCDCCueViruBPPj8gji&#43;ylwdvbk5Y3ePiXgympokBuU6LAeeRhMdIOVk1zql16umyel1N29vX/513/96h/&#43;oa7rP3z33WPKeYHLNsV1uRCOZBhU4agFDVI0RW&#43;xD9RQBg8joheXGcxllmJzWsq1I7Tvd/WRWHb//v1f/tu/ffvtt4vFQghRUe3bZDKBJUjqpiAlnbSgpoYpwzgPOlCe0QYoKYQh9z/UU08s2FlXVRUSvG5qppvz0T8cV8lVCWJzNpvN53MkHw6MoxgCgyvfyqBvktricOqhhsZbgH1QkjhuMNopYBOsVH6jVQibNiAGQkm/IePjMtO&#43;pCmfHngbewzT9Ojo6I9//CNyfh4/fnx8fIyyToTAJK0p8UrS69sOKaFQIpu2gRYEfo8YFPIntTGO3ATu5qIXmzaAC6EymZdcKmc617XM2RRUHy7x0A0yCm1vzD8YeufPJUszn7SIN/Hrgrqu&#43;&#43;GHH/7rv/7r&#43;&#43;&#43;/b9v22bNnR0dHSJGDggeFp1coWApDggvx84eJI95HfhHoM0Okhhuh8xvAuVBZubO3de9hPpnVi5Pq8G&#43;&#43;WWZSqN5Dl8LWCKIi8xCWN8L38OZHqQXfC0IC5AYIXxmDlGRcDpIMUurum&#43;QIIWWqbdv9/X1Ex5CcGuNC1hkfHezR4YNAvXfcBhNBSZXOBz4wCF4KUsEGfvMjMqKRJSxUOZ3f/9GP/vVX25/dPXi6v/97YV7&#43;bZbLsiykiAXAMFiMNnCfITFdKmUoRwARBZJaiN3FuCCMded9WRRCCmQpQOCLyGctcnhh0F97Svictm1Tan9OsXUlJZw5WEJJXllrYgppqhQif6Lo2W9YlCCr6/rGzz5o7QbIrNya735&#43;f/feF1qbgydbfpFnmSyKEjE8xpmU4QjT4rfgp&#43;d9KdgA76xL90AERcJLcoHl/Vr0PCf8Xzr7XdddW0IMS2KH3DLL1NZsVpQlhCruLlxvOAFSSkokML2FK84&#43;sU9W7Cg79i1vQDC1u3pxfPB0v2mao2d/a5YnXVuvLLdWR28J/eU9fEG6owTbrutiJgKZ561scfR5Hy7mxHnJg60RSAD/hyWP5BTo3Tdbxh1zgWzk3bQBcYec9TAh4Uf2Np555FU775Mcs9eN916GRoaYs219&#43;sPjx9Zk5bRZnq4On9p6qQWTKcWKFpX1HCYtWbJihg&#43;k1zELyEWdb5i4iSgx4gTXc0Gf0SYvCLJFnfeqqlSmAjPsDZ1hVVZ0p1OakDW9JQQllHOdXNM3TeMbwKxx9aI7&#43;pvLctPUrlkGXYgxs2luyTGysXQbLGb9&#43;XMfcd4zkx673mR6jwxFxKIq6XwviteTbUcDTmb/0M5KCl6yfjemML0quPZaGrujs0x9dmf&#43;4MsvZ7PZycnJD0&#43;fLpfL5I7G0Pj5iBK4P&#43;fc0DUPB6rnoWdpoH0ofxQzuHGiaMhEzuYynzBnbbO09ZI5M6ye3OgeH8bLhp6fUfni0D2T3GKpwC/lv5xz9l3eGwp95qc//em///u/37t3769//ev//M//PHnyhHGWZzkXcHx6MBp4RVCOgQKSjv4JIcyicI2ZoFxwZx2KO94qaA2XWbZzd&#43;vhP09273HbVc8eVz/8WehVmWciaNLhSsRDkG7M6Jj3Ab7o4kXxKxes/11K&#43;MgQKEvaM&#43;4Hxcwl&#43;BX2Rmvdkni7bEBmMpncv3//m2&#43;&#43;efDgwWQyefLkyeHhYbTplewPguKc6U63XVevVshPkZSHggsRtSDnoixwQdB575bLCtv2tm4A51xlxc7d3R//bO/h176rnwtpli9Vy&#43;db04KMFUsue5xP3GY49rFYXduRp4gsBnqsKEi147HQE3WJk8mE97niSCkNDzufF4WUom3aTndZlguqzjw5OWma5lIbEN3RVXV0dIQyqKqqYv1Q7xmXUlgbtIKgQOtIJphjgoJlSoTDbpMjFwcKw3XurUPF4XyU5WQ6m7WC8ywXZFshVBvWkTGOSjzKyuZCFEWOYkI6/oyCNlKIqIwVeZHnOePMEoftfUQEi0Q6iGBeqUypLGZAYRiU24EK3otrx89tgHNuuVw&#43;evRICLGzs3NwcPDnP//5&#43;PgYhdpnpnyfcGGthYcEVzhWeA/qAEYCKyVav4WVx1cyyoQ4OfnhL86arq0XL5529dI0tTddvcrOeLcQ5OvUggtkoUXPaNdRLillzVDAdVhbGYS5C1PWfQUOVCM8D5Mz3IZwIG3XdajPHWahvWYDUJW5v79/enqa5zmQ9sCyz1Qd0lvOtOlBZgck8FglgOjujfi3HDDwznTt0Q&#43;H1pw8&#43;YOj6JitjpnpdMvPqb9IpifGjWJNG542ES2VTM5wj5mXtRxNVlDO7Lo3DJZzmukwIfVqaSnDgAzYyBkMQwzqsYRcEI0U0nxS2eawxgrHBFV878DL7a01q1Pb1Zy4DXOGe6eIaWBFYARwdmYzQ0IG88samCwixnjDH8PMcH3w4py6ef6WD&#43;eYTPorxISHpVsJvGA6nQLMJuVzU7aAhFMXVwKqUTwp5HVI6U2pRv5tb4CHD91Zr/vxU/Z8OSlns62cqsObttHaRO9hX&#43;4ihUzhFxRTaq0Xy2Xzivr9cxN59ayuExEbUXRm5TklqhRw5qDINNxTumgSTi4P&#43;z6q&#43;ZJKsAVlyQ39kW&#43;X6DyyoQGIoqssR&#43;F8n27MptNJkRc&#43;qkI&#43;egPDcXJSSarPblG78FatltdvAO4msvg9qb3QfBLXU2G8MtY4UKSeTAUXfVoUe0qO3Lc3jddOQeuOM6aNbijdmgCVM8pJDeqN4y7LcxUmEvR9CpPdZNTlAtocERvYKB5VpTC4kgGcGOiZZAsKnIDDh1Juw5/Edt&#43;u8nNu5GOCVIMXHWoYhlSpKhlfZD8oKPvwclljm6Z5BwCPmyNiXGWcy8BMTcdcLKRed6SMBM7IFTyUw&#43;nXx992uXT&#43;S9LQF9TzonAduz6PIV3EBCMxGjwbVEoPMek2ft2NDHsUDxAiK7L5Xr5zT&#43;ala1fdyQtXnyrmUpwIS8kHesLQDTJeEXp33bVylg7VV3re2P0QUualnO7IvGTe2WbpmkoElsjTt48SW0enZLQrKcVqmCnNzlc7p3eucZjOuyKEkJOt2Rdf737983L7Tnt6ePyn3&#43;rDJxPh81whquVjRCwKAxgaSBgWA5c15BsV44reyIwuLYVUO/qpdXZxurAkqd947Rmtf5bt3Jt9&#43;U/T3c&#43;Z7VbPnzQvHkvT5BQJQOK76GsI4WzICFbHBC3U9kVUKW07fGae5agrwRJB1Ls&#43;etF71D0W5KrSbhwRk1lR7uztPvjR1u7d5cGkOfwbWx6Wyk0npVrzBXVdV61WuuvyPC/KEjGDWCJKNR1YdN112mhUuHHy6wW5TYNs6rqpG/7GqDtp/FxlxXzvsx9/u/fwa6&#43;b50r5&#43;lQ2J9MiyylDPdUnJycawpBd1xptgradqXDMyC2BZ/K8UCj75iJdEWdtRwcQQSq4GtEd4UpDHscDvDO2bbrVosmyulp0TR3s7nBwmJJIYZVUs8kshYApeBRzhlFdbp2TZEN6F328ne6MNvCi4AZLp6ApdmTc38zq91sgVVZOptOt7a4WXBWMGA7ODYCirDFMhIOf0cGPzhWyZqh8s/Q&#43;Ote01ki35mH6GTRvVFYJUgKds5xx8oB51SOBvcENCExzVb148lyIbLLVLk&#43;qg327PDHMruALIhaTXD3wBXnnmrrB4FBEMkxWTQABMe3Xn6vXgJF8Y8pG7ws6ffbYOavbennwtFstZdtwF/Sf5OQBIE2UBH09MIKR4Qj7CIYSjB6jpZCKksKFJDWJyqoY&#43;UG7rmM&#43;ps8mJM0rDXnNFdHWzYt9vTwWMnOms82Smc5zZgfJPEOFBywP/DGJ2o01U0PsnY3Kxo3sgDNd&#43;/LZwR/&#43;3/GT75w1evHSVi&#43;5DZwi6TpncBG9goB8b9jJQkje2/N&#43;IKiHp3vkxoAL0vVFbWnul5HJaywoKMBL266iG5n5TElguo5DP6RXJOSNIaJwyurGpybBkCJizjlt9Fno9eYo&#43;oLaVdBEiaN6ZwVjHoPpI6DQ4oaY7ixGV7yzOi3GUKUeenWGipOnL00xc3a&#43;zvm1d2LdEKPKQmbj0kmBVMuiKKAAwKJJ99emqAvtHVDIpFI5SbY4gcBAVez4Yw0KfZbLZeOamzX0oy/IGt/LFQStcgLdFFIkUy2daEMIHhHYjuJZjgzJPoBxhqKSLLWU1DVESEUuWtt1rs9UA/zca3MMLnZFxPAv0ollMNEUHG/QCuLx5xgoQ&#43;mINTYnkNGs77EEg1kRxAdCCavVqm3all9NYXg9bfIFERLqbD6fK6n6YMCZa1pr01CCdJbn08lEKmWorhHlNNCnu66DppflGUeMSURV0NqgelBJC9e6q6qV9y5oTQSDcRkQktf7gowxq6pqmwYpZqqPzCBjmx6KUArMs67trHOIAZgeKi7dWShCjFJi31kjJYSRIi5QuK9hEJnKEDwBbGNQ0mJpkCcVlFg5qU2KrDDbo&#43;j2JUlhYanqg3tS7cJZdH2kuXegXUYmX5gdTRwv2fEXQMTjHkB5iOGz3gYG0AuPUAdReifkoxtb5leTMaZaVZiCdRbOUSrggoBlJnDOhnOxqlecxUJ&#43;ThlowAsC/EpftBu97inPl7EIsGJ0ULQYZwC0QrD2qhsQzESucpEVXEpvrdONp2pDum72guhayuyA0bjuF0qPxZKgWO80cMKcT1MYqlXXviux8rludKchqASPxyix71THuz5mYM8iyXc9GjNU8s75IXqpeBkFb5wVwbMiv/N5sXs/K6a2qdqXT211orgTo6KqXh8d&#43;lUwIMB5pXRoXA5JmVLQCpIKmGjoJkMFS6aUZ3AD2gQzc709GHwN&#43;c8JjxKLjtrVC9Yo4QZc8gSMlNTL/Mr5GyCEIl/QZ//4f6bz3fb44OjRb/TB44n0ORWTWDL8GNX3QHMANgFJqRarLISYTCe90tkHLCn1gwC0G0mwbrA/U8zA9for4oJFWQpSUUwQkk1qd3CZKQ0J&#43;kk5mZSEPOa9J1maIxX1tWzw2jnCl394vT4gn2zvfnb/4fbu3dM8q54/ZouyVL4sch8BOlDGr42xyLyQUoYlWtUqywQVF06m0yyLZcq8d0OScRA0uSzLyklEQeaMQ99Anr73vm1abSImeBDXtEZvgJkSLJIiz6ezGfproEyGc6aqD6JbxbovyJq2bqtTqdRqcdo1dTjb1jJnkWieKecVFtebYEpZIMoZijt6H9RQ0TbOZo78nciJA&#43;fquo7Q6CiCxj2Ky7kBKlX0WHS6I7iwcCf4oIvZtWcYXSbkNZNSGMO8113bvSpE8Y5pLT29qarnT55JmU22msVx9WLfLo41syndE5oAO5NWnjOesuzBzSlkL1DdwKmwG4o5LGEpJWWCCBRHjKQf8AVSUyHr7OV11hF8FyiB/quqgi0GX/RN4bW/IW1IT68P/qqrYw5fUL1wXWOYH2L1DZfszC/EvDYaQIX9p/mN2cLAQxn2rTg/hrGycSVnUcoikD3mJigo5rqLlYcDjSXVro4GPNJw1kvkzo12kIv2Rs646I6ul7aJviAW2AhXeVZQ9Yt1DokCOOwR/kLJCF9HMTKo/MkA5oP84eiR7tVQrMvNxuuVUru7uw8ePNjZ2dFaHxwcvHjxom3bGNAOeplL0LLkfsh4MGL1OghtehGVVOKlyRMzxDJMp9D2dM309LgHPvmCSBfOi21qrqoyBZzSmP9M5i7mgHsdC76k8M7XJDZz0naAK4gcP3JIROO5aZrl4iaLnjnnZVl&#43;9dVX//Ef//HjH/&#43;4ruvf/va3v/71r4&#43;Pj/Miz1QQS7rTQNUwxigpt7a3pJRt0waOhBwnxhLsMSzKBDHUad21LRD4U4pUiryiNxJ6pVw&#43;CeH1eUGKempMZ7Ng2TpvnSNFrkBUiNNmcDhjA3fyEe3QWUqSLTnORR5jmfFkQUIwXq9uKBbWjzbLsr29vW&#43;&#43;&#43;ebbb79dLpeLxeLRo0fo6DqZTqji1yBFEnGIra2tsizBpaJdRkEOaKgKHrqYFci6TteEkFsUhSR7Aj6xwMqAaqPNgpoQXGy0Dun1ndti47TVyjPfNC2AexlrEdUj&#43;N4WOAoQyCjoCUJPRv8JhfciMJyxlvdYr/otiMHo66ZgNbwx0eYyWumMoqqEOYVCz840dQPLZgAvaoE6g/R6YQ1jMgEcoGjSeaekgqsVDI1Jxr1AIaLsg1c3kBmHpHg02UkpNDAOkyl/Tsb2EY&#43;UyY3cM9EPyCIYQp4va244XwiO7ufPn//ud79Dw4s//vGPL1&#43;&#43;XFZLWctqWeEgkznCUcq6Wq3gZ0Z&#43;JYCmEW2N&#43;X30K4LHZW2JEJJEJ5HkoIbURCOLyx&#43;sS2XGYaxJT0AJbvJGrKsuw3&#43;eez1wFA&#43;h5a674BtG23Xd06dP//u///u7776DED48PIRbOKkuqYdTBAjuNYU0koRnPIyeplTX5ONECvP6GFLx1mXG/HoWtL5Gb6Prwg3SMDaXoo8AynIRRt2m0zNEYLN9UT9K&#43;FP19jmg7P7h9KPkChsu&#43;pW1oCudxPe49BdfGsDVfPHFF7/61a8ePnzYNM3vf/97sKMsz6SQCV4z9bSZTCZZnntqEw4FTyoZdDbnJBUfKvKIoA4lI&#43;xyKJpigMhgqBAM0cDr2AHp1qQKiw&#43;Z0nFb/1HCC/r5z3/&#43;s5/9DMA&#43;P/zwA5Xn59AdY&#43;6U803TWOem0wlpQRa5EeWkLItSG&#43;1cxExFI4g28OAWeCsopg/Socf9QMDg9PR0dfUuAirpOQ3FvD6KDUAzwY1nDVwlKJ2TSdB&#43;qQ6gZzhCSpVC69ZZ17bg9dEz2puKObF&#43;NHjgjFv6HrKrteMip7K9cPz7anU0VoNjmLsr5gXh&#43;Kc&#43;/Te5VG&#43;HEqz/&#43;jxxGI&#43;Ojh49eoSk6CdPnkCFI9XeUIYowylu6roNeqptCe9ztVrBZ9U2bfREUQIU2lkg2hVxFNusbVrKEUIUOjyTALGvSmrYdujDP/6gV4kBNA94/Pixc&#43;43v/mN1vrFixfPnz8fakGpm&#43;xZV8sePw77B2hLnP30XUMZK&#43;oNfX8TasM1fUGvLWX6WAg3oKoqaOgwx0aeZ9636VlXo4euxiGNVuZVaAXXWMCPoIf55QlLgBDCKMD7qqV51U167Rfd0JD/XjbAn3cyf8hXeaRJ/z1sQBLL76gU8M1oiPFzbgM&#43;/KFfQPDAJM7zIZMfwIONm/p/vNuQfDvveyCvJyicyV5TqXFPatv3MdJHdG6geqU0cpXagKcc9Ft6q5S6QMCYV6lTZURs/HiO0kdKZ9CftNTxyPPzhDeHxQgbDY0RSNcYWP&#43;6tsnfN40WecxzEPLvW07ZlNqfmtoMBV2eRxcj3CkJAzh9R2qFN0pRufFQzMdL4&#43;RcKmcIhIgPUhmm0yngg5qmQY4m5PjW1tbdu3ellEDHhl&#43;wKIqUzYGcTtyPlLYFjw2amd/uwXgD0HT/wYMHhBjSOOeyLEtQI9gDay3c39PpdG9vDxn0KdOmLMskaqqqSvV7uBxw/J6cnBwcHCDp/v3N/YOgDSwoy7Lt7e2iKOq6puKq3HsPyKCEyXx8fJyyo6fTaZZl2AZgerg&#43;A6UoCmNMURTYg5yaG9Z1LYRYLpfvBg3jA6dxmWrqx5tKnMD9wT3A60XfvBh5SCkzAHnkiLZDpwLLklIC7ynLsmGd5fub9QdEG1ATT09P9/f3JZWZlUSJOyHfiFNOx8nJCd4/PT1NVZm6byuHbC3wq9lstrOzM5/P67p&#43;&#43;fLlguimeph/7LQBM265XKYklJSljAeSxglWjiWGyoQHEkuJ3SJN7My&#43;WCzm87kx5vj4GJh0V0qe&#43;Tum8Q0ACxr1&#43;13/taRZpiO/kVL&#43;TNM0EBvQrN5GJ4SPlDY1chtYXhvzxc9wB0hojJ5ff3iY2jVEQXpt8t7Fn7xxCz&#43;6Td3cURuoIpgfkjspYSZCnKCKPGIAE5uCHB5WW6Q8MtujqAxt44QEiwaMSSYPl4/A5IWSisV98qnBK&#43;BhooLbd5l9Gw1e3gFt6Kg9nU5nWzNaU&#43;YJ1KHrukxlQRr3/dvg0EjpStAvh5nrlDmjEOwGWlNq09xpHX6L8jg0VaFLISG006HGxqhMFUUpBhIICMpUWq073fV5CZwA&#43;UxVVQ31GnkPC3ld2sCCgjFVlFRHJ2HNCi6KspjNZpQM7HVYUyNEdFcAUbrrWucd9in20gjC2REQlUUbVs981&#43;mG0ueDhVEUXduqNqinebSf0TfLtxRMz/OsLCfUXFbwiEHJqUpQRKAzysoGq4J00e8VofEatEEI4yzjsltnW0LQ5LFGnLJTkTtPGGVUl2F8G/tho28MLZGMcCqUz0E1p7HjPNDdcd6To8IYHWEYBvBfnDHBhZXoT84IHSAsfipWiRtA9DaS3d8BjTcAbgagFKGmB1OVKxlTIfsC8KSegm8AwC8htSQZm4rHUSeNvNeYvE5FJoKLruvOlrJP8g6Xj0770HeY2s2O4u&#43;oNB5WGn0stMESDmyZdPz0Jl6su6lHv5teXxxUGD05bByy/swGJMa&#43;JnCUhpY25FLz/mBoQwjsHWvovO&#43;b&#43;3Gd3JuiC2KQmzrWvgX6NNc90TpybmAJTEQgeuYs8&#43;dQ3l7VKGi9SPpKyWifLI2xIrjM5GRLTedC5V63ZnXquxWjbuajrgDDOhkhzvJV4wOEGzqEph0KcHzbrUNiQy9JWUwn93609eVPi9m2qY6X&#43;9/r46fKG9G7DaDjJ7NTkzma51mRF2iRwwmcJoHNEJBnrORGkR60HcBCvEvorA&#43;TxtjRspzO7n15/59&#43;vnVnrzp85tqq6ZYTYQH9CxMXeF/GBKtntVoxxmazWVmWjhouomM7cHIZ3AkE7hFxXGljsAFVVZ360ws6DH0KNNqAcAkyancwmU6bRcFExoJS79DrCeU5wQQLO2E5Z1prxllRFFmeESoVi/0DuABgg6BqnrDirPf/9BavNjp25fgIDaibojFWhNNtfXJ4tP/n5cnx8uWL&#43;uRQryrGTNec4UIDuMOS47ptG4KEFoi/EyCNA/ByQZDL0PPRN1P2OSwQFW1vu76lBtsfBZ3fAOdMUy1/&#43;LNua5mXpq7a42euWmhvhj7OIW4sxCwikW5QrskZa5tW9HCpjPUtPYEB0qv/16sq&#43;Xui85YwA/pq3S2ORZa7rgn/WUNwCHGNziH&#43;9qwDrgVUSyWo01SXMnZLpK&#43;7zQ7aEA/Iimzn7vTzH&#43;WTLVufrp79xTAnGbWVp4U6a2DVEyAy4E&#43;mZlCxHRE4ft9N6ayLgBhcIN1jYn6ytK4FzWaff3Xvm/872/msfvn8wNnWdQUzmZJ0mBl54xF&#43;0brTQHObzqZlUaaaLIJGYnmWQ8aGv6XUBJ2Bvs&#43;E0&#43;7atl0ul594dH4dtE8Vk63tO5/N7tx1RotiKlQ423mmBB1n6vIUD3tUOhlH1hAKzHPA7HCe5XmWYQMyIYRWynlPULRA1LXo9JeQJ97bGrxXWteCdFudnB48a9tuefS8XZ50Tc2ZMSjflISSKCLgGLWQ0EGfaVpjDPqrAgyFslR0bDMp2ohZTnEV5zzgSLTR51DCPklab&#43;BQVc8eW2tVOdPVaXPwV7s81WQJM95rQX3YJNm6SOGKRQd9G3AoP6lhNuQBsSOBzqSXQe78u6e1eIDp9OKl915khesaXZ043XIXtaChLyhRBOHroRSHn7aOXpO8/5RUESG/0jufoKvuvBbEuFCZms6L3fuqmNpmyZ2xzghvATuPDtNSyCEeDLw94WjzM5t2venT8Iti&#43;jQh/CWY7wRv&#43;EntwRi6OGhB93/02U9/Mdm&#43;05wcHH0vO&#43;4KZqRE&#43;yamqBUOwradDiI0CWHGuelDaWjssJ5iBBsNchhppqhNQ&#43;IpMnY/KcV0A3RxOd&#43;9c//h9p27J3lePXviT5&#43;XwhTUu0AIHjaAYBKtNW0TloxxNt&#43;eF2VhTHgnJfmgKy9wdZyPeVzexf6fQX8NBoSalBNFChKW/hqtuD5q2gBdrNumWZ5yQdDFLbWx4oZ7x4VQUiKqztCq2BrCIKYc0JZ1dCPO&#43;g/3XAgH3EVBwtE9ue1agiB1Mdc6cC076pXzKdBm6OLnQqrJVrc8qV7sm&#43;WJdqYSPJm1Cf0tNcio65qLoAVZc7aICMv0KhMONee9MwMZqEKISlUJFux6naA&#43;atoAXdwc/FVXJ0IqZzpTL31XawqzgNabXgbZXfNhL&#43;3xl/QOuOFHJLVnVAT4qRllr4UuJp3kU1qRd0zn8ILYGnTxLb0lOoeWknzLHwik/t83jQAuz4H23VbKv23CWR&#43;mUJ6B9l2MGTf80SclJG&#43;cRqCDalgcOXouvV4PbF0P6euWQEOvl0otJxBmSR21ht21oP4DsGAdtnP44lWQqrf0KlIIKG5vbwOegKKGTFJpRmBV5NJBmmhehD9onJuui7UW4OgoxqtWFbXgub0KlyWFMG9ZlqiOR5sbSZ2Lg12qDVLY6rqWQmZ5XpYlylWEkI46GltjkSl0fHJijIGv/33P66MhlapitNFZnklqVuCcj01DhWDIc7DOGAvnWp7nUknq6c0jzDuBnaJ3wUeBf/weaWTwx5a/1CTPWWNRonXWXjAwdK6kmkwmCfHEOssMczyy&#43;9TZOc/z3d3d7e3tWxb0KoKYBKYDAH4UINy//PLLn/zkJzs7OxH4oXfXpF8bRbXY&#43;ZbdZ6laLuZRv9dpfrgExv7s2bPvv//&#43;2bNnbdsqpdTe3t4vf/nL//zP/3zw4EGWZWc&#43;tUEW2&#43;iDXsVkbpf&#43;YkIz69/97nfe&#43;9PT067rwg3Y3t7&#43;&#43;uuvf/GLX3z11Vcidg&#43;04Ok4zLIHtQQNYS5v6Urkva&#43;qynv/v//7vwX1F1UJcH82m00mE&#43;tc3TRt16IcMWhB3mVZpqRKzuc8y6bTKeqB3/eMPjIChwACGeIi50D7qNpWr1Z10zRd1zV13fVJhqoHHGOcT6fT&#43;59/DrvsVuG5Ko3AEdcq5QVHEnnXddVqBW7jrNM93CicGAQ2c8vub4DONgCCt8iL7e1tRe070NQ3IyOLaje4NXZV18BLpG4Ut3twNRqmP53ZAdYGgxaIMtTtUU4mpVJya2uG9s2cn3Vom82m6GZIqf3&#43;lgNdiTwlfzRNA0bivVeo1drf3//uu&#43;/QeGJorQ1hAkCppuWjwIr/0Aha0KNHjw4PDzvKo1XW2sPDw1//&#43;ter1Wp3d/dKyuUFJcEbgZY2PrahH&#43;L5D3/VV1wwnot/a30k74yXQnzu7&#43;//6U9/Wq1WzjleEO3s7Ozu7gJfctSyOf3m6EIMwQ&#43;HpnKqZk0Ac68qkhn1dRllM74KBTn9vY6yDOtkNJhRosZo/KnQ6p3tAYA7T05OkIimUtNv1mcMjhrZpAnHot8BZgoaKI9WFq7QjMBshi2PR0uTviJ9HVZhyNnw/DBVK8I5oXHxoGANXwrNODVOT2Vr5/BWzh8FwNi9s2QkfMuwF51CymDSL30qqTsbUEQnIRcRG2ZlDTGJz3BrKFaD&#43;Y/O7OgaDev6Ei8a7gr2L3lYz6HjDHq5pm1O0b60H6NdXEdFw8TRI&#43;y9KHWkhnpmPeusl0hjoyqufjRx4t4LL4UX3HJJIAQ&#43;lqOeT0NPNyNJ&#43;RGiZQoVDEst02OpZjihGKD8D7mOo1XDw8NjjpGg8jIB9KfGm4lbDmVAgiN/Xyq1Crwhy9XWbj7fk0XJ0cBsmMs26FhPuEvMdq2rTkSzyDKn&#43;qUZnfeNKZ44a6OijNHRG6L3DTdm&#43;GnD94eMPkFY48inh4em/qhe4UqtZ98GqbD&#43;s53tf/jZ/EffFvPPeOAn/AKkGu&#43;srk7qHx65wydTridFPmw&#43;s87ih6sG5FzswZXm/KoQ2wWhtytF5d7nBjAh1XQ&#43;e/CT3X/6t/Kz&#43;0JlSQj6tZF5z5wz3elhninHu23WzMo8laMO2fe6nmetraoKkOo320j7oyZq4qOybLqdb&#43;8W870sywolchlsX&#43;soM9THoLz1XltnjeHem9mOLae590WRo5foZDLJsizlTKQvSKUvQJa&#43;zf0aker5o6AWljJTaj5RO6VSglvvTRC2JGM9qzp70pjGMy4k/Sc4dQSXUk4mk729vel0ihwvrTUkJ1Z/sVigte/QC3hLoN4Zx6P6KTgrlNgu1TQTktxtHbXTdZ69XOnGuHaQvsUjwEqMKEyn01QRn&#43;B3UYcN//bt0q/T2B3tGdPWN9pJzjIpPPPahnvgaCfsOuP2kb/DkQdrayiBP8GaiytRvwE&#43;ojBr609bo63PJCCiWVh9F9avs741bn0lnXN1XR8dHS0Wi/RmMn1heY/UnturkEgNVJ7wt/W&#43;1q41LtZZ9widHuCoZ2UEro/XM3TxXSwWo2UdJpKu5yve7gFIJQOfM98jojJi&#43;69kGvzMxO1Fx6B1wyt/67w35nYDQP8/AAD//5g86tbEeqD&#43;AAAAAElFTkSuQmCC"
     data-sizes="auto"
     width="748" alt="Preference screen from the application with sections for picklist settings, index settings, other defaults, and theme."
     loading="lazy" />


</a>

  
  
</figure></p>
<h3 id="picklists">Picklists</h3>
<p>Salesforce Picklists are a bit of a special beast. The obvious choice is to make a picklist into a SQL Enum to support validation of data. But not all picklists are restricted in Salesforce and aren’t always required. By default the tool will use enum for restricted picklists, varchar for unrestricted picklists, and add blank values to all picklists (since it can’t easily determine if a given picklist is required or not across all page layouts).</p>
<p>If the picklist values in your org are pretty much set, the default settings make a lot of sense. If the picklist values in your org are likely to change you might want to make them all into regular varchar columns.</p>
<h3 id="auto-indexing">Auto Indexing</h3>
<p>The next important section contains the index settings. While it is <em>possible</em> to <a href="https://use-the-index-luke.com/sql/where-clause/functions/over-indexing">over-index a database</a> I think the three sets of default indexes are pretty good guesses: Id columns, external Ids, and picklists. The one you are most likely not to care about are the enums, and therefore the one you might consider disabling if you aren’t processing on those fields at all. Id columns are now case-sensitive even in MySQL by default as of <a href="https://github.com/acrosman/Salesforce2Sql/releases/tag/v0.7.0">version 0.7.0</a> since Salesforce Ids are case sensitive.</p>
<h3 id="additional-settings">Additional Settings</h3>
<p>The other defaults section let’s you pick a few other system behaviors. The most common to fuss with are first and last in the box.</p>
<p>By default it expects Lookup fields to be 18 character Salesforce Ids – cause that’s what they will be in Salesforce. But during a data migration some people like to put legacy Ids into these fields (I recommend a proper legacy Id field marked as an external Id) so I give the option to use 255 characters instead of 18.</p>
<p>Salesforce also has two categories of fields that are common to ignore in a migration and you may wish to keep out of your database just for ease of use: the audit fields (createdBy and the like) and read-only fields (like formulas). The final two checkboxes in that other defaults section lets you keep those fields out of your clone schema.</p>
<p>The middle two fields control the behavior of field defaults – generally I like these two settings as is in just about every use case, but you may feel differently.</p>
<p>Salesforce2Sql uses <a href="https://bootswatch.com/">Bootswatch</a> themes for design elements. The preference pane also lets you pick a different look-and-feel from their theme list.</p>
<h2 id="final-notes">Final Notes</h2>
<p>There are a couple other details worth knowing.</p>
<p>First, if the process runs into a problem where the SQL engine complains about row size limits Salesforce2Sql will automatically switch all varchar fields to TEXT fields in an attempt to reduce the row size. That will override all preference settings for these fields.</p>
<p>Second, <a href="https://knexjs.org">Knex.js</a> – which Salesforce2Sql uses to handle the actual SQL writing – adds indexes as a table alter even when they could be part of the create statement. This makes the process a bit slow and it means that if there are errors during the creation of indexes you may see some errors in the interface but leave you with a pretty-good schema clone.</p>
<p>Finally, yes there is lots of room for improvement. I work on this project when I can, or when I need a bug fixed for my own work. I am excited to get suggestions, ideas, feedback, documentation edits, and code submissions.</p>
]]></content:encoded> </item> <item>
      <title>Solve Interesting Problems</title>
      <link>https://spinningcode.org/2022/04/solve-interesting-problems/</link>
      <pubDate>
        Sat, 30 Apr 2022 00:19:01 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=1859</guid>  <description>A problem is not intrinsically interesting. We find problems interesting for our own reasons. That interest makes us intrinsically motivated to solve them.</description> <content:encoded><![CDATA[<p>During a recent department event my wife introduced me to the sister of one of her students. The event was an award ceremony for some of the history and political science majors – the student&rsquo;s sister was along to support her brother (and as a smart college student get a free meal outside the dinning hall).</p>
<p>As a CS major, this student is trying to understand her options for what kind of programming she might be interested in. As a good professor my wife introduced us so the CS major wouldn&rsquo;t have to pretend to be as excited about history as everyone else present. Listening to me talk about what I&rsquo;ve done in my work she commented that maybe she should be a web developer – my reply was that she should do the work with problems she finds interesting.</p>
<h2 id="dodge-the-gate-keepers">Dodge the Gate Keepers</h2>
<p>Like many people who are going through a CS education she has been surrounded by people who are confused about the difference between IT and CS. She talked about going to a conference and running into a bunch of guys who belittled her because she wasn&rsquo;t into computer hardware. Apparently one even criticized her for misstating the directionality of a Lightning adapter (I can&rsquo;t remember the last time I cared about <a href="https://www.psaudio.com/askpaulvideo/why-do-cables-have-direction/">cable directionality</a> in a digital connector). My suggestion that was old, familiar, and involved one finger. I also pointed out the guy was probably just wrong.</p>
<p>That kind of adolescent gate keeping out of other college students isn&rsquo;t surprising, but it is annoying. I work in a field that&rsquo;s short handed, and we need smart people interesting creating great systems. We were short handed before the whole <a href="https://www.washingtonpost.com/business/2021/12/29/job-market-2021/">U.S. economy started to run short on workers</a>.</p>
<p>From a short conversation I could tell she was smart, capable, and friendly – exactly the kind of person any employer will be lucky to have some day soon. But she also felt discouraged, as if she was weak in some important part of the field. Assembling her own PC hadn&rsquo;t been fun for her (I have no shame in admitting that I&rsquo;ve never built a PC from scratch); fussing with hardware just doesn&rsquo;t excite her like coding does right now.</p>
<p>I really love having a good IT team to support my work. And having great hardware at my disposal is critical to good work. But I have minimal interest in working on that part of the technology stack myself. Sure, I&rsquo;ve done my time installing RAM chips onto mother boards, and re-seating PCI cards, but I never really wanted to care about the details of those components.</p>
<p>I always wants to create tools that solved interested problems.</p>
<h2 id="what-problems-are-interesting">What Problems are Interesting</h2>
<p>We are all attracted to ideas and projects that sound exciting. This student became interested in the kind of work I do because I can talk about it with excitement and confidence. I enjoy the problems I get to solve on a day-to-day basis and that shows. I have no idea if she&rsquo;d enjoy them. Being a Salesforce or web developer might bore her to tears.</p>
<p>A problem is not intrinsically interesting. We find problems interesting for our own reasons. That interest makes us <a href="https://www.healthline.com/health/intrinsic-motivation">intrinsically motivated to solve them.</a></p>
<p>I like writing <a href="/2021/12/announcing-two-new-snowfakery-faker-providers/">middle-ware</a> and <a href="/2020/12/salesforce-electron-starter/">creating related tools</a>. Filling gaps left between other tools is interesting to me. I know people who love to create great UIs because it makes people love the product. Other friends love to work on security problems because it keeps systems secure (and gives them excuses to break into systems they should access). Some of my friends work on creating software to advance science. Still others love to create high performance solutions to handle big data problems. And others who help create games. I could go on, byt you get the picture.</p>
<p>My point is all the problems are interesting – to someone. None of the problems are interesting to all of us.</p>
<p>If you want to have or want a career creating software, look for jobs that solve problems you think are interesting. It doesn&rsquo;t matter if I think your work is exciting. If you are excited about it, I&rsquo;ll be excited to hear what you&rsquo;re doing.</p>
]]></content:encoded> </item> <item>
      <title>Salesforce Developer Podcast Episode 119</title>
      <link>https://spinningcode.org/2022/04/salesforce-developer-podcast-episode-119/</link>
      <pubDate>
        Sat, 16 Apr 2022 16:36:03 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=1855</guid>  <description>This week&amp;#39;s Salesforce Developer Podcast featured an interview recorded the end of last year. We talk about Snowfakery, PHP, Drupal, and more...</description> <content:encoded><![CDATA[<p><a href="https://developer.salesforce.com/podcast/2022/04/episode-119-open-source-and-data-generation-with-aaron-crosman">This week&rsquo;s Salesforce Developer Podcast</a> featured an interview I did with the host, <a href="https://twitter.com/joshbirk">Josh Birk</a>, the end of last year. As much as I still don&rsquo;t like the sound of my voice on recordings it was a fun interview and I am really excited to see it come out.</p>
<p>We talk about <a href="https://snowfakery.readthedocs.io/en/latest/">Snowfakery</a>, <a href="https://github.com/SFDO-Community-Sprints">Salesforce Open Source Commons</a>, the evolution of PHP, <a href="https://drupal.org">Drupal</a>, my career in general, and even a bit about <a href="/2016/09/my-grandmothers-hats/">spinning</a>. I&rsquo;d love to hear what you think.</p>
]]></content:encoded> </item> <item>
      <title>Disable a Salesforce Trigger in Production with VS Code</title>
      <link>https://spinningcode.org/2022/02/disable-a-salesforce-trigger-in-production-with-vs-code/</link>
      <pubDate>
        Sat, 26 Feb 2022 21:56:13 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=1828</guid>  <description>Disable a Salesforce Trigger in Production with VS Code (and a solution if there are failing tests to bypass).</description> <content:encoded><![CDATA[<p>I recently had to disable a Salesforce Trigger from a client&rsquo;s production environment. Having discovered the need last minute for a project, I needed to react quickly and make the change quickly. Since the <a href="https://help.salesforce.com/s/articleView?id=000327373&amp;type=1">official documentation</a> is a bit lacking I decided it was time for blog post of <a href="/2021/02/why-and-how-to-write-good-how-to-articles/">better directions</a>.</p>
<p>The Salesforce CLI directions in the article above make a few annoying assumptions:</p>
<ol>
<li>That you&rsquo;re happy to use MDAPI not SFDX.</li>
<li>That all your tests pass in production (which should be true, but let&rsquo;s be real it;s always).</li>
<li>You enjoy working out CLI commands in a rush.</li>
</ol>
<h2 id="what-you-need">What you need</h2>
<ul>
<li><a href="https://developer.salesforce.com/tools/sfdxcli">SFDX already setup</a></li>
<li><a href="https://code.visualstudio.com/">VS Code</a> with <a href="https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode-expanded">SFDX Extensions Pack</a></li>
<li><a href="https://trailhead.salesforce.com/content/learn/projects/quick-start-lightning-web-components/set-up-visual-studio-code">Basic knowledge for how to use them.</a></li>
</ul>
<h2 id="disabling-a-trigger-using-sfdx-in-vs-code">Disabling a Trigger Using SFDX in VS Code.</h2>
<p><strong>Connect VS Code to your target org.</strong> Easiest solution here is to just go to the command palate and authorize an org.</p>
<p><figure>
  <a href="/wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.12.48-PM-300x118.png" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    
    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.12.48-PM-300x118.png" alt="VS Code command pallet wit with SFDX commands shown." loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.12.48-PM-300x118.png 300w"
     data-src="/wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.12.48-PM-300x118.png"
     src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAAAyCAIAAAAbXkTiAAAMxklEQVR4nOxb7XLcSm4F0N0kR7bLW7tVm&#43;Q1Nu//Psn&#43;yrU0M2R/AKnGIXtGvs6mUmtfSZGgssricDhDfB4cgPFvf/t3IiIORMzM9CF/lJipmcbrehVJIYYQQle/22D/Z34is5mR2Ut/4f9XYkRq1GqLJZeYYkwhxhBDDwIRCUHcRF2IqLWmqh8m&#43;IlixpWoGEeoWILMU1rmmLox&#43;g8z10NyzqUU&#43;7DAzxMzVhNmjuRJRlhiSqfTsizzNE0pdQPkkre1/9RaP8rDzxVDnieK&#43;I8Rq1JtVqoa1drMI6DlorWaGhuJ0UcE/DQx4v7DHFk4iAiTqq5rLqWJOBxiNjXVnv6bdpj0EQI/UYRJhJDw46eH&#43;dPnZZpSEBK3jIeIkZBZMApG08BEhxwI6TDL7wqEAVEZXrTx&#43;20LQOKAij&#43;SfpuHWvjZ0Tt9mVnHNbrEaUpfv375y5//9GmOszThm5KMpFFoMnFIIcSBRwc6EpdxxfEZuHqPK&#43;k2bK3VWltrPYm9aRv01MAhdNA&#43;btyP726rLseJSCT9p2eRWs0s&#43;BtVtfqfRhZjjKfT8vXLpz&#43;f&#43;GtcE1c77NZIMi85fJH583x6CCFA/6qtlKKqKNf4KvhsMzvgU&#43;vxFaMZlZLP5/O6rjjhxdT3z0rXZwhhWZbT6ZRSGofJ7xpVs9YCRceYemZ319y27Xq9qto8TxJCLWXbtlorijCKAQWxSVpibT1BGRNVYmPTIJLi7ILL1VrXtUOjlNKyLG4Yg&#43;VhiZwzc0kpzfPMzKXEUkrO&#43;S1rn2ABEYkxdrDYtbGnWNy7u7bV2l0zxjhNk4hAXaq6bRtz9/eeS8xKKXDc2Frb8nY&#43;r0G5BO3V2MxDoEPVSrmGJ7m2y2VLU4KiW2s5F9UWY0QEIP8w76FQa2mtuRdExM35fL5cLqrtjduAQ5Bty&#43;u6egQgVVjrKKV7PbO4ejQECSHAQl3D27auGzOt6xaClFJL6e7YzVlK&#43;e23b9r0cZIlWuA9S5tboJFU&#43;o1D8oAS1z8Sifn7QR/x4R18lJf&#43;a7gMEZdSPOJQi0fBeIvGAFPwrAYcFZGP&#43;rdnpIE7QCV0f48wkjJTcok558dvj2W7lll4sSnsF&#43;3tgPHaZNVEYY5p4g5VDdcKQeDv&#43;AwYQyT4lxB8ZGsNNsD/Ub6YWVU9IRWc8Bblf2pLvRz8&#43;C33KIiZU297e98bPWVvYoUDfWI6iantdSUrm8VNycIUPaiG8ydHsIe/d/2aUQiSUsdLIlJK168Iq5qX34aSEEIoJaMk5JxH5XhXIiLTNCFKojkr2lRLpWsmVWraDSBsRTlXra1ZL&#43;8tMrWmBzFnsDbs4YVBjzLAOAGhyqyH1R3AxVDrDTW9TwPg9qG6iL&#43;r0mNmNYvSkw/6DDUq2rJl2mjdCtzZnd28CnXjuTkUXQVUPJJjCCGlZKbrugE4resaY8i5XK9XXAdJ87uIxsEffm&#43;cOV79rrt5K83e6EtvBtiTvrsju&#43;rNeigUpWrK1mw0b4fWoMGR36GFUgou3YMrRnCo6MKQdkYbAgshjFCrUZa9twsHtKDxRe9CikfY/V7d4/grt4QdeGY3gDA9JPvLiU4JL8P96Vz5XIOFlKZlvBfOHmN0jF9qLQ4443BPWAUgdVjLMSiNSu66DogqhwcRpTuE4N2DM4JmI1nBZvM8pxSJ&#43;jVLybWCuRJkOT/Yw&#43;v19xyORMpBR7sB5kBfZntIu/t3d9Z&#43;a4WkcpimqXdx3TcJQ4IjoU&#43;l5G6fZYENvPFbr9dVRJZldhvIwGGwGQJlmnrFbq2WUr2fYI8YOp1OU&#43;85aHhKa21d11LKssyn00NKwA65td7yHLa3WtvT0xOYj9dcXeCR27aVUuJxiHKjx43X2hOR9CLcU9ClUalaqHBv5EgkjJQiIrVKa6A10AcqHNznN2UoRYRRrr1CsJl61qLWgmNUPSCTuOJ69MzzFALM6ZyVR0CtZV3JE130r7HDXJ/fcWuKwRFy4wvr&#43;H&#43;TkT93AzSjS0E97BEgvEPaopqVlKh1tW4Ic8dNO9&#43;E/BBCuF6vXn4NlRmFwY/xIAXF88WIBnB5I72M5C5yRTG/K7ld3aqNWc7nM&#43;o8Kk3oskOvbiKX12&#43;AUYp3A7BnoRQoym1Y04yso8hgEsXR/fFOwc2LyOi27oo7Dd0db7HRPMPyCAWYc6gedQXVeDgICi&#43;mdq3JcZE2OnC3pcEAo5YADrwJM&#43;xfNwh9mexfP9OSzItiv7mi/FTlqU2aHqZpiSkyyyjfUI2nhS2EgM7CL2aoqyAnXLmIOPUi2bPzfcFwbrXnNO/UJiQiLxLsTNJeyVHtceY93h0WUm2ODmjb8rdv30Yr/srlBkPFCdHgmQc1wNwwYj33xxSnaQbxiRwyqAXnnkJy8wDVoBgc7s&#43;jBnh6yUjx87xgN6bWxtwPOrc9AYDiUgBXbip6nqMENB/1EBX/aPbKpDgHX&#43;wf9BOvR44aoPSU6e9nDjI64Z6CstqqhfIllxbjFT5&#43;nx8A8I9NFh7MKNDhwZLyyFHAJznnaVoHwsFBz&#43;YwcFfl4LxGxkesIPhcGLjWyzWhJURZ2rbt9bcCkAMFEW2Nv20U2I4MBD5OG1XqWOgWzuPGcLdwyZH3R&#43;s05nb3usD5l8tlmGpU9d83us&#43;mTs&#43;vc9/9fveue/bx9cutD1ii/WkhsKGeMKgqryqbRotzCHFMHoZfA8Mc3FwYRRWABL1YCGFk595du78PrPKLnPRN&#43;D7kKMJMnyf66yc7pRuhujV&#43;rPKok6WHaV7QhY3W9CjCXZveoCbw&#43;x4Wtq5rzvnuOAOAllLWdb1cLtu2vQnA/qvlloKaUmkszvswWlbt8L/7uBOgIezl9IDgt4TTWj1eoh9NKgRsgZl6/QxI7m8CpfxquS/C/B9ni8J6TOW1F2HdLJNQ3DLK7LHWSztt58QOENERATKGMNfrdQCS0Q20VjGN&#43;XD/ZzDU9n0tCvtEmPZ03/O3QqH39C8wzKgEg4PEkdHlws0H/rlvxz4M8KwR&#43;zzZv3ymh3SMbcnZoSLfatK4pGkBzrkfOtZaRcRJ/9seNVid0SihbpdSzuczxgBvq0j&#43;ahlrKRxDb4MfErdDOUG4UNgk1pCmKWELCNN5uPZBak4hyE6g&#43;sYLIqO3Vd4eYzHGdynymCi87G2/HvH2NXSPrcTfiq1KVXdqqBmvLVTlRlpKdb7FvEVizCBbq8gozsDsdDwAKO9riYZ2bExg3nPm&#43;c7tdjIuBJm6JIpyJVrbTsYxGjEWleBLiSCNaylycKJ7A1VrQwTgCJZkmAW2GPQ3ximD6H9v4uvO4tskYGsaXDFiQv9wmj/N8ilqlK5/qEiNs8pm0TgF5ykdzsiYEh6X5uNPdlyE3hjUv8H9/ePJx8gvq4eXEb99drZxGQwm1kMjBhpzil8X&#43;&#43;vJ5gCyn3xSL&#43;cWHnXReJrmUzxsMPauBs8zpgKgLUFtDmIZndfrHxP&#43;UgkhnE6nL1&#43;&#43;pJTWdWV&#43;RLF0FOTAh7FXRD31C1ngfYc9IHScmTxG50oUhgGwE4lNxTFvwXFkPeCil9bAaxC&#43;bU0f4rO91tbc/ou5VgrcURBWDtWoWMu0mVi4bvdP7o1WAHpGt4ATPAJ0EJnYxMJE9z1HAHYMzDSEWEq&#43;Xq97CsIolcm0SvbdUIgZKXFVrpbNcdKYDvrr&#43;yOtIuHgRPU5Wc2jMXbIVN/5c5bMdL3K09MZ6rpti2LZn60txKdIs9jxFCsXpdVCadFopoOJA9Nwz/NgJ1eVjjHkvoeCEflH03svY2g49OGriU1NbGL6OtlD9LUUfy0rPxZWkRbiNM9Y&#43;jwmJDYGIGPhdAzHXfsbdkkQaC94z69c4mD/i9K1UFPzuV6vwEXJd0N7&#43;1VDBfw/QOe&#43;LDWG7Clham9Hk1zBHX24/z&#43;WGxt6zvx36rBUDQ89gQ213GuAhVwOLkiGDY7FUDyRE2MMmL&#43;Dpbjvfn/I/4yZ7XejtHdlsGdD&#43;SiUDriICUEzY2&#43;wjkS/Q0wU23t&#43;FJtSoylD37Esy1D9dw&#43;w4VNwBFsqMCfW7t7402T/B3nGhv7bZ3vAbuixK/etyG81oRFDhgHZPBYUwTGICIZfA/jvi4&#43;&#43;pQN7gD3F6o4PZwxPVLWm8zz743xaa7tcLufz&#43;f10bbfFrMDd/VPoeMawnk4UG8cgzYmF5Kuc2ETDHAZN7xgL3z&#43;w58Gh41kBZCe3CsWYjiUGTMQqFtmPNRMe64XvwQa31cSnQv955nSldky7nA2lVavKmqvGrXcDdwtV42GN/sufQ1uPVvm2Jj6SzNhiG/N9VTzs1xuR/YGpGMec8k1s9fzzslMRKMK57g8H&#43;APG6Aa0WSFuLBvfyX21HGXguyb7u1fHsbHnM4w00K2vUOjoHl5OLX&#43;c/HcAAAD///zbzUyqGraRAAAAAElFTkSuQmCC"
     data-sizes="auto"
     width="300" alt="VS Code command pallet wit with SFDX commands shown."
     loading="lazy" />


</a>

  
  
</figure></p>
<p>P <strong>ull down the trigger from your org</strong>. I find it easiest to go to the metadata browser, find the trigger under Apex Triggers and click the download icon on the right.</p>
<p><figure>
  <a href="/wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.10.53-PM-300x273.png" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    
    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.10.53-PM-300x273.png" alt="Screenshot of VS Code org browser showing an Apex Trigger to download." loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.10.53-PM-300x273.png 300w"
     data-src="/wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.10.53-PM-300x273.png"
     src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAAB0CAIAAADCX62TAAAdFUlEQVR4nOxd2XIiydXOraoAARpp5sZzYYevHH4AP4Vf3uEXsKPH7fA42pLYas3lj6xPfKQKRNPdSA0T/5kehQS1npNnX9L89a9/DSGI0yAkcOIp/w8HgTg0VVWdjtAQgvfeOee9/38afDUAjUC7qev6iwjgnOu6zjn39s95xSCl5O/7uPU9OOciAfDH4AilFE/m&#43;fjdOWet/b4EkFJeMv9JKY0xWmugi&#43;sd3xKNzwTAF/waJ2dZBhp477uus9am5w9&#43;AcGUUiB7ih3cTPYw&#43;Aq/408ekF6ZD40n4RXSc3k6b5QuHbzhO5MKz1AUxXg89t63bYsl23UdFzqfKhJgcLIxJs/z0WiktcaL1XVdVVVKg/1bZlk2mUyMMVJKUB7oA6&#43;YHvBk&#43;ApopUbRPaQk8d43TdN1nVIqz3NclsjFudZa7z2Ih0sppYwx/Laqqrqu359ZtdbAIR4vhNB1HX/ysGclzL&#43;VUjgTL2ytBTHwO1bTwfsppUaj0Q8//DAej7Msy/NcCNG2rbW26WE8Ho9GI6VUlmX4KoSgtQairbUgYcqzzrn1er3ZbIwx8/k8yzJgFusIR5LMZFbQ2Jj4Utbax8fHh4cHKLl3wbxIuRmSg2gcCBKC4WlYa3meG2OstcAgqILleeSWQG5RFFmWjUYjLNiu60DnoigmkwlRo7V2zkFkSSlBA1CO6xqPDuaYTCbj8RhIB0Vx0zzPlVLAO77lKRCJo9EoyzIIgTdG&#43;xAgfLDkgb3XEPiCAFhKsDKhJcATR7APFFtr67rGddbrNdCKh8B6x7rGXSiasZbBYSQAJSZ/rtdrcAm4uGkaLPysB7kFSC08M4XY&#43;5vLlKt4WaAO6&#43;ngk&#43;xEEF8D50CSDjT4QcCrPj09YRmmRhioSJMANMABoBAlOPgMV6OfgZ9lWYJ1aD9Q8mCxUweAtNQu&#43;2L3HQBP2LYteB2yCOLk4PFm8DdVGcXFQUt2cMsjngGRnkJqt6Qf8pT0ppA5g2ump9C4So0iHvn&#43;BitMR2BysKTSw/CcQwLglbTWsESdc3VdHzGBACD727zO9QHZFMhMzWUckKqEIQEotihb6rp&#43;f0b&#43;DcCA&#43;aASoPOgHWGOGx4NeQ1VjCOgWnHo6QSgVrxYmg1E3PsATO2iKLTW0Afgkh0B6LbR34FBchz7&#43;/Id4gsq5KDgSx2uzz50enzqNqea9rUTKYKx1sj4MHPxIYNip6Hx6wG2cp7nWZZ1PeBhdiIIj5KK8s&#43;ulDQCwdfI83w2m8Eb2Ld/v4gAICc4kg9GXqaoPfi2&#43;8eQJPAQoSfbtj1FyZ0F&#43;FQ0/4Y64IvWAv0v&#43;Ld4mRBCnuc3NzdwyiaTycCNSKXTZ&#43;/1LRzAlcE1zrNgJmIZLhaL//3vf0f8/PPCvsAYKuEvAhjdsJfwPnxPrXVRFDc3N&#43;PxmDLtjHCKjnntGAbVy7Jsmua4n/9G8KoVdDpgWSFeppRivAgMDnmHkMZbEOAbwVq72WzW63VZlu8jf16DVwkwcIsOArVZKqbrun56ekIMtaqqz0YyDjLmG2GE6qpt29VqVZZlXddN01wWAVIT4rN2AmMAxJq1Fi&#43;22WyWyyV86UsDsCb08PdNcR/whBmKYGD9eDg6PTf1A6HrBvJn/20ZzEm/opHwFtgZJHy&#43;LxwggDEG/gL/BJMeDDak2S6mYvBuTO&#43;k&#43;IVvwdNJbMRPGE1jDBzkx8FpLvuN0fJ&#43;cIAAML0ZyAQSj1dC4KyiKKSUCEHHSxszm81ub2&#43;RAAD9oKKBZTAHUgje&#43;7IsYcjijkjswBXHLZxzOOa3FHcapiRpdzOEzfzGZ68FHxhYRh5mPp/f39/DHOq6DlwFhNJ4RWoFuG6aBn/meQ6HBZEoPENVVQ8PD4vF4kKkx1ngsBKmGwm8n8j1g5gwndjUEWWgG/ksRvogr3BHfMWLMCrO6P/boOL7wIFoqNaaOXSE7k4pBGJWgOn/ruuWy2Vd17ga/G&#43;kPIFNrXXdQ5qjxwPgmlQn9LSrqvotyZ9hRgwyBLzPnNQpVhCTjsSalLJpGmSVGQOAfAcB8CFEU1q6sp9RIQv&#43;JovyhgQA9qkA/BY&#43;&#43;840k4gyKN6DwbjBiYPfXztgUFM0eIBTPMcLhF1SHr8A&#43;7QIT3&#43;fNDebYoryhFfjAUw&#43;70fW0lR7ShheMF0WVFoMsl&#43;RqbrLB/DpT1zyKbCqBaIfUgWFIePxmCl4GEiUOcA&#43;4qms46B6gOaA0ZnW/IxGIySKqWyklKxEq6oKq4cR/wuHnQhKXa2vWD5AJbAG7smy7Pb29v7&#43;Hjkg6IOu61ApxRgk8kTAHfLveZ4jmk2EklHgIqBeD/INWJ5MJrPZzFq7Wq1QO7TZbFCWclZ0nR&#43;G&#43;YBvuRaLi4BZJAZmsxn8uLZtWbNGMxTcwMUOPwDYh/uGbAkM0LRujnVgYCmEvp1zRVEg0snakAuHb8oHDCCt5KXlA8MRQQXvfdED2AVSO3W1QAmsa2ZRmMhm5Q8lEngLuGY9R57n3nvUbJ3x7d4IzkYA5xxDRkBQ27ZPT0/r9RqFWZBvo9EIEQugG0FTRibSXF2q0mmPIcIBYq9WK/BQ27bQGQiHjMfjd8syfjuchwApgmiBwA9IM4hAH8IV&#43;BDoG/gBgNTWTI0CWkFpxpEGEjis6zp0/pzl7d4UDhdmfZ0&#43;SM3W1xK2KO5MTXvqyYMSIzVA8fu&#43;ZE&#43;PgZKHMDziK&#43;yf/r1gGIxjnf7BzpkjsF8GgtWKCA&#43;rOaGiU4c27b/Y/wWH0X9mc05K7LRvAJYY2YKPRy5Js/xpfQYD5u9sOL3whGHkQV5zoZ3i1LBCIs3OG2Nubm6m0yliqyk96Ogx1sRLscwC2EHBc1EUMP9p&#43;6fKJnXBxuPxzc0Nko5p0QrIP2izYayQiQpEZN&#43;TBkMCoDeGpVuscD7lmZh&#43;wfHwA3766Sf0CqDkC1Y8Y/pa67ZtUYAOekyn05ubG6bDVqtVXddw6BAmYYiQ3QAI3NZ1vVqtUJWEpUDTC2fBsYBJRkePrk/btmVZokTlPUsxD0dD4UbBXEF56Il8QGDLRr6FqqpAJAiitEejaRqIETrPlBiokGSKBusAlOCiAWcIIcqypA&#43;IpB6cshACunTgNMALMcYw6YRnEELAsnpLhA9h6AnD6wEuQABg6pQgMAueWPWHFAqblsAWEHGUJKhNA23gN7D5Sym12WyqqqJdS&#43;HGdCbkVdM0dKQXi0XbtnD0mqaBi4BrQkVzHeBDapeqqlgz&#43;27wggCsb0iTASeGQhHMoSwGUh4fH5fLJW18CmLyE90rinLel2lIlFms12t215B1WEYPLxqcCrcgVQxKqfV6PRqNaIPRXqCuxvqDynlPu2jYIcOEOFK7eOJTnik1fnAwvOJU76WWyWej0IPDBhXXqSLlQmFXzH5XbFVVEFyvvUtqC30hDr8JXugA&#43;pOQlZC/Xx1WTN8kvQKJMfgzNef3cfGaUX&#43;wmnj/gdkxemne2QsOYJEhsP9FTW7sPmAPOEPNMEPT2D3XLOQ4bUq07UH30FRNO8v4MBRrVMuszjuYNbtA1ANecAC0KIcRnI595gNgcYJyxpjpdDqfz9lASiZjwhINzew/bds2y7L5fA4Dhs/AxZH6dDArU6sGNS8oibyWrp4XShiWAJbSa119RwCRSBqFeZ7f3t7&#43;&#43;OOPxhh4Z1prNHMjVtN1XZ7nTKSse1BKobqdTW4wewY9lHDZaD6ORiNjDAyqp6cnrKHrIwAsmdPr9wdAV55lJjBR0hosTDQAKkEtiq&#43;0cBxWPIQVhBLMdlZzYn3Qs8PB7PT/LhXnXwcHEjJfvXBoa0PjIT&#43;F&#43;nUsydFohGpRRECZkMG5KIILISCdAnKmPfgwMdlKTxahXgH5N5vNtSz/c4ajD5alPD4&#43;pp0qxpiHhwdmTuBbpbEdrGs4g&#43;QkqA26SyzXGFhNtJ1Y/XiWV3trOFtCZr8sZX&#43;sUIqs/dBp6kDsnzXIlB3xHgaF1hcOZyPAwRlRgxE1XKRp011a0jKw4mnakrqpH/e9XKfzwmECDHylzwKWZxqyZ1kKKp8RpaDxnhr4NExpxXMJQ2nTaoKXwCtQG191rdzhBo1Bf&#43;EpF4KtgvgXRDDC0Xd3d7AyETqm2wVxD0spHTbD6BB8gru7u8lkgpB113WcR4Q4Bz6/6oLRww0asO3wkl/kDGdZRmMxz/PpdDqbzZRSk8mk6zq0fsAKQpUKovwMwbMyHv4ULjLaAkLHsFBxynq9hml0vUzwaocMJQZFyvE3pGRnqguWKKZeYUUzK8kofzrbiEKMEgYoRhUQhQ&#43;oyxjqfjb/uuDVBg0gCwY4EHSczYlHHAkT8/HxESkOiB2IIEaJ4TSB1WDUs5MdzOecA/1Yc5eOGAKvwGl4e0S9FQyDcQyosX4NHv/xxADQAU3LwxDtGcSi00gnMU6FTMymhVlUS7SUUpOJPPeOSDsnDGfGIahyJG7&#43;GgyMQlb7Hg8CE7Op/X7w4COG2TVin8&#43;84wBjDMbjMfGExUWpcuQ9mZ9Kp3ViQAtilnBf0/QT40UoA2Akaj&#43;KmaL&#43;lBFqlwz7K&#43;wFBzCGRRV6ysQawH6XpNYa4WgOwmENDyPeaOTjSDhUhTAQm3bX4BmQd7yiUE8KaayFC/pAUp5ltqy0Pd0VYPoFOnY&#43;n//444&#43;wGlGeztGhVVWVZQlnDfw3Ho/xFU1SZuhoEy&#43;Xy/ccbnJGgBio6xoChqULLwY2MQiTtk1/3atCvMB0QXwY&#43;WE4xqhDoefFlCHsIhisLDSiFYtUzxWFmlNg0j&#43;dsfFiaB/ow2mrX&#43;HiA6EMR2P6rXNu0gO&#43;LcuSpSibzYaVh1jg8HIpYfQWWEx3fIjyhQNNuzTeteMAsnn6yelXp6tFvkFicrVaoSgqreKndkEhEFCc9n&#43;lZmtaQsJJsG&#43;An/eA/QDi10/M2j8xbagjlqGW1&#43;t1GgFNb5Tm4A4WTKRwXQ14x2GohM8F&#43;xlN6vbXSksOmv/7VUCDGqFBc&#43;f&#43;ZQ/e8dKIdzYCHC9LGRSYEN1pdDPV&#43;eksa6bP0kwke/lZRzOo6Rs02PA5WcJ1rhf/RjgPAehIozSBZSmzHlJxNNgXoiiK29tbdIrR5GVcCPYrSmvhn8NLQJaY5aEwajmqnLGT1HFLS1E3m83lKJJjI8sGSa5TfDGsd5alzOfzn376ieOAEGfFAVVVrVYrrfV8PkdnJKtu6a9hWopzbj6fTyYTKSXsNPSxgmAwUpGEkFKOx2MM64dqAaOQ/Kh3Z2n7&#43;dD49XAgGorf020DUrv1yLXSOFpalgIhg9WKKiA4I8zDsHqZ0Ys0gs3AFPM5LLwFHskuWmvsGcByOe7FwgHtKMu4HE9iF4rgrIjnqd69E4RvsRL3p5gPYOAHoCzFWstiLKTJuA0AfIJ0sgcLe0gAcEDTNKvVih0WbL4A8fjMyDTgamydRJUjsmla60srmttxAOuf&#43;DIQHfiKJccH4UhZynK5BE45NIspF/xZliVVN0NSrPtkfXm6hwxvmk4i4uwD5hsGtRfU2BfVQb/jAKwXPDF33eCYmVNaBA6WpYASg6B0au0gcpd&#43;&#43;9q0lEGF&#43;nGPYb8U/ojJ&#43;x1h2B&#43;QdhPiQ05SP/7QR8pSjowopJ7cz0Bweh9WNBM4g6qs41mEy4dhRowFJrTeYFYeJ0BalkK3Syk17iEtT083leAePRwmkbrKqGmE8YNKaTgNaQ/wkSzCtcBhMzSdPnlkA5oU6AegJgXh6B9&#43;&#43;OH&#43;/p69dmn5NINxmKw48MWgdZVS9/f3RVEgBocxB9Dz7DfG9jWr1epKmWBYHc3aEBY3nB4jgt7mvNaiKFCWgloVNM6BIdATikJamEboEgA451arFQrlx&#43;PxbDaD8YoaFjAKevCQlIcj9hX19JcAQwLsK8DTDQamdEgt1JXAj&#43;XQUG5UxQY8WKtpGwy&#43;hesL6xN2J8cNsaaawueS9&#43;w4Ai&#43;2MOFkHk6FOX16FncNo/FT1/XDw8NqtaLo4HZg8OzQWIqYBOIH7F9E6lEI8enTp&#43;VymY5TYdM92eWqkwQ7DoA8HRSAnFgeAVzAcSWke/FBq5OW9JnZADyw8Qdf7Wfz04OvujLlRUIGC&#43;q1/byOw76wSgdfkjaDs9Ki/tRL4AEnRmyuFPtn7pDZn06Sbqt78ADENdEqk3ZeHHmGq7b69&#43;EM4ej9Ak02nE4mk&#43;l0mm7CjSMpNFCWUhQFRuimwfqB45ruvXDV1bgDOE8&#43;AAYoEzKILrBLkn4AljzSkNhiI4SQZ9l0Oh0VRd3Xp4CSchv8Cd67qIcssA0LdbFYfDYyeC3wjQR4oS2YtwIeYd1jhhhMUsT7RO9nVf1smHKzcV0rnNNS5L3rMBoVkZZKm8xoY7xzTT8zIVqlITjvvHPlZtO17fWzgBRiby/JdAzDKy6YxD8cJfr1GkJfS9L/7Zz1PkgZD&#43;qaZrV4CjfT8XisQnBt24UgezkiuzaPFpbVdSXXWoaQOTeSYVZkhRRaS6OklqJ2NrSNbxpvrQhCBKGcM0IYKZ1U8e8ewvY3Puvl0ib0uOs5PYTXtzDh/iUvLTwpldZGSoVXRshUglDegRoq63GnrbP9uCXTtGpy09tCnZJCBhG887YzTXMThOmsWG9kEFoE4YPzweZ50Cpo0/ZDNuq6bjrbeeeF9EKotruROs8Ln1hNPngXghXCC&#43;XjHeJriktJuryAEEQUq6GNLyTk4QYN5JUwN/XFSGelMpOPdKGitBEU2fGqwcsQlAiZ9yZ4I0OmgjFK6yyT2tigvFRCBx&#43;wCILWelyEUbx0JFzPPkFr67Rqg5JBChtEsFY4b/pThRJCC2FGxU0&#43;SWy1IILz3noXedAFZYWySlupgpTxRvHnBUHwoe26zXrl/TKE5oAISrdweZm9k0qZYjSdze/H42JLgqCCV8FrH3&#43;aEDIRchGyyALSKmmFETpXJutVqPfBQ6gBNT5s/37mPqmV7llK&#43;J6ipv8nQpCUfc//iP8gg1O&#43;i/&#43;cF144obpIAO2k8lI6pVzPsOKtOYKXf36d5/&#43;edWR4/sZ7v97UQei2bZztXlXCqS24u4WUWZ5Pp5P5bGJMXJLKu8zZzDsVmJzSJo/mfdCqdq5xQWfFuN9Tvuu6tuucdSDmc79jNHN2pbjPI7W879rWeb&#43;1Q/so4fNb4mVCJGb834kQVHAmksGr0AsggYMjmZ1UrdKd0v6N8sAw25LmIqBu12MrhE98deuCUma5XCulhdxLyqdjG1h4k0iheDetZWZkZoQOIRd&#43;5K1SvpPaKuWUDibTk7Ga3ER90dSms5Obm/v7HzHNZLfVven3KnCeiXVkoTnTDGE7RtlSVw4Bkq5r&#43;2hSG4IXIbKaFCEKHRF0JImPj&#43;edDtZKX2oZaXBeJuhXeMSS7v9LpgkKKTKTadOnUYNIeyykFEZLRHyGZihKqVDMnJbHpnq4pzbuLbTwubdZcJ3SrTKtUiKq6PifzLLeDNJC&#43;S1mTZ5nNzcToJtbdWwH6Umtd8PKjNFFkUcjwWhGnjnfDTFRzFrsX0wEaKIt07vILjoqHCkm1hXeOq&#43;cUuHcTCClUEpmvQ&#43;kVBTKPa5Q3mESAW56Jo4refAEwx000JXHenGUmG9LpsSzfNuKXxnfs29Fikah9LCugnCodO&#43;fxselauu6ahqJ0L&#43;UKsueJ5sw587KFw7oAu0j2Yoiz7K263zfpkov&#43;rWJRohNCxFcL3&#43;8kLpXJ9Dz54Xd3eWzcZduerPNmB7bNG5IABigqQLY1eNjkUX1GCJiheiCiAaKDypYrYRTJuhoEDV1Y61LCs2T6SeRQ6IROZ6M8zy3XVf3EemAwF20ZaPDFVWrVCYzfSTDZ/FICwUOF7quqjJaqPFGKXfST4nWgXfa2eBcK0QbZH/&#43;2YshZLScfbS5e6Q/v4XsLY6IuujMh&#43;0cr37deOa094pzB1MchgOMA8KWXVnVqtcESoSNsyPXZd55KZw2wWQiqjvlepvdY9nJUirdnw01IzVH9EYZYntqgrgBBkOIWjTK1n4S7tPzoFCMlKrrrm17xfH8SsC4EpCKQsugomlkg7Pe&#43;SqIVplad1a58BaGkNwWtPH58XEyRAemHjDgnN&#43;U8RX6N9qbmFWWJeuc0uqS/k/pvaubyj88rFcZfN1o&#43;AefRU1gjRJGZ1IZ0Zt9IIAV0opo0vvEX&#43;1toIjh7WrYObS7H/2LGf3cZgNL1CMu1BMDMlD1hkTW/1TbtR/v7DrrXBdkJ00rdVQAb2eGDgzQ3YfJF9vX6pm4Lculj5wZhj1i&#43;wnIJBoRD&#43;nqTVOVvJHqHWHZO1&#43;5ElpKI1UhRC6jUSJhG0TT0PMJXHSXooAOSvYsEnnlZYiZ8lru5EkQSgoVopCLHtkz&#43;UWvgWCcRuhEaIJoQ&#43;i8sz50QkENXI5jHJFoXdvWcXmEYFIj5/Nx9ijCrI1ry/dSAks5souWsjVGKxlco53LRBhpPZ1MZkU2jgoxaqLefZKt901nvVQ6z6ObGt0x0bPCC6HXB0yi32jb1lkrgtfPEiYudr3FZ&#43;jZq&#43;5/Qi21QbT9DQM89AvzhOFj9m/kIgfc3t5&#43;2X43zyLNQaL3DmuvnZVWffyya2Vpo3PU5mY8nWX397mSvms90pNKmaaRVWm0QcHENqrXZ5W7&#43;J&#43;LdhG6jkXbtsvlYr3urO1rZISwIqJ7&#43;y4R6TaIbivlPIIt22/FRYblYG3gd/OHP/zhl19&#43;Ydfkl13oZXqWZSk&#43;Ljols1zfTOXNVOUZWshkHxvy63UX5Y&#43;Ws3net6aqviEyatXNuqvrXD1XqUZG22xs3ZSyaoOLizrRJbsI6PbDi8T2q/DcovT73//&#43;6elpsVh8e157UMUVhGjadtE36WVZZrdByiaITTQJbdhUYxe8d71nYHpsl335UDExuZG&#43;bW3Z2ZULGy/aXu9eTcz5ZHghB74FUMOTdkOgLGW5XHJuFjw7tGY459ZliWoJuCB9zWEbrX4TnS8k17quK8sSNYu/AXTvgxl0K6SjM/DJKWwB7Y0gz6Ashe40a0NZTYXCdN6XJw6mqPz2NvBMwaTYZziMb376rIj9igoWOrLXJUX0a9dJhwL9xvpSD8KLaSmz2ex3v/vd3d0d1mlVVcvlcrVabTYbdKq8dhU22KTbaXLtD8rrDhayD/osuDk3K&#43;MHRx5nzSsqXTFEX57nP//881/&#43;8pc//vGP2IR8vV7/97///fe///3hw4ePHz8i&#43;vjahQ7uKY9NfDh5Iu34EC/bxpkKhRbBNohim5JMEbovJFPAYShCvYp6xV1X4mQy&#43;fnnn//85z//6U9/Qq1yXdeLxeLjx49/&#43;9vfMJL8CAG4nwVjcHme393d3d/fo3ULNeVkiIFY4w5UaKs3xmCGOuYZDzqNsFXQ/k63HEy02WweHx&#43;vol5xR4DRaPRDD7PZDATAjIcQwr/&#43;9S8Mcjp&#43;rXRhgqVg/6CrAmMSsf0md65lzgeD1bXW2A41lf4crkgCoGuDIpF9OFDvUCHr9fpyWiGPwItoKMQOOmkxMG&#43;xWPzyyy//&#43;c9/0Exx5EJ0AlC2hvWIPsjJZILqaFAardKYnAPrCEVEaJhZr9fYDAm7LqHCDu0xtKOo2wdGFJtz0mabC4dnAqBX4sOHD3//&#43;983m83t7W1d158&#43;ffr1118/fvz44cOHh4eH4x0QKKFgPxfGoHBHDHASVjq6tCFYuMckRBBUCEoxeGWlFFq6qSoGrIbDWHHNRoTLaYU8AjsCrNfrf/zjH5vN5p///Od0Oq2q6vHx8enpablcogvlyPukL592Z2CRciANrUyGXQ8OVNyfvFHX9SnyJPVdrsV1MKnlsFgsyrL89ddfIakxF&#43;B0P2h/RgllRbqHDL86/ZpMUA/CpfsXuQqkpzBMyHCs0hctInbZc7tHoB5KmLvKDCotBtte7RuXUBIwnLIsw1C5sizBEOjk&#43;YJY&#43;kXCsC4o3Vn&#43;dIDPhQY8NBiBJNPp9O7urizLxWKRjuJL9ydPHbS0&#43;R1HTiYTbEE4Go3QcPnp06fHx0fobZaqn97Mc2nwfwEAAP//jFrk&#43;looo2EAAAAASUVORK5CYII="
     data-sizes="auto"
     width="300" alt="Screenshot of VS Code org browser showing an Apex Trigger to download."
     loading="lazy" />


</a>

  
  
</figure></p>
<p><strong>Update the trigger&rsquo;s XML file to change the status</strong>. All project code files in SFDX are accompanied by an XML file of class metadata. Open the file and change the status to &ldquo;Inactive&rdquo;.</p>
<p><figure>
  <a href="/wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.17.55-PM-300x161.png" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    
    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.17.55-PM-300x161.png" alt="Screenshot of the VS Code file browser with the trigger&amp;rsquo;s metadata file highlighted." loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.17.55-PM-300x161.png 300w"
     data-src="/wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.17.55-PM-300x161.png"
     src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAABFCAIAAAANeXmbAAAQd0lEQVR4nOx8i3LcNq8wAZLS7vqW/u3f9&#43;j7P9CZOZ2xY&#43;9NIgngDAGJUdZ2vE6axk2Mfl&#43;7liiKAkBcCYS//vor51xKERH3Dv86hPOHIgDoD3FOvplcMP&#43;Qx9f1RfYG&#43;Xywg/qPuPqPA4c6lOWz9YCOcf/EIr8doP1HTr/U4GkCgEL7U0TAuQ5xHbxzbiQuzOwEFpiR&#43;S2GDnt&#43;ngPsluJuwizqiCWGDKkIzgOgA3JCLKwjptmc8wgegERIxAOsvPcII/FIxIpvABcQO0RxLhNnZvpxVLAFB0AAV7iumR8t5gkCAAAihhAQ0ZBVsc10FeP/X/ceYJ/LkeoXNxrZl4NzJDIUyiweK3YCAosgGD86VG5NXOmHAAHq0k5wWq8A6INuIBoKFZ0tAESPm&#43;A7RJ1BOo9Xsa5ym/IuF7sIzl3EcN1FEXef0t2YRuLHn/0vQMU&#43;wNr7yy56gEMpu1zyI3Z4egcgYt/3XdcBABGN4yjZrYP/re/WwY9EieoOqHwqUrjO2XnsPWbmuyHvS4kIv/XdKni7qzugEiCz7HPZpsziIsI6hIvobVhm7itDV2YJWGm2y&#43;V&#43;zMdCCLAOeN3FqxjXwYtzLHVMh8jOXXcx6SY4FBKRm777re9Y5H/2cCx1qf8Oxh&#43;DR7iI4Y9VHxDuRkhVcpzKxacJICLMjIje&#43;8rrlYf0/5Wd3WUMEqeRiXgg9vViRU1W1u4Sdh7/XK8uY0jMVTq4aR8MhTrdWEciD3XYKvirGE1CXoTgwB0yOd1MlSphQt86hOuuu4j&#43;Mobee7a7zIn5MobQA7Hs63apf25CGIkCLuXoj4EqTqDKW3RPL&#43;UJAoiIcb1thawAzEOhh5Sdc6vgEaAoWYqKaUBMRCQ8FL4f86HQWryJGtUHpiedsnVlXnYqEx0dZxShqxImc90vY51KRuJdrsaZESNzFeiJ4AhVxJX6mwcduQ5&#43;5eu2QN31meUh5Sq&#43;SKf7cUAih1xuVcbuc9GvO0MHGA1KqRgGADYkOnco5e/juMtlFTw41/RbAPSz5TESPaQyEq2DJ66oMfFddPdExJF4m/NOx9QNUbEM96lKnoCoeJShsLJ/5W4jWGEZiDLz2nsPVZOzm3aAc673PqKpd2fmADMXkWPVRj&#43;MBGIEUI2ospczP2GWPWuG2j5YXqnGj6RdBq/7ySQSuKpFYbaCSCSp0kt1x3DAqlQDVlUh4kzZjkRmEqhuIN2kGdQu8rof1Fowg6rOD&#43;Bs8LGQX8gUXUD94XWPN4PVNIT9O/NTH/1vgYgrMrGpuKcXcq4fYPRkkqyW93xRLVE6eat&#43;PInZJNAsdzfhx5D72V6cLXdYuAXN2G&#43;Gf3k9N/9wV6CZ3c/BWQRouqzO9fl8z7gXixeL&#43;wyrz4x&#43;bp7lrR&#43;NzO8CLxPA3AJEZIXJyVp4au1K&#43;7PBd178zwBnESCE0HUdM4/jyMzee/MSqrxWI3XptYnIqHCiQt7hSThLBJlfZshNKfV9//vvv9/c3CDi8XjMOfd9j4illBijiNzd3d3e3vIPVYD/FThXByBik0Vd111dXf3xxx8xxv1&#43;P45j13XmOmw2G3MdttttSumdAC/CWQQwt0BEcs4m3Kf4hIKFK4ZhSCmZLFL36B31Z8FZBDD8EpGRYRzH29vbYRi89yZnTDSVUna7HQDsdjsj1fdf/38eXiaAsb8xteHUFOx2u11aPjZAHVUoCu8EOAfOIoDJmYZQs3xOAl12N&#43;e8/PMdXoRXOGJLGjSqtD&#43;/5yJ/ZjjLD/DemyNmcqY5YksH7cV53r2zJ&#43;HVjhgRmSUaYwwhLBIG04YQEXPK7MeUUHOulDKO47tuOIFzHTHzew3Rfd9fXV2ZMxxCMISa&#43;rUBdtF8ZjNSiWi/39/d3b1bqCdwbjTUHDETO13XrdfrTmG9XlviLIRg9o&#43;IxBhtE9iesGMvIYTj8TgMwzny6teBcwlg&#43;RnDb4v5NDljvG/QdLVdLKXknJsi&#43;fFJwjcGZxGglGKOmFmZKaXD4dB13TiOx&#43;MxxmhIb6ZRU9pms5ZSLD5hsbzv/1H/JfgaRyyl9PDwEML0bOPrJtzbn40w7XTFOwFO4FxHbHnFzJ4WaztTqryboU/CuTpg6YW9Y/MfhLP8ADN&#43;zLI0i9PCcCfy5J0qXwHnOmIxRma2GGfXdZvNxqLTS/lTSrGY6DsNzoezRJD3frVaOecOh0Mppe/7m5sbS3418z/nfDgcHh4e3l2tV8G5OsAsSws8mC92fX29Wq36vmfm4/G43W6JyFzf77zmnwrwzHFElFIy7raoTkrJghMW/X/PAH8dvCIj1kzPcRw/fvw4juN2u7VcvBmm77G2r4BzHTFjcDN7cs673e5wOLQAXAs8vGciXwvnOmJL&#43;9L4/UkX7N0MfS2cfTb0BK1zPO6zA3H//PJ&#43;fjjLDzi5glr7MT0P6BHKVIUxn6d1y/K6Tz9E3K&#43;mqa0UDtxpJWGDFwhgpmeLQ9jh3B7hIgREQK1MiohJy&#43;HsvHh731w1Np17Fq25OGoRyy9CAwToPa607mq0cpJH5WpfIoBFIGKMVixmOpZz3gT/&#43;7rTGjwM&#43;g4WR1rEYQUtVgcQdZcMxFp9VynxcUh/H4f9r6EnwLmAcBnD/9Masfsx3w5pkFMv9UsEaJFkywBXW4iIwSG4iLgJXmvq4CIGLQuViGhlMxGRteRRnHtIeShkIouY75M/lF/j0K6WMXceL6K30qCKhEef/oIIMq63U4illFxNfs4IQyHFsjN&#43;7zrUOiE0kR8Q97loJQzvcjECeAAbD/BsncBPBarwRuJ9pgA8VMw9kQt5gQCG98PhYLmUUooTGYr7mHJiRgfs5CHl31bdVQwIkIiDlmvdDslKtAYtSLLS37mi&#43;rt981sCUYG8y4VYEGAkSk8FC162gswFaxkxrcRjHvMhFzNHP/r8cUxrTZCRcEAkkV0qaS6jtBpVBCCWxL9QqI61Yq5MpYZfZQW1fMCnXLxWKCbmNO&#43;ngUjL57LVEllJl5Wv2vtk2Rni10G/QqskfA5eIMDy&#43;NuUgFRBX9HbJgbIMlWMnngB7nHPjamHBJw4d&#43;fT5aSJxZlPvVk4t0bMfndzZVJKKalWsMNxJqOWAVGvj1n4qDnMNpUl1Notk3JfCKYuH2&#43;TLB9/PL79ePsUekVKMoRwc319dXXFzA/b7VZZfqNg9QE551YXZodTloEjQ70dpjMCVK9iPrVY1btSAj51WIGmgVoetB17WYYIH2&#43;LyWbT9bxxGryiX5D3fr1eX15dllKOWp3hvf/w4cPNzY333qzVlFLDRdd1lsAxTDFzjNEya82&#43;siMtllpoJ0qXWWhrlJBS6rputVoZhdpI2wc23uhtV1JKW4W3Xyj4CgLM2997nE7DGUdbhV5QMAa3QqXVahVjtCyxneWy8kpL7BiFzMWzVFprzlKXpZlOI&#43;pOoSWiLUdtmml5AKnve3uklLLf74dh&#43;G5I&#43;yfhFQRg5mEcDvs9EY3DYPw7DMP9/f0yLGqoMTIsM5TtFMU4jpbNtzO8jZCbzcZElh13NB/QjuPZu5YHI&#43;1ocON6y5Kap2KPmHx74/LndeHonPP2YZtT/bDD4WC5l/v7e1UH3LTrer0exzGEsN/vTbwYLuzfxqR2xNHo1Pf9er22olejkGkUKzY&#43;HA5WCdvcESKKMW42m5ubG6vONJLbOUk7/2tPvX35o&#43;Hk2dB80qprd022WimkOKFCzUk27m51rHZa1A4u0gzmSRh&#43;rdDD5jcarNdrqzEupZiCbXhv5WbjOO73&#43;9bIyM6q2iO2wmEY9vu9Sbx2IrjZb28WgsU77YzJ49vLk7ZMJBrJEXHBT1vH4jomCkzatMR9&#43;31SYmZ4b78tmXx/f29vsUkMj8vOCK3Qo22Rh4cHi9Ea7U1Xt0fMXP4PiCA7dPXccZKFQWKe19x6Zbpb/V6jwdyYA5rD5Z5BADxy1jRnAW4mZBPxzy0aFm0FGy3btnMtYTcP/jLIo8k/&#43;/65X8i3UBKeepFBMAXYdd1zu3VuzCHo2E8xpimuiQARIKA1xhFaNKUBcOgcKyrai1EfCdoX0frf2C1LJ3z5C2HReA7d1LNJnsdLa&#43;uCjxjrpGNmG9n6XbYx9i4S&#43;ZazHq1nz5MmQWje6Umryk/P62XvZINy4Svm9wQHQhboEK6D3/hKuZElMdOn8ESd2mlEsEWhA0CnYdFQJZJLcxfHrF9olGgrQLDWS7a9xLv64GQ1qUAjEZq7ZC3RplSRMueIor5u7qAz4dQEqaGVRLKODHVmZy2icMYOAuyJDvTp016LfQ8VUdpjTB6fGQlLRH9xFrfx8mdfAshdDn8nODL0iNfRfwjBQ0XioF25YO4W2s3Nyoo2iSORCLDSjp5ON4e28qqjM095tJawwxnLSSRV0kpEWCOym0a2IAPPm8NP4mJC6JF4espjxeO8FYISgBUdqa7LJZZdYQR3HXyn7TKNV2TOKUlyAwl9lRAyul7oGnbERKd9TF/VOVc6lEvPLLQtmBg9uA4gYmUclMosBcRDZTrvYO2rgEoiWTG4J/YAPcIw9ysz1tBvFr2FLakZtdlgZhlYtoXEcQd1QtshypjOa5fXpnna40XkQKydZt1KCSA6YY/1FUHJPDAPVanVXZUq0xQP8GcfVohH4iLS6dToKgPdwdcnkWTqKzZtr8dwXrMOFQUD4332hWFgYGdC3B1ZJJcWBK2I0PRj6&#43;NGVRQov2ts1rGbNsqkCep2D4qdta9ChwTM1mKVMFnZubAgujIfqhB0vRKvyRYTNVUoceXoUf&#43;nuWj0&#43;oMqzTCKMLgk9S5rD7tKD&#43;UYcFNnSdK7MjFvXQCJ&#43;xZjisSNIvBMXPrcHUDi9gVJQgQhgSNBnZf5Yy7WZti7SmEPsGYZFDWhqN8r2q1U&#43;1SauEhTlmZSyB3ipvJGcI6L2PGVOrMikY/MRxLla7BmfuQkAFTFEyrXk/IXOjgQH6mOH7nKH5XaciTpsVqvHlxP0CFGlYoqKrURsn7aULck/&#43;9YN&#43;LInKR&#43;jrGITsL8tUaQ9Q4cqRqRT3YQDC2k9dwUsxFUheBIdtZEzRvH5KAs0gCm3OIklMCaKCr7y9zM0LW&#43;oTJ137b&#43;vngMFOrXqu6tG4uHCe/TOQIT4vY9CLBGGIK3foyosmjgKnkyT0&#43;Z8h&#43;ATPRrV8ZPUsu0fWsoWNQSstDStFNnY9f0UPmGwLZULpTM9aWPKRDagc4vOI0nbtRnt&#43;Z3LK0XnDW6NUi0ztKzde5OLGIEtwW401NGqgArsRSP07Mn5ry9a4vwUU0U1saw4MAkVbNNHzsBk5BcrGTZ&#43;/oEZSdf9&#43;3u3HNKJBDR8Xh81aH&#43;L9Cjvcw85jPXDY/cpRe/&#43;SseeZsQWrz&#43;M3Sp/wtqilvTaLvcPIYv5LBaK4&#43;ThNQXyPH2AwbfD4KFxj7LHAFYYBNC0LxfZmLRKI0FO2OMLfCyrAo2L8lCY1bF14JujRiPS4jt7b9s/fBkBS24FRDBxy6uLzBEoQLjUNU3T0mPDx8&#43;XFxcGAHagVHrE0dElippsf5l9&#43;mTMu5WR384HHa7nZ39&#43;oGI&#43;FHwyAyt9rD3sY&#43;rDfrAVB0jypk1pBxCWK1Wl5eXFjRu6XjvvcmxrusM761fRwjBgsMhBBNcFsTPOVv/gtvbW8sQ/CfC9/84/F8AAAD//3Dib1S8/uUfAAAAAElFTkSuQmCC"
     data-sizes="auto"
     width="300" alt="Screenshot of the VS Code file browser with the trigger&amp;rsquo;s metadata file highlighted."
     loading="lazy" />


</a>

  
  
</figure>Navigate to the file in the file browser on the left in VS Code<figure>
  <a href="/wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.18.07-PM-1024x277.png" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    
    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.18.07-PM-1024x277.png" alt="Screenshot of code snippet emphasizing the Status XML tag and Inactive value." loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.18.07-PM-1024x277_hu_75741c9993d51290.png 680w, /wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.18.07-PM-1024x277_hu_685ed807f689ae20.png 850w, /wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.18.07-PM-1024x277_hu_da5b944d396311c9.png 1020w, /wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.18.07-PM-1024x277.png 1024w"
     data-src="/wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.18.07-PM-1024x277.png"
     src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAAAjCAIAAADT1JXcAAAOLElEQVR4nOxbi5Ljto7Fg5Ts7kkqW7UfkP//u03SbYkkgC0AEtvt8WSzqbu5mb2X4&#43;qyJfGFx8EBqCk///wzEQGAmUG0&#43;y&#43;ICAD5N6/Mu3l93sovdjZEzL85eD5wf3f&#43;nBPN0e6nmG0&#43;nB0BgBGY0ADEICbi&#43;dj9grMLEd0v4FuzPCzsfvb7bX5966kc5t2nc2UrtdZ1XZlZVe&#43;7qaqIEFEpZQ4qImOMKS&#43;ONteNiGOM3ruq5s9SfPzUASLmmKpK0UQkHwYAIqq15mhPTUFVxxg5sncxvTC8VhSD9wFGdb1cchf5zL0yciVEpGd7EE1eYeZpi/cim72IKFc4t5w7MrPcUV7MfeUgefdb0j8U8MMPPyzLkjPNuUc0Zr7ExlIE27a9vb3lDvPWsix0NjO73W5vb2&#43;pOSK6Xq&#43;vr6/MnGaV&#43;psKaK29vb2NMQCg1vry8pLLyJ3MJUq0Mcbtduu959pM&#43;kuB/7zSULDNpNQvX74syzKFnqLMHU3hTjlOv5yDq&#43;qyLA/2lMrovbfWxhglWi4v/4pIa01Esm&#43;qJPc1RT&#43;l&#43;rVjuQJyjlzTNJ9p3aWUl5eXVEAa77Zt85m0iHwsLXpawf3dWmtuNQXxraVMU12WJd0uJ22tpdyZ&#43;fA/ADUQs6E&#43;SiprjpnrKaXkpL33XDnisdM1Wo6fwr1HKma&#43;X8AYIwWdI882pZR309HTkyYQTTnc&#43;8qjAlprv/32W2stTXj6bHYopYjI9IB924bvx6025/OOsSAK/Nn3vbWWGiIKCYYbGZhIQg2agZmaWh89zSfMRABs390jL5dLrcspvrbvLeV&#43;asKHUrO37qMgwCZg3OzXX8nN3IVSl1pKMbX045j6CAypRZGB6Ovfo&#43;Wa00tKKenZuYDWWj4zXSeVNH10etX8PsZIpT4EpKcNMwhPr5&#43;uN6Etl3UMYqIqI&#43;zJAD86umINTF2upqlmdHEfvUPoZ7Dyf&#43;dYoqLetzC5FyHFqIWJEX0/w5V9GI4PD0ox26HOGEg9CHv3sDcgH4pDvja66wrQ6JgUyKN1ISo&#43;lmrvI/1jWl7qYOLJqUK5d9N7bnJv1Pa53XvDNyEo584JZsidwfacEphxqVgLcqVhS5OiwC5k9wxRbWSjFlsLknturMZnVQBlejSC/DnUBhsOQ4TLFWpx2&#43;5NeuvKuFYsBARG4BolBCJgVymoQh8pAleGi9j1Zs6DGIg1nBlE3FcIoVYsjK4oV5Vvt499b9aHhpnZAxK21h5kes8J/0h74Iq/Q4TKw72E7Iw5c2Iil8V1pdUjLje4MnxRrG7wfZfRsEkl&#43;XKl16sLSARy1aYunVJi/2n2CkNsiHUBAqiIvRsRfPmBC2N7VxlaGF4u&#43;OMrleIP945qUNgHKcVBTMR6qK2wK3vbtXUTM2IsK1JxrQwBGv4FEa8vxARjBxtuSQTQ2VS0d/3aKH&#43;HtPw&#43;n/lzvcof62CnsZsYDIBw6YiFAS4JOEx&#43;zWMXWMCC2yxEMCA63TAMsXXbhyEBVyRymapaE7vtujdLM0M8HMXHce/0T8DdcZHJnRLAvUF23bsh28rEBqIwujlXEvBYoKYCDuMDKiOzT/dnZPl/0D4pIFnB1/HaDPqwt5tyg7Ctm6EARtDWYaqgo6H98mbvu6tG5FRAQITLzrWS7gxpv6JADNwiq0JsewBLMxV3uLebRxoE9JCiLvOEoNOdfSgmXBfHx9um75v20KjrL3SsctgGM3hEDJWYei93Ad&#43;GiX7s/RO6nAHjwLhTCA&#43;P/QkdnoTto&#43;9zD/gqD3SbAgExgghfZjvYsYaIXB4Stq7QXWrZ/9OWjjEVIWNdGLgjkl9WJ0uHWANnXFu33UnOXMARV04ppHvdmk8SmAYKhgpJKbMfhm95sOmu16SIKv5YMBYIagQH//gQesBU9j2oh69QxeE0WJY/lFdiMrAPxZ2SnRu80xMh8tS9BHrYZwUkDS&#43;lJC27i&#43;OOtp4vL1fjF1E0PcDHLHICD3&#43;mMuInHWPll&#43;Cc5nSmgfRS9OXiwXzWKixt3I4FcQC9IoyIH7mJQ3ZqEv7m0kkZxS4Xw3pqxZ212&#43;gu2VqRS6jT6bx3d8WcyOYANXwQdlA6BowU22PJsqJ350OKY9i&#43;&#43;7Cl4HpBJBS/ouZAABienlYiksuDZI6&#43;5oNAATuW4jFa072BqJV76c9MZCaKUwG14Ou1lMtq5UeB5eTyounYsTljH424EhcuS2gFVIeOPtrW998U5brCf/zI15XUIpCebh6k0Bc0xKVU2D/JOwKiXEyitm8hXApECl9JawXMIBEx&#43;abbTZFgqU5rSzkkGxJ3E6biUm279W7MUKrLuoS4x7C2uyjXC14uVOpBfHq3umnbvfv1xa&#43;nMkStRveE1tGDdMSVFKGIO6WzL3IIGc1APA6FBTiXfowBz8sXdljfMoSxOTtBchof8O80VLp/dUcmdlLPXCoRW6homHZzB&#43;6hqT6MvffBZBCPuB/k0lpXMQ/OdXEXSnBwWVdEQa2anj4NOYNzhHrgkkaHZuSxhw8a9gF6dOASApSa3wNw&#43;KAJiWzhB3DQwMMFk8L6l94td34kP3fwaGA5foarvDxXO8y2cBpC36nY5xiQ0s&#43;qyOSgp/wdEFqTYlvpUMrmQO/034XvKbJaIqHLQQebkHRfgQr0Bg4&#43;o4uzvm0HNWV3AMccPDwv0kif3ZN5JOTYM3FK2bXau4ODCHrKfMYyGTBG/sqd&#43;3cRyIgy&#43;hHMUriJmoiGdBC4JHd&#43;xUEliJ6G9MG5L93OeeAQdI7QdksuZhrJwe7IPn8CQGMn1i6iCHKiRyjp3fabZx4IHlPTzp8E4fsi890VMLRhfR8y9Haw1VS&#43;kQCdeZmHJ&#43;oNHfnQTAK2xQJZGYKhCloUZhCEwLjUuqzkCcFAaVhwWSpEUSvwHsVK7266dvKfdA1LaeE0ks/lcRsWhnQXy77ZvuY2T1OuOU5G14fuH3fxea9AkUwbP64/BuEaLZPh&#43;4UHdKKS7SZgclQaHKn9htrLsMWALDwOAbM65NLHRqYV7GKe0zIYUVRsUNgaoS3L9fryhbls2/b&#43;/s5MLy9Xkfa&#43;WZM&#43;sGxw3WFV13H4PgByBSKTIaMfBhqawShJBNmwAhuMm2fVwSf&#43;Bw38Je1Aic9refSAWb3DySpOgpFwrHB6bmiFS0AvrIgvHuRVUEcBuNTAcAFDQdECWBELILt02INqVA0IrVa6epzEvvCmFREuBQXxnbEZdsSNuNOiWMRsF9kNrCyCJMgBC&#43;L5BkEQMKZSneiTxBg77/DAu/9u7VEBItLHcGCngBQngB9Z48dOQguRy4hBV9qBqSAtJouOBWy1vSKgDB27jKGIO9JGrM7EgrzaQBuEsEiv45bV7BGwzc2juvROJpE33K5FkRcFuKg1s6FtM7xFLU1UIqom9xXnu2bDo4AHnuYc7e8r/SeZsIgA4gCwujg3HA3lA7MysE9oGgISlTgDW3hfiV5RVzQCj7u/qA2VEbFaEJ2kFhDQKD567gWmhMCjMQkcCYEDNqE/BDoKWgEj2IiEaWfECrYQrgBVjTRAKEvSgId3Z2xwOJJgB2p/D/z5VnuMAZEHlIFkvKgqeaCT3F0SkllY9x&#43;cZRwCo1e0n1AqYsPyBrQjbCYNyJCxSCGtC3NdUF1C2V/1KFlI1hoJHNHitApHc&#43;fxgE1iVaE6PzRdES/IF4IVx08ohAWd4w7V4fz1I2wdfvp3tv1sj4mYh&#43;B1EaNGixO6cG38eAbueQIT1kIOPHb90coPaDvgDZcbcnc0U3SA1oL9wvtSmctFjbmUZVmJMM5XmkqeIhhTHmUxE4z2W99tjC5Wmr0MWM08&#43;2/MxqxgpP2LjZ88FOmmt9ZvkXM&#43;Kbj/zdtjDDhwAPDzRZglsPNo5WDWwQOPgocBEAQbtTivSV&#43;xI5Y78sCIVIWO8mqwmhHF67PqEmmgZjKocWhj/huzkGoIHA4UrplL&#43;qDkf6o89s9unxKxPGIcqp2KlUhLznLYaV9T&#43;phVqNbEoHmwRieXF4ILEhruZs1gNxDV7slTHKBQc4QPUz&#43;OfVwtcs&#43;&#43;Dqam3aM0eJItpoAbASwIK/FKuICy2bvZf5n9atZ1BHf4DsX/vBqq6vsXjQLHSI7t1&#43;RIXIGqYQnLjNOwOCT3eAr8anaBfkW4AHaD7oQkD4A9ZR42MokYWU08XWqCG2Z64STVGH1xa1AxjEpWAVwIGFDAflF4U3tT2G1moN8d/MBjDPh4Oad37VGUipIH0nH6UUtUnvlV&#43;TUy/k7nOxdIvBOJjs1kRVi5LEQvTg&#43;jzOMW2od00W5u19rFJJHn4bQycSwTBcQjvQZQgGF6G9ABmsEWoh/Bhr9DsX&#43;0pyyIeQy0WXDyO4XxstBSybB0WqS8EjCLZAk6au3x2oRqA7ghreVyXdYLx1mkg3q3tmF/v4gVHCY6IOoRdy2n0vwYCECPvFdDxGou9xbncWIQZWP4Kq/8/tqTPOB89ewufTQbYnuLn2TNmo534ngL6lSAY4yT/u7ZHBen6FI3DPs10&#43;FJAYmxQomDGVGyk48ek5zJuoaIQ9DOULOWkx/N3DxD&#43;4la33V7rIaeb&#43;no52ooDsHNczJEMs9G8RekCnlMbMdpYxSCM2irNDUdgznl73qSAW73npLZg&#43;xnO6uP58dmMRJPdPreTf6hPckD8g3L&#43;Q7s3d1iHh2jLOQJWosEdNYAzRg8bz3OVAVlzyQVjkpZvFsS8fX3Lfd7N&#43;r/VfsEQcy8rmu&#43;DZdvA86GSPEeFj9/xQeeyQ1PiEY438b6l5LtH2rPE7F/zNjfIyv8y9snBYwx3t/fiejhRGxGiPnm97/bP6o9yYSfvpkyX8//Zyzy/3N7cij/9UPz/0f8hQv7V2n/HQAA//96T53Jk2eeDAAAAABJRU5ErkJggg=="
     data-sizes="auto"
     width="1024" alt="Screenshot of code snippet emphasizing the Status XML tag and Inactive value."
     loading="lazy" />


</a>

  
  
</figure>In the editor change the status from Active to Inactive, and save the file.</p>
<p><strong>Generate a Manifest file for your trigger.</strong> Right click on the trigger code file in VS Code&rsquo;s file explorer and select Generate Manifest, provide the file a useful name (in this case used DisableTrigger)</p>
<p><figure>
  <a href="/wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.20.28-PM-300x125.png" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    
    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.20.28-PM-300x125.png" alt="A segment of the contextual menu to show Generate Manifest command&amp;rsquo;s location." loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.20.28-PM-300x125.png 300w"
     data-src="/wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.20.28-PM-300x125.png"
     src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAAA1CAIAAAAGW3RaAAAbg0lEQVR4nOR855LkNtYlHAGSabvULYU0q/f/N08106M2ZdLQwm3gHhLJNF2tif3&#43;bHxUdCmrKpMErj/nXpT65z//yRhjMX1hnOGKMbL/vVekf/zy8qfvJpHd/yIuPnst0st3iguRPkyP4/S/yCLn/H9iJ/8/XjFGfjHFxcvH72aMQ5ZLiZHaIp/kCU1kkZLsLwJWUsoH2vuf2Uvew3z/yNndjuLC8VjkbLnO&#43;VoYRBLQQ7HExb34QjZXUljK9NrpHzz1Z3v74Xv/nu3jUoJzdm/v9LbZGPj9sn7qIpG8ajaC&#43;c0ci77ysMWNOLv6cSRh8&#43;tn/fDJnM3b5llD14&#43;ZtMHvH/yTuyNCzEKlVQncPdJ1&#43;8Ef2P7CfC6XurhG1mmM3gfrbAhBCCE4DzGGECALPE/QdbN0em&#43;6m/feOYuFynQJWmx6vPc&#43;hihk&#43;nleEz6&#43;NGzvvR2tD14pVRTFpIals8wGn/dDD3UxRiHSzbG8vODgvcd2aJE3goYc888f&#43;MEkmOicCyHQpmQI0TnrvWeMK0X7TB/nS/O/uSF9e3V7tVDbZOze&#43;6ZpjqeTc04XhVRqHMcQglLpzc45zrmiSwoR5pvpojBlWRRFjDF9/Hj0PolPa11VlZQyshh8GIbBOWeMgViD96O1QgitC86TaKSUnPOu697e3qy16/W6rms8OssokkHA1IQU&#43;G3XtlizUqosS621FJILDuE6upSU6bmkAyFECAHCIO2EIl2aJOCyweFBUJu1tm3bcRzruq6rerS2ac7DMHDOjTFVWUo1GXQMyWmklEqpO6/iy8SublXNmHXu7XD4z3/&#43;471fr9ZCiqZpGGNlWcYYrbXQvxBp5&#43;M4OueKothutqv1qq5rzvnhcPjy5UuMUSklhIACoP9hGMZx1FoXRQF1dl0npVytVowxvCjL8nA4/Pvz53Ecd7vdZr0uiiLQlQUxyYULbfR2u9Van5vm27dvfd&#43;TOtP9jTFKKSggi1gIEWOEaJxz3gchOOx6t9ut12tr7el0smQWeFYyL62lVH3fvb6&#43;Wmt/&#43;&#43;03znnbtm&#43;vbz54WEZZlrAePI5zvlqtttutMeadiP1AAZBy13XWWljK4XDAukm3QWudvKRtlFRN07Rtu9/vjTGiE9jYOI7DMJRlGUI4HA7fn58DLcgYwxgbhmFpy8MwKKWMMc45IcTHj58&#43;ffrYdd35dBqGwTvXd11RFCQsDzWMw8g4gwVUVRVj3O12wzCcz&#43;e&#43;7&#43;EfIYS6rktj4NZw4qIoUnCztlCFNmkXUkqtTYzJFbTWxpjz&#43;fzly5fz&#43;YwVWmeTmukahvF4PMQYN5tNXddJRM4aY7z3p&#43;PxdDwh7HuX/uOcPz09JZ9Kzi3/CwUIIZJDVZW1FgblneNksEmTFGGTUYUYRQwxRdcUeWe3mGI5BRPsvOs6cn&#43;FoNT3/TiOEB/iAOIDfGu1WjnnpZCGZIccIKQIY8B7kla8h1dRIA7WWujG&#43;wC383SxyEKMUgjvfdu0ox1nq6fYWOj0uPWKvFMg5iTtjmPbtqfTKXuwlGIcR8RMxJBp&#43;yHmbYYYnXcw037onXMssq7qkJbuZHyJQg8UgJtC5&#43;kdSq03m/V6vVqthmFomqbv&#43;2TOZYngm6xJ60jxFFaDBAjlGXJMeHRd1VJJur8SguMR2bQpQOu6ro3WQojtdmut1VojOpGNXvL/er3WuhAiWVZRaISd3W4L6xmGoeu60pSMM4QXSr5J5ZCXLrQqFHZH9xHwBngPMjnnvKoqY4yUYhhGSF9rzXlauUrbLmIb27ZFWsZ24HxpUyGVGyzG&#43;3qL80sJ&#43;9gDtE6CgAkgtK1Wq&#43;SezRkpy2hTViUMcLlifLyu6/V6nXK41vv9PmXIrgshVFWllLLWUubwRZECCGIC2W8yzP1&#43;X9WVTip5wk&#43;QexC4OedFUUgpEd&#43;BIrUxkIukHKu17uhC4ErBhPF6VRe6WK1WKBOM1oXWiO9VVRWq8MEnsabHmc1mgywCBXA&#43;JQmE1qLQm82mKivGWHKXphFC7Ha7kiwS7zmfk6BUoaRUS4S7cIGpWLpVALaxWq045/v9fooAQuBrKmnKJLK0z0JzMekWauApVhZKqe12K6XMVRDnfBxHfApWBquHKU21KZmeEKIsS2MMIjJcCglca20pcEmEBapwJouREuVNaUqRoqCA38Cu67oeh6Fp22EY4MeccammJBxDxKpCDOQeCh93zue9U2hKC7TWeZ&#43;qrLqu06eo9Ow3G2wEqu26rm1bBIlUHZjkndeFz1UQUve/gxfjdrk0xguYHkHKtLDLzVJ0yOU8RxWYPw5fvkErS/yyjJLZk1J8W4DVtB6q7fJ6lkaDCiqqmF8jfqJ4S&#43;XcMFibEmYqFuZH5NI23wcVdlmahL3Ss8RywRku4A6oOBAhc00BC4P6N5tNWZbvg1aVfOGigyUai1kut2kEKD&#43;yCRylfxdZT8XSNUTMsOvqNov93Ehzfg5F5DC9Ryhx/55rMoPd0BTZbrCAjB9xBwTPCVIsTA1xY77Fe3RcqjuuuRzKGXJDbkFISf5EARd2JIICjCH4vu/btkUMEUJQKg/IeAT8GKItn7NJnLKZhv77vm&#43;aZi7yNNZEexNL&#43;J4LEgT3JUDNFWpeBiLsnOP5jRaXW5q9KjDGcy3vnMPaEPqwHlTb4zjGmAJRfsTSQbG2dyR4w9YgXAPl3L7vkSKvVM2TUTBn3eHt8O37t&#43;BDVVdCiLZtU&#43;Ki0DyOIwwKgpuguRD1Kl0INYfD4du3b6gNiiKlPmwYOsOGcwWJHWLd0DfiAOf8dDp9//7dWluW5Xq9RpGXt5chsbU2RkYVrUeWznfGo8/nc9M0QO9QJ7Jx27YvLy/DMMCk6qoClIXNBUI86/W6LMsb3uX965r4zJby&#43;M33VVD0wXd9dzweqb5J7nk8HoUQq9UKFlRV1TiO5/NZStl1Xd/36/UaPiy4kErCgZAGjofj6&#43;srbk1AjHddF2MoibdA/ZMSuBCaChiICdGz73uAUuccIHQIAXEctoaCbxgGcBKOfM5QedP1vdH606dPq9XqdDo9Pz9DiM46bfTHjx&#43;3221PF6mctW17Pp0sgUEp5TiO1tq6rv/44w&#43;k4r&#43;vgHdUc6&#43;HB1VQ9jtAEvAHRaFyrET9AIiBKFGWJdJCiEFEAYpFKRVD7PoumxjKZJAnXdcZYyxdMPwTQSGAW6010hcCGoBbMl7yOSA7FFowNAov6WVBxVLTNPAbEBt8BsOwax980zTA3nApznnbtA1VL0QWcTtiafbDhw/Y&#43;P&#43;rvPk1SzdFnPgYByCg930PR4Ynbjbrvk/ibtuWzaSjIZmSdNxiodE52zTNnNYEkaOMJBYS0JUTi3cJ&#43;vQVjCZicQ500AHyZ8ZKqGtR5KSiqyiG0XrvBOeeIAVknRWvtYYCpvXNmC6EkLbD2OQ9dHnvhz4hFSEsSuS/IWz&#43;87YKR0ckssWeHyNhkDOA&#43;wBi2&#43;22qqocEHShtxRGAbjwKU9UABXFCRlZa4uieHp6ipG1bQMcQLQBkXfb7Xq9hkMAJwOjOefAtED6WAbiVQyBUY2LbAEWb7PZrOpaG4N4hZKcc953fZk&#43;VyIl4IZCCFCBdV0hsmutz&#43;czYAcKStz5fD67VLbqnybhhWzvdMDveim3QYg/CEFKqfV6HWMEEKPaRmht8Jo8N4FYKGZJ5wJGFQnN7oTgiC1AkmChYct93xtjoFGUIpRFI6TmvEtgmHS/Wq0&#43;ffq03W5TilYKVByS8EgXnojqyzmXUhFJEC6Scsl6A8yMvJpJ6TXlGGAFYH5AHwjhdDqN42iMAXCbauhJdlDGA2P/QZlzE4du30M44PqO4BL0HFuQf/BVqQLs401DZlmEXfAacGzCgRw8WSbOQBhgYylvENETfBjGIcZYlhXiMpJBpuYzblpS&#43;SB5gAVrMmHBeUYYmTYHrpx&#43;TuAZ1gO6OzIm020EwMFsZ05rs9msL06wEP7DcPMgDr0LIyYkTDvji75twoCCiM&#43;8bfRhLv2&#43;aziaY/20ThISI8Hhd0JKHqMgOEXJQGBXOcKmD0iGhDnX&#43;zw3tnKxT9&#43;irXTp6hJeS2BQgY69akNPQC0jQZBOeC6iHFNqWc4j98CAls21K5k&#43;7NNOKmDxfZFfa0ktbjqtOoTQ9d35dBopiCM0I0yjFMmw5dL2C1GkRU9ADHRuDkHY/FywRwRcOH7TNMMwCp6KyDjlD43QlHuHmQVLd9NGSJFyQW6tk/&#43;MVLUgOomL3TDK2B5pf8rnXXemGgkABfRRAkCzJU2oWzxG3dd6eBxyOLvSzk0iuMkW1y1JWrR19nA4/PXXX33fV1WKBk3bEjNcCJ6SGCr61WqFaItl1Kt6u92CeDkcDv/&#43;97/BoVd0CSFQsDrnYwwf9vtPv/7qvf/69WvbdqDwoJ66rnfbnUkBuoDyvPfHYwITRpv9hz36CowzKdDmTMEN/LMxBmahpGQoCkjrfd9rrTebTYzx5fX1&#43;fkZ6tzRpYn9Bg2dS6afF/53ZeU7v3ykg0zGXX8OUKvrepTSaGCdTifsykUHjt5a&#43;/b2ppRKNcxoTWkYZ3ndyLScC2td171Ai8RPtM7ZECJKvdyr0brwzp/PZ&#43;C78/kMF3l6elqv1&#43;M4wiCIXrYyqcoxluIDo&#43;Ydm&#43;ECxCeJHUVfjzEegm/bdj33NZumQX8baPF0Oq3XKcqjjQU&#43;HFr5efFDcsXLu7GR99SzdJ/HQEypCTRhG6n2ILvw3gueILG1tmlaRJu2bfdizxYkM0qRqqpCCC8vXQhNSew5NeeY9wEMMB5HzLy2o4UVhxCen5&#43;pu7JLyVMVbde9vr6&#43;vb1REz9oo5E8ULNSI1NSXTRIKUEU47dgTdAVKMtq6pMQkscPv3//nkBiZKpQfT&#43;M40BgnuMmf2s67b3y//36B0TaIyAGOgUdXUfwSqliQ0Cs6/qu6&#43;aik6PIkUIyNFXn2gOhzHkffK5VEjgoyxJSgwjGcUSdXtf16XjKxA5q1qqqnHPW2TZB1Ba/PRwPwEoYUBiGAYVpWVbOWdyt0NoRhZfqVAroGOHgU07hQHD4CihAbdcG/eRhHP476PsjHdyFofu3JVt/eMNMdqNWkVJ&#43;&#43;PCBujRHkCRo&#43;WPyYL22oMmQn6G/gugKzth6vUJohlPDZjFpYozZbDYJZ5kyxojhBghOSrler40xKJwS2lqtvPNN22QqItUCupBCahoJCSGUZbndbpN7UfWCChgQDOkErWbEOiHEhw8f1qvVZrtJsPlt4khAs6MUzDL5SWHzw4R8JfQ5Yl2984ECpEzRAxkVLiylTDZLvVOCPAmIYUsIU4g8KJmKothsNt5562zuEeZ&#43;Pag3eMDUfEZ7llo8YCygSEhTa71lWzzLOff29nY4HNBuRHrHE0H8wZkwCJORGmmRS1RQJHQkfNi&#43;oXZm13VVVXadwW1TeOTXrdz4bj3/44h/m37v3OC2I5aR8BTxSeKMQg3lYUWhKeZCfloegSl8du6YTzgO/fcbkhb6gHqgGEC/ZTMn90HBHqMCLsuyruvz&#43;YyufSYYckbBqqDmJfWfUQWMCVtLq0XfS4inp1/AoOz3&#43;/sMTOX9u2n10pv6qQ74kqdWl4nMxfgcyonl9M5FcDxBtsv4SW43Y/KSLggOCPbhKGBeVkYSUN7D1kquCAGR4GG5b7rsYi6fAtdcQnS8DW6acxWWUVUVKi5wX/j48s5sMnP&#43;zsQ6n6rLB0j5NvgsccByphQazrWzc04qJYWk4sFNyqCVKdrGcg9JglJxSXNhwQM65WmnZSPwZpp12ZXNP8kSXAoX6kRyQmC01voQCkqyixtSV4NyyVQmcV4Sq5F7aXymK6iTw7OjIMEMhHXA9S63SS/m/uHD&#43;pMv5HinnriIY9msrzticRqrQwcjVymYksuUFvDqJQfQc0FbolXSdd3r22vbtBj62Gw2MLollkZAQKAAfxDnaeZp/I3ER2GhyE3QQKDsfG7qugKROY4jMnlWFWiJJMq2Ozfnpmm01k9PT8j8hLliIFsFZQ268Hg8vr29wWKwSFC2iAS54bpgX9h0juO&#43;BJrA8L0fXL0fOngAxJxzp9Pp27dvzrnVeqWkwpgYGAJM&#43;/T9wPkJQGy0Y2nK3W6XbfZwOHz//t07DwBM5R0LMZkqCGEQXuDoU001z4kAWqNU7ft&#43;GAaU5FDkbrfjnL&#43;&#43;vn79&#43;rWu66qqYCUfP34Ek7z0G0DIw&#43;FwOh6rusYT4UDIDaooHEGc/X5fFMXpdHp5ecHICT4rhAAUBXRIJRPFqFuLv47pS3Ez9hM2&#43;nEZmneCRUgp27adBz04zN8533atkrJJJtZicXYcLUX/ruu6tgMg6roOdQvKRFQgOaBDPeCEUXdh&#43;A582Tja8/kMj9ntdoLzqq6ts&#43;jxlmV5PB4xDt00jaOpHQzKFYViNKPZdt1orRzHl5eXqW8hgObMlhIJKmP0IBEz0cxpyH2Blq21mHQCz/EIoL2Dx&#43;46AJjU/9FoImEriSY4AqgPPscc6mdZnN64OefA6SzAcn2g8FCzo&#43;uEMobIKNH3fQgBQwkoeFC9tG17PB7nIUCGtijQlrW2YhGTkPCPPNwARWbHog7EiOCGXI37sJSoJCCxIbYjRxWsASGXQpOnYGCPxyPCL6iqHwqZLSnam7ozK2zRC5vzwSMPoMF2xPQUrJVc1StAIZAnlAYEyDiU3tMUFFIxVY11XWM6DFYDdhcdWuwWPcWEaZ0rlNpstpvNBvkjd&#43;LgB6Dyk38k9KBXq9XHX37pui7ObTgMniDsVFVF7SAJxI6UnmIdUViZmUAHJlUHEjhZrdYrPpMQlLGmkzzIB&#43;gRCWjrx5Qzz/8Wulq8fZmEpyGgh0BMmrLcbDaoNC5AbDYQ2ONEIi6mWTMQ2&#43;52jDFEElDE6MPkYwG5E4CfY&#43;zHJDyc7gwWaDnoCpYUKXGOgW7ZjMsTuGCz8/ALzE4VynuPiJon3QHB0FWG/6F9hjF6NNeQw1IOoKerSxLm7Paoy10kWZ4Uy6X&#43;MgmzH7QkBVFamD8AWskAB9uL0xkdtTzWGmfznypF6tbmCe98vGIq6qf5LAZPz30PCDoDwLi4MmqDNeQaHy/CPJudh&#43;CWfE4ut5bdtPxEvEiWQUP2iH5QQMZ06en3HPUlGzweQeePkvBNL&#43;fRVATnBY4fLXqBeScZxdwPerLFiOQSJT1IUXmk7nJAbLpbbszeH6eaVizVzarjNYp8UGywizlGNs9MLjDBzfDkpI&#43;8tZuTpf/N9bCDvGQu1H2aRnsW6RdJdTnomV/ctSymHeVCIpeD&#43;SYXidMHLlCL3U7aLr6boPvUR6QDfgnxiRmH89vzkMudL/eMjWJtU&#43;PzUUkT4&#43;1KPPXUsFQ49GNJP8C5l2HVq6OrCyO59QBsNSfbDDjhhpnFReKCC8M&#43;iBnV&#43;ZAefXw6AQAknO68YOhwq2lmXciZxhCz4cc81SOE9MG3TYNeCugg5ElqpIsFrL0aKIaVZGYJsPF0Op3PZ9QO&#43;cjY5Lg0GIvtCDFxR&#43;C9kdKVUhWdH7mB9Jk2XhgOuwFiN8MPucev7lk&#43;dLv&#43;&#43;usv7z1YsOUhvTwbigugCQNCKH5wSO/z58&#43;57wpos&#43;wOgrOkdmZU8wE8yt8KIQ7tFOADjA&#43;9vLw&#43;P39PqXKzQYJ13hdKmdIoqYBackcoE015erWksiLG&#43;PLy8vXr17SwusYhH5qT4NRqviRzaKiqqmEYXl5e0CqIdBhkUgBnPj3No3cEjHanA35bkt7Fo8eH9FA1w1Uh0OmQXkz&#43;CISFcdemabquAwufiRocMqW&#43;a9E0DcAn0uA4jlVVZVYAoscINMYR8/hiqmKF&#43;OXp6ffff0fDi9oy01HLtm1Hawsibo0xIYTj8TiMIyfvRJSAyaMY2&#43;/3//jHP4pCN217OBxijK/zaVbsejltR9M35X6/f/rwYSSjgbWdz&#43;fj8RhZFFxEFjG&#43;aIz5888/Qd3fhqUJDE9yZcsj3Jem/B2XnYlySz3b5IZUqmenns6WzIcRrXV5miNPkWBm1qc0zhBtFud7Y66OmnNzOp/apolUe6AlAm2NdixUUVNfDPAK88yn0wkQOoTQE47NkwCYgEOhPB8eTqbAGDPaoJtdFApVbJZ71hONwOKaBr/tPN&#43;oZr4P0VgpGULEvDBYk0Cae3g9hA1TpJ084FFLwBjd91MZs16t1vQfmR4d0iN5YZN56jYnZ4wgoGYHvTOdAwDJRSEIlHLSHx3JBwgC4FSFElyoQeWzYEgbxhjEJbptEakDAUlBH2VZ7nY7U5Yjfcu5KGi0go4UGoi2rlJF7&#43;dJ0DwmhO3UdUXtuzI3D2hHCdbBMsD65bnuCzxekPMP/ooEiM57Lcwh6JK3OeMZzngf8iE9eDrGKLFc4NV8SI/OwjPoY7PZ/PHHPyKNjNBYjsOgIIYhwOtNA4eUJNDyxeCCtZbKqZTJfQggiPKJe9SpxpQWg0Bk0khLVVWt12sEQ6RNGlw08I/dboc5O0xd5rMLI41S4ygZVILz8qjogNvHcQQhUZVlWVUJjgnRd/04jjjDfBlGWlKldxCAP/pzQOpi9hP6ZvO59V93uxE7h6QkKQb7yUg4OzKs2GgjiVfA0vMRdWcdFxw1EuIDSiM6FezsOAYiDOAuQJFjgqDBpC1XaAvD2BGLlqdrKGNbLriZR3rqVT3SwVKkH&#43;BeiBgnDzJqw0QpQmKOoosWkKIBQZF3PVV0ITR6OniM1qlU6rb0zVHmnrXIgwuM3Tah8FtDo7i5pXXphyyGPpfo6QaIgZV4dF4MG7vguGlkk8qkG8hWV/ViCJVXlcjjgnwx/XnzpzZwaa1jHZctoNybW4Ks3A67AYMZA&#43;B/dV1nneUkR10hhUoPxAGfQdfPOvizG8ADaHjEZ1nTAyL97Idz8Q/lnr99f5p&#43;OXC4FNzUuaVlZQSej9Ld9CZzyb88X3e/qqWqln9qYvmeK9NhPEykxqUfycXVLGx&#43;SvZXhN8cBq5PHvKJOZ4rY0zYX&#43;yGMXUmYAJqFzV7CAGE&#43;0MdpMxWKCFlmEdcc7/b0XBZ/PFQDXLyfHLYOmdjiJyOzINtBfmFxSB5onmg5qNb6Agh/iC1QBa5XYWvYND0PEyGjl6MDCkBYR3pKv&#43;JBMwFD/MFSi4V/UZzxnGIAcUhZI3FpDTQ9/k0OUYxMD2GyAlOPofNPCuW/3yFen5&#43;/vz58&#43;FwMMb8/vvvv/76q3PuX//615cvX4A&#43;biQopUI7EFgpc5AY9uv73r9XkE1Eo5QyAYi28yFVI9vN5v/8&#43;SdgGMZA0YECpUqjqCUN6xV01iOBYow1nk4nxtiGLmwY8kULaLfb4SDY9&#43;/fcZ/9/sPHj7/EGNFyMMZ0XZd7lkKI19fXw&#43;FwPB4557vdbk8X5/zt7a1pmu12u9/vITskm&#43;Px&#43;PLyUpYlnUOJh8PhfD5ba3fb7a&#43;//YZGW9O09Kce1n3fH49HTENZa4/H4ziO/zcAAP//ZwC2NESej18AAAAASUVORK5CYII="
     data-sizes="auto"
     width="300" alt="A segment of the contextual menu to show Generate Manifest command&amp;rsquo;s location."
     loading="lazy" />


</a>

  
  
</figure>Depending on your setup the context menu might be quite long, SFDX additions are generally near the end of the list.</p>
<p><strong>Deploy the change.</strong> If all your org&rsquo;s tests currently pass you can just right click on the new manifest file and instruct VS Code to deploy the source in the manifest to the org.</p>
<p><figure>
  <a href="/wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.25.52-PM-300x62.png" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    
    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.25.52-PM-300x62.png" alt="Another contextual menu snippet, now with Deploy Source In Manifest circled." loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.25.52-PM-300x62.png 300w"
     data-src="/wp-content/uploads/2022/02/Screen-Shot-2022-02-26-at-2.25.52-PM-300x62.png"
     src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAAAaCAIAAADwocO5AAAQkElEQVR4nIxaiZbbOK4lAG6SXU6/znz3fN7MN8xJL0nZZUlcgHdAyCpX0unTjOOyJYoCsVxcQPb//ve/P3/&#43;fDqdiMj99RAn&#43;gdE7DPo&#43;zgkAnZ2nNIJ4wXP08bM49ox7VhzX0QnPN3o/b4/G/LhkzwdlOeDj/XEffwg&#43;4fng48XjJ0MkX/46j6eGkKDs8&#43;PPTiRn8u9j9ba77///t///vc///mPxzGIiBB3Te3KeteyY3bMwB16B&#43;7IDNJBjzAI4z6hC7MTQQB4CPMkkWkZfjQtC&#43;sOwIFeCH&#43;j7A/f923CsdC&#43;cdnVPqSwWXpmnyDHFbC7wMfr9sUBDpOwvsAhCaK9GEkAWT&#43;PgzpZpdd1AHYL7e/v24HH7scdhYhgDI8ACEDCvquKsTfo3fUm&#43;t4dM/fOrUrv0BvXAr2hCDrRd2YCpyuJ1DEEHIZIIQKpfA6Ax1a7OKd29kAEiA5Ubgeudd5KUYFC8CHgOLUbYtfa&#43;w6OnbAIc1ezIeLYZO&#43;9tWZTeu&#43;I6AlhtwxL121wb6ynQJ0O1PLCXbq&#43;EByKSBtbA/VCHJpqrZZS3RCPQnTeC5Kqnsj5IOSHAYYN9tf4rHOISd9tgjOffBhgSA3mIh6EqWyRa6wb1Q17c51ba9u2ttpMiK0Um11r7cwAoHgFgETTNE95EoC7W&#43;5dncVjDJSAyJm/iGus0YHgiTySJ1W0mgEI12173RqzJAgBIyINM&#43;lZ1Vjvu4OCQ0BmdgAxBAeubKX37sB58jGGUsqt3HSe8Lb1ECDi8DEEtRV0cVCFa2seMUbvAR0yC3aNXkkxonNbXcBJ0G1BIEIny9v93gr3Rk0yO9/YVEiecs7BB/gxYt3u&#43;0y&#43;hVjTVNPUfZDDgR7DmQGw1nT9empL2ha1DvnqQ2X5c9lel6UDNuZ122LKMecGofa&#43;1SZN1RpS&#43;JzPLy&#43;fAPHN3&#43;9h7V03yVsX1/VeqIHJwuCAvMBWATGEgEQhhGmaN3a/L6W1FmpHXFRjY4L3vpRSazXMUXgEKKUQ0eXyEkO835d1XVkkxvjyci6l/vb1tamP87qtKSbvvW7Pa4hbTDDzui56kPSgQd&#43;wMX/yiYheKzOzJ&#43;eJJgre093zlhy3WkvxRQLxgGieHH0O0/l08gia8wZc48APatXXQrVgb4K4zS9vl8/rfGYfvoNUyyAeW4mlpPXmHbfp1PJcY95YboW/vK1FvQQrhjlO83TqrFCzwNp7L71moNnH4CMibr5Vz83V631ZloWZRTMWDLBD78mHwMOjYQTgPM8YIjuozPdllUVVY0SASHe/bhszhxCcOB987/3t7S2EAIjTxG96EzWY2iAllWrblvu9dR21KejUWud5Tim11rz3IYTGbiubyMpjeO/N5LPiBhYHpXXX1Fqrg5zz5rBRaAJ3qdCENJo6ODcHCCHT/OKJBtBpOkTu1BvV0ssW4R7Xt7CtyFxjrnkS5xWLHkFwwKkeZR96SiAsSMDd1y02nmqZeyUWoORynubJh7CWIghzSgLQM4eovkoISEiEI6owxjgSxz4AMYYQU/JE6qE6FMJpBIETmeeZWUFvhLY3&#43;QwoQwg5JR6JvSl0xGBjaNMcXFNHCAhwmmdwruvqAiNcnHM559M811oRMeWsUxffWmNRMXBo33ufUgo&#43;GBVUmQGC9zEEcG4d3j3lTEjgZF3W1iq35npTjWtG6sP3O7ZGvWKr1CqMHfYQW4iaKlT18JzLDht4DnE7TXf8v1gLlQ3rRuuCrbqyZClNUYTQY3C1N156VemShxA1xxJ5j0EY3cD2FDk6OM1NfbCVbdtKCT5M85SS4nvriutNRz&#43;fz&#43;cUVZRPl3NKB3UxyYYaeeg5dM0gmgvq5UKE8&#43;kUQ5jUzF2TCoL3XmMFUVnAmMqdS9XcPk1Tiqn3pnzDaxiVbWutKcMZ90DLZDmT9wlcyakPH08xphh7rSu6XgkleQSu5VaWbV3z1j/dvr5ACwCq&#43;sEPkdvghywOmKjFaT3FmudtOrP37q/ShYh49qGeXtacOzcqm9kAti2lhfLievOD&#43;2Jd2Lmm3khgfM553W1lkAroT8KVu6hPkSPs5CtKUdZDKdGIdcc4JEOp5BJyLosDmFF69ntS2mmiAosbvAkJRYF3lBXJaz4AwV4FxSEq6dDZShZeIomHnfX03qOCAxESKooOFsIOpUdiDzv9HMlJMzxXrK1DZ69C6oXQqa0ivZNOJOdQVM0LyeZdgv5pvc2uGgdTsgdKjZqPnXz3wXy/h9RD6BYBD59/rhMAnFpGiHpMDnLLs1L73l0tbb23&#43;x16I&#43;5cqwbacC2FLaUqY0vjIAkDVGhNSjFgDV6Jyp4GmHHrWPEg3Ya/2Ddcb8659IhIBXSFhm6EnYWtQDmiVe8/wKozK53yXqkKwE7yHxtrrZWyCcsgtGCLDInRTPyoTD7UDU&#43;Hx9duaDEAyO/YzYQUwnT5hIQuxM37ozIYvNMr9SQ/2Odgq4M7yMfiBp6Gc&#43;AfyQAckTg1t3ipANdluzVxDAihKomk4IlbU9oKOOymFUCOMaeE4NZlvW3KKSJhQq/3RLEt6620FlC&#43;AXut56Q07or7lsdwEErhvi5Lb20oug4gjqY9NedA7re3t1K2GNM0ZR8CEanLP6ob8n5dt9vtxk4zikYOUYgxxBhTCinhqE4E3qvZvdx9UBR54ip7B0AL4Pd3dtABqpZj4B5FgHuUAh/qLwDnfig&#43;P1bK/gcKq/FeO1&#43;X5fdv37gr69&#43;2LcU4TdMe3a2MYOgxxc95fkma/W6FrxiapkuNaCXpIuqkOGoaVi4nSvLIktu2apLwhCmi1kcA51OmEF/vZVGO31ptKVGQDsDBB95xD28d1iIZnV&#43;7by5Ea3MIIKWYpjzdmf7EMkA/KJMtHeqWOnxK51/mS8rZAT7XunK0GZ708xQL78Tx2SqPtsTRjfin48hzuwH&#43;upLY68C&#43;bZt&#43;qBWJ0ri6iVur6reWMom7iOuA4lwRVwEKy7qutbXemgPIKcUY1WKbkv1BS9IJvTi5rduyLDnnTLKtBZF&#43;PWEO&#43;RrKK9TC3VFMFLty85aTR2OoSEucitA2lnVVMg3KBJRCOk9nN893R8vWYBR1d17e1rda6yQgL5J8xDQjojz3HkTEfQ9N8hGbnlQs37esDiP8s7FXlgcL&#43;pmVRqE0oTWIAM7ncwhacLJISmqLPpSLo7WAAAMNPGlSj4DYB3CYAaqyDq0FlEDlFHLWyihEzxLz5FPqmlcoTHPISpiVei3LKIn9uq6ud0xJK4CB6Nn7MHPwvowyLcbYendOfJ4oT0o2AS&#43;opLgzd8QmArXGafI5gw&#43;OcOfjI7G/I4LszYIPX03bDyQZc&#43;G5pSUf&#43;4H/ZBwRsLcifqRHxtiMnvfeB64qUxaRZVmMJh&#43;5MaU0kiGdzufRq2i2HrMSjBCDccRBPZvZVQui1qZpUqoSo/dKzIlonk8xqtXP57OxeOecheC4SxgtIugjSyOihZQxdxklcRr2zjnPpxMAtNbmed4&#43;fbJC7OXlJcYIT9XQ4Yxqi/3bSOryODvueNgILOE/qRue/v/D8bjnzyPgMIBmRSf4GCISQpCB7McRoxlHP9VYkJ3aeeSIod61NDV9WUbVJDEmHIqwySmleZ4PQmLTjt7h0dvcWdZj2iHGsZo5wTRNxzRzlKMfebjhd1nReNqHevVZ748AsEV4dMa&#43;g/W/H48mkPupAQ4hWm/ma11Tscph7v8sme386Ece9rON2eUH8FkwPdPKY5&#43;ttXVdrfcwkA3BNi7f0QY7&#43;K7i3roS&#43;SdL11oBwfo8Vk6bjzsnVpxrITbc6JCTH2NsVjOfc85aUs/SPgts0/Yae8DAs1rwOzX/4OLH8D&#43;iErO0Vq/X67dv30yDpVRC9MEfoofROkbEeZqm4bDX1&#43;u312/OOWu/6E6a/rOZz3u2EDH18ehJeO&#43;Xdf3zjz&#43;sezPP87G&#43;Wd282Nx2lAtsaMaa85djEV1nWa7X6yjfRMlbSprmR9gNWtFK0Qq9tXacsuOjilYca619&#43;6YbOZ9OKWXrjR9imHtZr/Dr16/rspKnY8sWx3EMfHq68fz3sKJ1QfwH13oEQK317e3t9fVV9&#43;yglJKnnDiZoAYLhkj/&#43;te/lJ&#43;Iuy/36/Xae79er7Y6d/2nUDbSwKHuFBN5GkGm3ppSulwupZTr9bpt27Ku1&#43;vVjGRqtScNJplhyLZtoy36KQR/u93MYWOMp9NpWZYvX74YxK3rOloRSgos2Zj7b9u2rqt57rDie4r69OkTM3/9&#43;tU5V0rx3o/OgrPmkgFszvl0OpVSXl9fTbD7/R5GRWITfvnlFzP5Xz1f2t19NAgUbP8agh40tBnmdO6mUwvYWqsJnVKqyrSreSUzl1LMSBaSNmyT2xi2bSsCxYly2WmKMboB99tW1nU1&#43;Sz4lEQNk1v3TVMu9/v9blbMKY&#43;u6GLQYflcrbgs7TGuAy7O55fz&#43;WQQJCKl6I2MEVh4GfqdTidLaG5s02Q2n621mtaOG1lYW9vVtmZsIoZoQfzBqz/agIimabpcLj&#43;lod57i0fLXefz2TZJRDlni2jlnY8Gcs75crmYc23bdiDsNE0WAQ8XxhDiaJvC4PV49O4PXZvqbdu2yRCC7dxq6uA1TwQf7C7myAbZzrnToEAHpptrx6TsqI0a&#43;6AVSKgl3gPfLP147y8vLyatyaOXwE4QUkoWl/bVHlGYv1tWsNz5UONPcsBoIO4RcJCEZ&#43;2HEM7nl5EA1S98CGk0mY3zEfkQPGr9JWanoYcwz7M5YCnlaOMc3MOQBMYjrfFIAA3rvPfn89lcaZ7nIxsd6REcWNPZIs&#43;B6637EF7OZ8tG5hamF/2sqFWc2OPUPeXO82zE1wxgPquWJrIUbG40z7O5ucnQWjufz7a&#43;8SjzKg3ZAffruqrLK7uFZVmsx2pG&#43;htqhFoUKZSpd1oqN1h/n4E4z1MI3hos&#43;KCYBw58Rx/tfiLZ/M5WOzjSntuFubN5vT2TEefYmu&#43;P5v4zy3o3wINi2tqjmSR2lWHUM6&#43;wosEEexbmwGjrt9pxW/yZ3tijt2MFeTyuQEB7LGqBq/lWVA&#43;n04m0XtSUloYjisj5vP/ERMbt3J7F35PxUeeqAf744w/L4Hrx/nMSa531wyrPVMzw66GO3XFse4dCDUCOPZge398f9OZY0&#43;DVFGQeemjf5tiHcUTfDiJoeLVr5Mlm9jDuuPtBuo4faNhBk/P5LI&#43;&#43;yx5qx&#43;8pnByZ8/BRExXG7wKssYEjgIYYaDBgNPoocZ4DwkiXIsT//vc/Jwq1McZda&#43;Jqq&#43;u6lvF7he/DZzBrAwTjAMH7PE0xJRmZ&#43;VmVh9AGvuZ0e3P4IZNFdM7ZOXe73ZZ1GRFHNv8ICDtyyI1IIXh4PO89KJMBsc2xZGs501DCrLsX6iM4LYYMlGwsy7Ku62Havf&#43;AEEOc8hRiMGhalsWQNudsEWPJxs4&#43;l3IH/z5KV&#43;NU1&#43;tVidbr6&#43;uATzL8tYVut9uff/5pj3Z/NEDOOcZoRMJyV845xMi9N2td/NwAh&#43;sdI4Tw8vJyuVycc1&#43;&#43;fDEKaHn72QAWcwbotqxVWGPb6MfPFCwrvr29HU/hDwZlKKfmN4e13vWgIi8vL0S0LMvb29uyLPf73Qzw3DoemDz/&#43;uuvl8uFiO73&#43;2&#43;//Xa73eypZ87ZZDOXOiD9cHkaaRMBjqK9926/Ovj/AAAA//9FdKlggoKlDAAAAABJRU5ErkJggg=="
     data-sizes="auto"
     width="300" alt="Another contextual menu snippet, now with Deploy Source In Manifest circled."
     loading="lazy" />


</a>

  
  
</figure></p>
<h3 id="what-if-tests-fail-on-trigger-deploy">What if tests fail on trigger deploy?</h3>
<p>While all our tests should always pass all the time, Salesforce admins frequently find that&rsquo;s not actually true in practice. Heck this trigger could be part of that problem in your org. But to deploy a code change we have to run <em>some</em> tests. Since we are disabling this trigger, the trigger code doesn&rsquo;t need to be in tests we just need to run a working test with enough coverage to get the job done. So go find a test class and then we can deploy.</p>
<p>VS Code doesn&rsquo;t currently have a setting to set the testing mode on a deployment, so you&rsquo;ll need to do this last step in VS Code&rsquo;s terminal (available by hitting control-` if you don&rsquo;t have it open already). In the terminal run the following command (replacing [good_tests] with the name of your test class).</p>
<p><code>sfdx force:source:deploy -x manifest/DisableTrigger.xml -l RunSpecifiedTests -r [good_tests]</code></p>
<p>It should deploy pretty quickly, but you can check the status by going to settings in your org and checking the Deployment Status.</p>
]]></content:encoded> </item> <item>
      <title>Project Estimates Tool 2.0</title>
      <link>https://spinningcode.org/2022/01/project-estimates-tool-2-0/</link>
      <pubDate>
        Sun, 23 Jan 2022 20:28:04 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=1814</guid>  <description>Project estimation tool using Monte Carlo simulations and graphs to tell a story that empowers good decisions.</description> <content:encoded><![CDATA[<p>A few years ago I wrote <a href="/2017/06/time-estimation-making-up-numbers-as-we-go-along/">a piece about project time estimation</a> and created an estimating tool. My goal was to get project managers to listen to the fact that estimates were inherently a guess not promise. The tool I created took a series of project tasks, the estimated time range, and a level of estimator confidence. It then ran a Monte Carlo simulation with those tasks, and generated a histogram of possible outcomes.</p>
<p>Five years later I still use it for project estimates. But I have grown tired of its interface weaknesses and needed to add cost estimation to keep it useful. So I recently heavily revised the tool and <a href="/estimates">posted an updated version</a> (the old version is <a href="/estimates/old-version">still available here</a>).</p>
<p>The interface is still very utilitarian ( <a href="https://github.com/acrosman/simple-project-estimates">pull requests welcome</a>), but this version makes it make easier to adjust the tasks. Much more importantly it now also estimates costs, not just time.</p>
<p><a href="/wp-content/uploads/2022/01/TimeProjections.png"><figure>
  <a href="/wp-content/uploads/2022/01/TimeProjections-300x242.png" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    
    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2022/01/TimeProjections-300x242.png" alt="Histogram of time estimations" loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2022/01/TimeProjections-300x242.png 300w"
     data-src="/wp-content/uploads/2022/01/TimeProjections-300x242.png"
     src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAABnCAIAAABHHd2mAAAR2UlEQVR4nOxdiXbbuM7mps1Jc3pm5v2fcKYzTWItJAH8h/wkWnacNFtj5b/B7e24jiLLAAl8WOnu7&#43;9jjEop55wxRmutlKJMOpPKVH4kIlprk8laa4xRX/QGcj9//vzvv/9CCNZal8laG2OcpglMJ6LCdK21iFhrq6rquu7m5qbrui8ZvIXcNE1///33jx8/Yoxa66ZpdrudMWYcRxEhohBCjJGIlFIQQ13Xbdv&#43;&#43;eefeP0lgLeQa9u267q2bcdxhKrBAldKQSTgu1KKmaGUoH8u/eT/T0jfZxqGAZagLGoi4oWwFUQEwoCmaprm27dvXyrojaShXiQT&#43;FuMLd5Z0/qaLyP8LuS893hVAA9IRJhZKQUuw/xiW8AOF1z0RW8h9&#43;&#43;//4YQtNbWWryFpS0i3nvw2jlXVZUxxns/jqPWuuu66&#43;vruq6/ZPBGcj9&#43;/Oj7npnBdBExxrRtW1WVzyQizrmrq6u2bYdhuLu7s9Z&#43;//69aZqqqta66&#43;E2&#43;qJfksN/YAaYGXATrARz8SOYCqggICJcXEyIMaaqKmvtlwxeRA6YByu9CMBaiz3RNA1cYiCftm2LGOCsjePY9z0RtW17c3Oz2&#43;2&#43;BPAicmuYjyWvtWZmGAYwuixw/A1RwUsYhuH29jaEcH193XXdQ&#43;D0RU&#43;Tw4pGLEjrhEqZGQEJCEBrHUKA&#43;a0y1ZmaprHWgulEBJPwtfxfSg7MVUqBg84dAVP4yX3fj&#43;M4DIO19ubmpm3buq4RvKvr&#43;urqqmyRLwG8lJIKCiFA80DRE5H3fpomgP2mabA58Hq323VdV4wtsNMXCno1OcB8Iio&#43;LXjtFoJbAOCP5Q95lFt8Mf0tlFRQCAF6P8bovcc/9UJEhN3QZnLOvfrDTkz0l&#43;SSAIwxBYAWJwAyEBEgH4gHWwSyKew7CRk9jYLKT8sdEM/4X5aEQ2oFvIZCt5mQookxWmsBe4io73uwDBFp7I&#43;yYyBIcLnItYSMSmwVYQ8Ybdjz/&#43;WwUlJBWPghhGmaCsuAQfu&#43;h2yYGegIgAdSaZomhLDf70MI2CjFVYYrx8xAViKCxA4E4FxyAHe73ffv3wGlLs2Hi5FDzKf4tyXSWbIueB8rHa/BQYiq6C78Lpi&#43;DqaulRK2Dt4B7vpy3Nxff/317du3wkFoDzCrhOcK40paBgqkaRqlVNd1CFcUdq//LsajGBi8jz3Utm2Jwr6UZtlp9amVl/bel7RXiUYUAkgt&#43;YCycstyfix1c/QZK9msqeyzlxoASRZFmOF/qFllvur7X5wcYCVWNzAo/DLwC7jzBPi/I73utsziI/lAWYq6srZyxppPKYIDZxFznjLB0kLFr/OUW6D0nMT7MYxTVFoZrZvKXrWVrqzZzEM&#43;nw5eVUEjKIkoyZmLPt4ZYlFTiLf7afDRmrTsp8pao501&#43;hOi2VkABZvXdQ3WI0j3agv5&#43;yg9G/Ho434MWfmrJujOqs4Z21Tqs5nkww6AnimWFihzgwEDWODI4gOJKKNFawlWqLFSWb29FfM0HQRwgn&#43;AiLYG1TNYYB85RI4ZuzmtSGLsY&#43;iqqqn1Z3OqZwGA44BASIGBYA&#43;2QyzKRx7G4CPBbxElTOQn7vvJ7XamcvYzCgCO0jRNwzBM01QcqK3ZAECgKVCMXHZmsgqRBh&#43;bEGuujVafSARHNgBVoSUQXbzijZBk75eYiWc/ZUHQiiSZhNFTR5wg0ecxxUcoCOVAUPoI/mxKAEqEOGv/rH6yRIoTo2KyDRRJGvlMUOjID1jHf0r0Zjs2TUQBgPpID5EBJ/H8KiqyPTqDgtZxzRK83AKJkhB5mGKIeQccrfT0mMyLDGQ7y&#43;YXdIqCpmlCkRYA6KYi9SyKiAMx5QDJmpI4simeQmyibapP4xQfoaBxHO/u7u7v79dVKhvZAcUDiDSv/hNiltHTbe8Tftjppv4cRZJHKKi0x2itwf3thOGSAYg8&#43;OwBnJMAsUQf4/3IIrWzlTPGbuLJn6ZTFGStvbq6wptEtB0/IBmAZIGPPICTSwJxmGJV2UC8iW37DDpCQUXnlGDcpnZAtrH8KPsFjoLweRW1UTrA/MeqS7ZgA8D9SHDB4JP9P6EjGBpjXGfE0Jpx0cebSVSOQCQ/63m6RT6NjA4wFCjo/v4epSgov93tdpd&#43;QlVcMB/mdsKnrsR2yWG6T&#43;ERHy3wdY9GSdBf7tnKU836J9CjBmC5NP2BS8ycRbANA/YEnaIgNODhTTTJXPTx1Kx/eI6A/kIAWQTEyWHOWPVT7YCC/QsK2kowTjJPiSM25S8vF5ljQp9BAkcCWPfmravVL/d4C8kL1CFUFm9Bez6DjlAQAnCo4CxViBf/IrKY1ucgG/gBySPLGUujt54fO0JBaIwZxzHGiLAEig8vS&#43;ApF2TzKyJOeCnZDBJrZePJmaMdULKSRISCuJKfuRRJhjSjj6OPkU6DoA8vV0rzHBalyFyL3Tb/lVuP4KiqarfbofIZ71&#43;88RrcvxvCfgyB5jT8EyTrvE2gtnZm21DUlb6JEgtCv8YWUBBS8MMU&#43;zFMgZ5lV0WJTr&#43;VE2fJFiuzaSzkiAjDgtCvUtqDYYcvG4zLRSi0T9xHDOJ5YYgMW3PgiLcflXNocRnHcbfbFberFKxfFgXlJNecak8r&#43;0W/O2NXpbbtDjiEgIZhqOu6BOMK/L9gYRZCOjGv5V86wA9/N28C2b4/7NaddShFwfA49OxdMBoqSojEhxwBfaFbu9RvxRC5qWTLqbEzCZnC9AsXF&#43;QarAD980ItKEpl601jiF3j7IaRkFvPIgP3gYLQtH1ZDJq10CszQuiigfdQue3Wyh2VpZTyLPzzsuMfZBUBejmYSbuXckCCtm0HXKmHWHfcbQEFSbHAD6qAnvHL6f&#43;cK1niHBrdqBJyYDQEEBcqYrgUCkIEYkIE4lWBTZm1ULIixGLNRkXgihuMaU1AQaVd&#43;1IJGRHlQ3LBxlwG9BrOoWQaQSHizXbwufW4YmRj0CYGjXSpUARn3g0ZR74OjEnWQSHOxbxNZbfZNuDquv727Zsxpus6TCRr27ZMhbuIAOBG&#43;UghMKEJ5lWcE6UCUT&#43;Gfoxt5dDP/f6P&#43;zZyGP2Glhi8KCnJ0iT8wc/Euduin1CG/vqAfhIkST/F/eiv2qqutugOOAynKf8&#43;adX7eBSEhOIUaJhiWBDka9kmCOdBlsyVMZuDo0czCDCTBtMjoIU&#43;PhSBKvPRxym8A4LPaEpld/phS8Em6DQjhgr1MiLrg22AiHji&#43;zHcDT7pH34HluW4kKyw0LYkcMTf9fkM61a9DyMWNfn4cz/d9t4H4vcoMcx17dRPYfDPKSz6aDrtD8BIynJow0fuALhOU0i45XkZ4GfeVsKSVutq5zbWyX2k4ssA7nV5&#43;sc9y9IEmZuQ3m&#43;hLla9n&#43;J1oHpjDsEGCt8WkrkCLtneZ9WfPP/OOToNw87vffM30tEOQJ9eQUFE9GGxIMmRgxBRUPXeHMqRpRyWiCGSy1NuNrIJTlHQfr&#43;/vb0F68u4tw8gFpl8vBt8P8X4Vvh/hpBe7sfYN9FaUzu7kQlbZ8rT4QMDC32MFwbsf9v7f26H&#43;yEk&#43;PPeiB3FQvsxVM5ora67usFGuDSdzorACQxlatAH7ACofnSY3vV&#43;CoT0y3su//w3s4wh3vZLtcRuEzI4RUEYZfthE7PmuH&#43;g/ej3Y5iy9tHvy/7DhykiGaZIycPLQskyuGwf4pEAyoQUrP3fmpJEuBjg5G7w/95PwxRQnpE&#43;8DfEDDLLk1e8rnORtqqyPbiUGE5tQDmX57eWp&#43;dsO/uQlPLd4G/30/1SfPhb4YksiZp&#43;ipId7xCpa1xTuaaySR99uAxOYSj69FAV&#43;jvK02WVbrztZ9aPnnwA/P&#43;IYBmyzf2YNpwP1NXu266&#43;2TVtrWYRfOBmOJ2WEkIYhiGEgNr09y1PB9iH2rndT//dT/sxIGf7wTGa3Pcqfa45RdgjqT2pXT4g0OY/HyOG06mJTdPc3NygUfK9ytOx8VHgE4j2U7zbT//djQvivAQJ9K3yQuhnYlGDp8qZprJd7eoqKSSrtTr877fQGRSEVf8u5ekAs5z9LNR6TpF7H&#43;/GAKWfPvRydUc6r4lkkychkv3onTVt7a67qmuqprJNFoPR8x/1G2aFn6KgMj30deXp6wkHnDnOpXE3Ny9OkXz&#43;g3f074KcLyBRCZ5Okp7KGI2QUVvHq6666uoqjy6vjEFZBfLK&#43;v2e&#43;zThxcf0HGf4oGFWrXQsKjJHEsp8XwZZqTCP3HtFsdtvo2XKR8JFlFeOJECmjbbOREkgNRrGJnDJPJg8LTYJQT&#43;inp4vm1MUhCa9csLwycSsk05FqPX572xgl0betPADc8wzxNI/eeb41jIiBXYtL2ZVSXk4b2TRjAWkwWtrtDMM86C1sotqwk8hSD3rktPPOius0zbVaZp&#43;/vwZY0SRhLGWWKzMdSHLGAalF0C5qJdcTc6qjDeAJCASrQ4B4E1x/zEqXtphfuF8WISQ6Mg5bLMSAHhtoLqzI2mWC8pXhvqyD0pjThu1gf1RKqG1UUqHPKnZZBETpuIpydI&#43;6Pe5hHapZOaDjTs8wfby4U&#43;TrF/plabNwhBa7ECZr631vEB1koqa7bYozmVNNp9zgJ2x5sORCsK4CHRJElGISdhTZC8RgpvZXXbAwvSZxfknWs32QL&#43;unGrbtBKGzE5l5nz5qcqrE6oGrIburXJsR4w&#43;WYenKAiaR0R8CDGJQbLRLGb/MLG2rJDyVg7jzANV85OuF9HzN8C5K89oLjnc&#43;Ln0RIndo4/3xHMvGx5f9WAfzeHLSxl4ZUtM5/iOpyhofTzbPCIsaRQ9i1UdPkhWjzi/yK/06vXhp0uT0axV56b33FOKnTLrrxWH5PC7SZulSw/3KsfSiFbLJlyJROu5wWepq5AZ8hasdu7xpazlQ2nawsDyhXR5glXvyIG3xftZdkpm32wUWcScSOBUACUn4/MA0cgiVinDhzx22X5lp8lhYy775PAhnBkni3QTCqKYVKhio1grjWI1g68DCKFmyKHmBaVz5wKQhiqTmA6tG8JgS77n4bGW5DuyC6SzrJKFnN8R3FzNN9TLO1nSopgixYw4i9o5RImOGa9m26uW59Ar8WK5kOig2ClJtmBVmXGm8K3MsWeKKn15NkcTanP/ba5YmQ21PuyAE&#43;yVFij8CZxaiJ1ktaqtUxXlOISZF7Ni4RBJkvORrJE1KOWcEfdBovO2FiKiyFarpqoabWvjauM4733Yw8P1ChualKjsUNmiNApSKU&#43;&#43;OLziJFoxTo7splZyDF5lPt2L2eSC/myAjwkYSYQjB&#43;HkSazA/RkBwBIkLOScUto6V05FQO/YOI6eozOuq5uctS87YSV5eAMZ105ERps2h/bSJhBFO56Hj&#43;misiRGGsZhmiZnXdvNRxw&#43;dGrATyLOzbWD0fqqbbum0taxNrLeqcutKZdcDv3AzG3XLIeXnfdmRfIE4XFUSjpnuvapg/ITQoyhH4JQrJ1pm&#43;rhiVNS1JawfhBpPWMD8Hn5&#43;ML0ddZnUgjzpGRiouCdVpU1XVM/Fi&#43;aA0rTyMFra6uu65raGnusxpZvIuL9pNlLEGf4unW7XYfK1LMC8CEY8XESY3TbVddX1&#43;74OOkDXFFp0dzfUxiIFXWVublK0n2Mp0TU7/dxyl2LRrV19cRB1cw89KRi5Oh1nfMKdfNwD6h5s/DDLO/5HbCc6qlOYuOcoWpVVS0OiVxOPXxMAGxM5Vw9txyj5&#43;Z8EjbZBueaumJKXki93P3sNwdEaOp617Va66auXVp559cpDGldVV3bMHNTV5Vz1eMXa6WqyrVNurhevuNjAtBKOWfrujJGzxc/Xn66uLNHLH1ZwquYaFQtoozuiWgd8mto9Hj64vWdsf8g3KfvjKb&#43;alFuT6xTXIxBnLj5E9/x5OInHqPMWULoHhe/KHz54ozjenbYc2Kl5fpfXrw&#43;gfI5F0MGpZ1tfUDxWx7jLRe/Ipl2&#43;YlkryNkT3GSbjntEueLPr1mt0abGIz7ChKRcRz/&#43;eef9RnTV1dXf/zxx9O6a2v0WQWwPs4VisgY02TLqS4&#43;5eIl9IlVkPe&#43;7/tSSoyE9m63a5rmE&#43;2AzyqA9VSp8hXWvT2Xfrrn0v8FAAD//6qXQwhrcTI3AAAAAElFTkSuQmCC"
     data-sizes="auto"
     width="300" alt="Histogram of time estimations"
     loading="lazy" />


</a>

  
  
</figure></a></p>
<p><a href="/wp-content/uploads/2022/01/CostProjections.png"><figure>
  <a href="/wp-content/uploads/2022/01/CostProjections-300x239.png" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    
    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2022/01/CostProjections-300x239.png" alt="XY Scatter plot of cost projections, in a nice bell curve shape" loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2022/01/CostProjections-300x239.png 300w"
     data-src="/wp-content/uploads/2022/01/CostProjections-300x239.png"
     src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAABmCAIAAACMQQ4DAAATA0lEQVR4nOxd73Ljtq8lQFKync3O/G7f/wnbD502iW2JJO4Qh4IVR85mN5tYngbT6SaOLNOACBz8ZXh8fNzv96UUN5GI5JxFhJlFiYiYGX9yzjFzCKFX8t4TkfuiX6Xw9PT0119/HY/HlFLOmZXGcYRIcs6lFAgAgnHOdV232&#43;3&#43;T2m73X4J4D0U8IyP43g4HIZh8N53XSciSQmSICIRKaWklIio73sR2e122CjX/gq3TfTw8PD09DQopZSYOcYIdmclsBivQBjQP9&#43;&#43;fbu/v&#43;&#43;6Dtrpi36NKKVUJmovqUoxvuNF&#43;5Um8t6HEPDzVb/CbRNBy59&#43;n7g5F4PR2a8vWc/MX/L4KQrQ/iklwzM8EVQ/mI6fsV3sV/sBFELYbDYxxi8ZvJ3Cfr//888/Hx8fQwjeewggxgjlDktghmG/34/jiHeWUkxIMBW73e6PP/7wStf&#43;XjdDIaW03&#43;8fHh6cc957aPkYY9/3IQQIwHu/3W6Z&#43;agEgwxHwQQAyRlqgr7C3S599pe&#43;qgIIIex2O3MCwBc8wtA2eKJhdbuum5trXF9KwQXMPAzD4XCIMeacx3HEPU1fgfAzZPylr4KxBg81sA1YaewjolLKZrMxPxkvAqemlCDJw&#43;GAC/q&#43;H4bh4eFhHEe4zXM0he1yd3f3v//9Dzjqqhy4MgWwHqyE7Z0D/zzRZrOBbEy3GDeho8xbnr8LjoUZdvwJ3hy20ZcfF8A4WN2u66B8oHDAnePx&#43;PT0hJ&#43;9933fm5BKKTFG7/1ut0NciJlxk77vN5uN2QYTrcU2uq7Dra7NgStTNcKHw2G/34ODXdchAoGHF0of2ma/34N9UFYQABFtNpv7&#43;/u7uzvsAxC2gvluc6fBInpfRripoLkywa/QFeAUAg/4FereuAkmYvfEGM8Yanto/pYvOqOAp36z2YQQuq6DBTbwE2Mcx3Gz2VgQAm&#43;DPmHm7Xb77ds3KJOXLP5i&#43;g&#43;pIn1E4hAT9d4DQZoCgZ9scAgWGKYixgixWeZg7iQvkl0zf/G/HFB6BhBTSkCf4ziCocxsumiOcywe55xDGBV/NdRvvoLdHyy2SIYxHUrsP5vYCeAjHCLsBnDc2GFe2DxBZnmxnPPff/89DAMiE33fd12Xcx6GAZKALEMI&#43;AiTH24LHPX9&#43;/fdbvcfFQD&#43;gScMvpgD3HUdmIIYHCINuAzcBxOfnp4eHx8RI9oppZSOxyOw0/F4LKX0fb/b7eBG4P4ILqWU8Kf/rENQH8y7uztw2aIL0PJQ8WATXjcBQFTb7RbaA&#43;BVROBMlFIgvPkOOEsg4845Z9scv7B6E9rt7h2CBTare4bWTQWZBrdYG2QArGnOgWGhuWmxtP4ZjrKQqm2mt69b8BHSZMB0q4iLwLiXiReLphnGf0tC5ic&#43;eJLTmZv2RqpSF9cWTk4jITcpgeWcIhgNpWTw5iM&#43;/hc1z8R9vYPqH3JtN9CNqaNw9rvF&#43;s88r/WQOFfEZVWYPKFZXaVuBrkxCTwTAOzt8XgEiFxMC1&#43;fTPM4p9yuu4Ec8Y1xvtG5AMZxRKGK9x7xibUJgKg&#43;&#43;GVyt4u4UoRINMHm1rdjf0DnKgjpMIDLM9yyRlIpVGDmHDsn1VDJbeGhZwJANvj&#43;/n632xnovN7alknElWqoquZxXDWPl&#43;LqOr2Qst/dUhjwXADIAYD7o9KqvorABOjPjdMilEYZBomd494xEkpyK87ZuQoy1&#43;mlc7AKUglUhcPU7DCMQE7kPUEqdEuu8WsoyF680tqWSRoSFSntZw6xumEhEPzwVe3ZH9GCAAwFoTRobQKoD32RpAWV1f1iEh/Yax6JuD776pHdihDOVZDV/wAOre5hIgX/ui0LKjOKK8pu70SoMEISetna1r5IP0ZBK/wepD5wcZKKZCmsLM8lB2HPHLy7obDQraEgBaB5ih/mXLForPyvJiFT9ciqY3wjj/9rKMhqT9ZD4P6Y8qh8dxMW8gxvUby6BdBOqoduQAgXUdClFoErUhGXchn1PyIXmKPXEjFyTOrDc9M9iCXeRFzufAegAOvh4QG9YEgcXmltz0gU7qdcNwE554mCPvm5lFQ3hIQqBWEm89HcLXhjC7GgGCPqcFdWOVuf6lxKFvFEMfjgEatyCJ8XeAeKfhiMX8/aL9O5EQ4h3N3doQ/S6jivt7xnBA7nLBwq1tQN4OqDH&#43;v&#43;mJJjRLfjBCzvAKvMRa54PQIA&#43;lRLa1FaYhatu67mocAetAtuYgMsZcTmSbGVGGFkwUQqc1X5ECoF9I9Q&#43;tMeELoN1TPROQpCTRUqFfFijPFKa5uRIA8sTpz31LS/wjR9RtQTbskAh2zqjdjgCyjo8fHRSj/XsANONShaAAG8T2ZoybFTUORKLlKcUBUYnbIDK6YFG4BKKaCglTRQTDVG1QZAxbvz8t4mCbhohJgca3Bu3SI4R0God7NmvDWgICgZ&#43;OUGfl6uiU7XSy71HRUg&#43;bX7w8t&#43;ABpUVxILUvgvConFB7qM8OvOiIFLwxGSXWH26&#43;b/q3VB69D&#43;FfzkUsY8ZacvPBCkAJSIpoyx3EQD1AIKOh6PqKi1F6&#43;0Njdpf9EnwlXb29DP8sXkqEzPj&#43;emrFZOz9pOgYKGYdjv99aldOV9IK3yR4tO&#43;IL&#43;t2urqJLFqN0N&#43;AQBxVhIAqMI1yrLccV1nyJBArKgGPQHF58Wajp09UHpAOD/zz//eO&#43;/f/&#43;&#43;3W43mw1iQWhWvaIAtOiqPtE5l6kmV9i9EmamKTxX8ShrXmbl&#43;eG6A47H47///ouhEdaAN29KvRpJUylVH6oB&#43;MH16hwzUab6xqqKqNC6u5GDhR&#43;seWg9KKgFmBX&#43;B8/Ba8rlskpBHDR4lmrMKnAqQhRWXaoSLPkOdqNdG/I4s8&#43;fTyLN&#43;yXWGOcsAnGJqpPMLggXRaO56qLqDazWJQ42DhHteYChmHtyXRR0CvGTo1Mb&#43;I&#43;5qI&#43;7WMRaddF6FVEwdU9E&#43;L81R85biD6fNKIgYyrOSaig/u2jJUQMB9UN7pjUdq8Sk4Z5CzUsMOaYXBEFIQsB/DOMmdlFj3z7G1dCpIlJ7KFVPvcnap4w&#43;I4ksPUvXm3PCvSPJnsr6OS3aH8jxCQQsk5v8B6uSycBoBIU3etXR0GGfwJzDOz553xaJC&#43;r3CS7qXNvnTshQMtD7cAOY2LEy9mtn0nS8lpUue/5pwvOqzcgdd8U1Al92ELfTQH1P/f39&#43;gIw7iIK8eCyJF&#43;JjNy7Ci2/QkZECo8mAqztIRC1UUrtAchhICBPzYywGJBi6NlPoNgA/RHbkHNn16FGjPyntBktdq4ULARJ/YtN5sNBqhfBQXJlIFJqYjTmP4vdaCimdKjiDpXbyd4dusrnF7olLfBTFeJBdXPLWVI&#43;Zgy6QNyOQfzA0JAukh1Jsi5vvPMfm110ws5dxs9&#43;fnaH9BzTGUYS0rvrc&#43;2904hVS1fXJlBXkhJjuOIIT/XiAW1KGauXoirT&#43;z7IgjaQd8sAYLbgvj0anbBggByzofDAZN8PnkMN3YA5kAEz13gH4egL5M2UzrvORRJyvyUm1z56pmmiZZ7xDabzedPtkVjhZaau&#43;i5i1P986/eEMaNp3aZlCeV5p3z9Ou25bfSggAwpwBlKZ&#43;GgsD9lAvSLyFw9KwRoHexiaYcWStu1EyZZ&#43;HVNG8stCjZdKtPQ0GImiGFkrX/AtD//XOwGhhlrg7lJEo4GTJVj15XEMs9YvMUzUeTTNUMWn2FWZlWe/IbmFNdYk/i6l7S4q5qY7hABdkl7/&#43;cX6QFI4w2McDQj0ZBKLlF42NFihr/RK/vFMR5L2&#43;wCbiZASlSsrb2iVr4CWVdTQLLArBTZWxQ&#43;gdR1Twa&#43;h/GfBjSmAszBWEbSfAbGYMIqzoEzeREz3V3XLV6ccEI4ywe2wEftz9t8MyYyzHl41g/spv5hr/rgy1D4JlKoSIyKCRCrImJC7tr5e2XBYDDFj4IBYlYyXNzjlB4y0yRK/rsFYBO3b&#43;/g9Se173lGZWmuWj9qP6Xqe44tHe4T7cIF1HQB62kpdoFaduKzQd99kuRyvrgT/D/9314K1dhdqF&#43;qTE5zdrXP2kZY2EhL&#43;g6QNPN5wnhk1CQdVgg0lm04ipX7pdhzGMq3lPgyfn6gIgl6zgPNLBqb7do1E9SScgchOCDVr54ntIPnyKGZSOMgei/yxmGukF2tmiwc0wV8KRUBZA0TFM9o4ZYPsokWsmQBOdyHlObeuCcOt5ZYuAYWGGwAw7mjxfCwg4opaBCfX6mzy&#43;Tcb9MkYYhleOQxpQBPYmoix5hn4/O3VJ1yhAD1o57OvX&#43;6doY50Z55hA4tGoumWqNPmRJCwKwBD200FtrcWaOZTNmU3aloR1xWUrOAr2ftI2oGl7Pm873MUT/4YfKkG4EXzcie5YY/OQcVB&#43;wlGqNRFwX/bYLEp01wzJ2w0wt2Xd8J70WjHs7ChLTVFMqca70k2DATAOdor0r4HbwFEOFPV0b3/3hShdMBCJSy0xDKmN9IFokCjCpqIPSxakh1qnL1qaEP/vids&#43;LH/cqLeyAeThoQo2nQQDzy8TNz8cDt5switjr6mqhybQNEyNFmS74qnyilty2xO&#43;bePhe0oh0tbxFKNcHAScilDE1kFaKHMeEybwxAJFJFmI3teFP9znd8oKiblNzLhu25R4xnOeQdViEFw2Q8Qm/m3qxWIHMBmqX&#43;WhzvUbtqk0Sc8UxnibvNeRpowfez9o3kxb81u/EhO1YNAvth/qNpU09aAyxh08dtzLNSngmAME0nbOdQFOhKk/Ti17akuWM2OPjY0oJZbHkA5dCwqd0npzcKPdCALYimRpLSZPjHqsQKZjxQ/PBD1eIzIMnVQwkqDzKUfrsAQ1SLr6pKZpUaX1X3c1ZbGL4FOo&#43;PyqHZvy0Hmae&#43;DCH2csoCGe5EXvHjnMhTSQZTTqpFa9BuDon48RHnlpTWjQYMzT0kuld7jT4/HrRyMn50r5urpIAHNKuNAdAig0Az1HVqchUNkMzJdwYL6dUA3RuQSpUeRI99cHHGdZYTsjc3d1VLVRk1IWkitiKIQC8t7SN2bQQ0zQ6TKxvvTVGTOfrtSgPzW6zgpSUM961DSHiScRPf8CAhOkx90K5NPbbCR54&#43;CAqZbQKbNITsOda5SpM2sY867J6LRZ0HEYZRmoAnWzHgWveZgfr7ZidDdCY2ajT9WaL1sHzZWprfqbIZYbr6uNVWF0HFU4RN9O7bVYIvqJMT1kRCpPW9XTe6PlaLKjVGHtWJNCClGS1rpP6s2DLmTo5fcz5v5dLQ34Xun552zfe8/mxQORO8z7sBghq4Mc51jD/4DQ66tRm0W4NszdfzHIsCIfO5pSdzgcLBklnn2Tb9hLHbHu2PUytQNPw6ItvPv8m5C7f95wuMXeGGd52z9OVKOq65ADbIz9pWpnPqTsJ0VKg1Kbqkw23nmhZADjpv4IxR6zBW1uHzLpwqR2dc2GVDT00Y4ErT4MfXhwb1M7fk9YOcBE8n0TYqj1fQbA2eaF5NpcBebuyAu52Zk5grr7hi8jgFNAtdiKgMlvo&#43;Ref39VqVSdAeFrza9HQIlL9E8Vednc7r7nkTMzBY3reUoVdkVzqTiqoxvGevXeO0HgkZXKdT4c2pYp9RUIMIcTgPb0oCtLCoaL&#43;SVat2o7SWiwf0kxDGsfq03hmve3yAJ75lTquJHQxdl2ILvjn6qsyJ&#43;c0nTxrB5AvHoRUcsWTKdcvpRf6gKiv83b1ggCsWV5HsLEyrukt0ULXYRyG41Dv61zf9dvdVvEyP5sY4ySVnIfheDyk6lVKiHG72Wofjm/zPiee5pwPeTyOhzwMCiBiH7jXoS3P4K9yfxhyOh6TTrOoz2nf932IMTx7ulHkksb9mMp4KDkJsac&#43;dqHrwjOvT5c6jumQkqRjSUmIgut857vAkxtscEhLN9I4HI5jagfUbbfb2G94vmWnRHfK4/Gwt6Pstptt9OedPstGGDVxp/L0acFar&#43;xIipPsigaxPLPbBEYJ2&#43;lrFUxvkyw5lazMqgqoD55C8M89FZcSuUzJi/P1hcjSB9qBrTOdqVszs6R0KMVlceLJdd5tO9918XwBRYZByuCKd1n5F1m2HW822ATPrySRkcQ36xrqAngTvA88sxuqyUoZ6tYe6/cq&#43;i2l17DK8ysdZcGVSeoOQNNDaQ7p646Yu3y&#43;LOsBxNvNJk6xUh/qbn2RwSK7Muj5uK39r&#43;&#43;DP4v6VKtAoV7p9eRW24IxvCyMo0Ju03fkvm01s07MVVfopecLIHExuLtd33dIbIQQ&#43;q4L5yPh65XURXLtSiy17zvvzzJDpDqHN33PUyMXivtfZPAIl/ZdT1P7&#43;zSI6Xwg/Wtn/y7Sy1qVS0Hks5M4aEa/fOXcrs6&#43;Lplmn7/l5W1/uNTpOf&#43;JK19Z6st1LjQDXH0ewS&#43;TwWUcSGkTT1cy5&#43;6NtKyCboLs1DOcpAvFtdvtcPrEtVf3VrphAWCyxTiO&#43;/0eg053u11Uuva6foJuWwCoIbNZy2dHFt8E3bYNgFNmBRx2BuANyeD/AwAA//8hSGUzqMZYlQAAAABJRU5ErkJggg=="
     data-sizes="auto"
     width="300" alt="XY Scatter plot of cost projections, in a nice bell curve shape"
     loading="lazy" />


</a>

  
  
</figure></a></p>
<p>The new version is faster than the previous. And it adjusts the graph type based on the range of possible outcomes.</p>
<p>Each task now includes inputs for min and max time, confidence, and hourly cost of that task. So if different people at different bill rates are part of the project it can still give you useful numbers.</p>
<p>The histograms broke down when faced with too many bars. So I settled on an XY scatter approach to help visualize the broader range that the cost estimator made normal.</p>
<p>Please <a href="/estimates/">give it a try</a>, I&rsquo;m always open to feedback, suggestions, and pull requests.</p>
<h2 id="costs-estimates">Costs Estimates</h2>
<p>For this version I added the ability to include a unit cost for each task. The first tool worked just fine when you were estimating the tasks for one person who had one billing rate (or where hourly costs aren&rsquo;t important). In practice teams need to be to able to do an estimate across all work streams, and different roles will have different billing rates.</p>
<p>This version includes a rate for each task and a graph of projected project costs.</p>
<h2 id="why-i-created-a-project-estimator">Why I Created A Project Estimator</h2>
<p>I wrote the original when I was struggling with project managers who would take any estimate you gave them as a range, pick a number, and promise the client (and themselves) we would hit it. To them an estimate was a promise – one that had to be kept. That lead me to badly overestimate projects so that the lowest end of my range would be a safe number – but that&rsquo;s just a different form of bad estimation.</p>
<p><figure>
  <a href="/wp-content/uploads/2017/06/TimeEstimates-300x250.png" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    
    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2017/06/TimeEstimates-300x250.png" alt="Histogram of time estimates." loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2017/06/TimeEstimates-300x250.png 300w"
     data-src="/wp-content/uploads/2017/06/TimeEstimates-300x250.png"
     src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAABrCAIAAAAw3x3dAAAaHUlEQVR4nORdeXujONLXyWHnmJ6e3n/3&#43;3&#43;y2X1mppP4AHTW&#43;1QJCLEBY8dO0vvW7qRtg4QoSXX8qiQpTxRjFEJwzoGId8QYgxhjBMYZfW//6Qg/A0D/vS8uhADAoumm9HtfhgifB22J1xoGN7y24X&#43;YlLN2t9s1xhL/eQgh&#43;CCkVEhSCOG9Dz6wlg/IWSkFo&#43;9YhGGRGCPH4oL6MiiltM4gBmstXuKCYR/ExGrOuZQyy3SWZQyYsSbVkB4ghFBK5XmeZZmUsu3k91EaAe&#43;/s2/JwtqW1K&#43;c99vt7vllE2MABt4574JUKiMWaK2CD957xgD7JgLyTishBGNMSsk5t9Z45wR1mnPOe5fneVmuovfVfmes41IIqRhjkargXGSZWq/X9/d3nPPdblfXdQgBAATRarV6fHyUUqZJefId2pk6wZR09aDUsMgBW6e4fDjxBzf0X48/nKxfMS6Y1CCk98jfGHkADpHhPwGAR4iAvwDzkUXgHDhNA5HqwgkhZORB0GelJEM&#43;SiE4S5NFBsbTVGmlVSolWjEkJFHf7tSpB3wf/XrwPgf3LBnIJ5/Ss3KqnoMbeum9vH4lpM7KdWECE41mwBmLJPSRMUpyIYBFzqLgXOWlzvKyyMpMaSU4ax8WA47sxM4k96VEMQIxOvcYOjXAWJJCjKaO0ESc8zzPkxJKzUpdkue5Uuq6CuCC2k4WOZ4W55LC0Skk4wxi4JxJpQQDF3xwnkWU9d4HiFEqVZRId3frVa60JI7SE1vF2&#43;nn4aA40M/DYduLlzzPp5Rw//kCBvUyZ34UfzopBsAgDdJWx6KUCJ6hOIrA8F/WTgvUosRvHK&#43;8406M7Qzo5crQHOqflIpRHUDivZVj83QZ9xfe8OnEOVcheIda1PoAjAFzOA8i8BDQXhEkEZJcMsby7Sb6plEo4bG3pFCoXcE5R9YO41yS5kbr1qHqZkJKLRUX3BqDGhrVcMiz7PHxsSzLXpeMtu&#43;4F8&#43;lAz0xesMn1o86AIL3pmqqbVU3JPqVRGPUee&#43;5kFpp6gMBMTbeNdV2J5lE&#43;x2fq7QuiyLPM&#43;esNcY6B8DvUEiVxph9VQGA1tmqLPNMN03TGGuxB/x6VRZEw9cY0kLDcSH7Rus/t5Il9Y/WM1&#43;/4hwEB8migIBVRM&#43;FkJxxSbYLj5JzLTmZnChsOECI&#43;H&#43;0i9Cm5NQ9EGL0zgNj6NehXY8CJ33USuG00DoyLjVeKIo8WTujZt/B7zN0lhQaZdM7WT9a//IWoghCScLRUtdKAkoVqZA1rbvkPfYKGiSMaZwbne3vnLEuhiTUmc4yYEnjtYM3L3KpZF03zloAyLIclS21MzkQeZ4fWM3DN7mW&#43;B4VEberf34qjBZHY9H7YKxt6oYJrpSOZMtr9IQ1Y&#43;jNOmtZMtK1KpVOrKyrpm4a6dDpzTKUVBCjJVHkvX94uNdaG&#43;t8CN47zllRFEKKvn2vsIcQ7EyOJA6eZO6MgB7WMMXBqfpHa7u4fpVQB01cRK2rlBQcYky/J/sHyNAB1oI8aKij&#43;4XGvlSoYJNhSRatIF&#43;CJJNUeZZBWaI7jT6B4&#43;G1TYCGFE4yjTpbnSUNZmTUjHgZdaqXF5/5cb6dM/WTIyYEjeGcDHm0QxPTe7AhyzSKGolsTs5RQn6yLCO7U7DIgvOcca0yYBwi9LaNVgryPMaw3&#43;29c8kNU0rFGJzFr3lePDw8rNYrJeW5kuGkBXLxzR9ZvwJAOwjNGGeThI5ptDJelEWeFwxYug4QhVXO&#43;bwopBQA0VkbQrTSMliVRc6FQGlmjGgMY&#43;xuvWLkNpDCsMYa7BspiqIAgLquvAvOh5zMISBjd2rmHgvu15nUFVkoK2agpKn6Rxszw9MDmq9fpU9JriRnDI2ZGAnqFForKSQJGeYdqlPyy0AIFB14J3guUIcrrbmUZOXjH&#43;9Q&#43;hd5nheof2MMjEALLnie5wmrsNYqpVvwZxqiGf3xAvEyf2kKbnq/IJqvX7EBHC&#43;FRHsmRzbhNSVjiGjvK63WMsbSexfR&#43;gyce6n03Z2y1gSP/7POZVl2f3&#43;f51nTmKQ4iqJYrVe9vk2AD2oO6qrkP&#43;ssk/K0S/wpdGtfGs1QFEEBTZ26rqVUK87zPFNKGWOrqo5xz4XIs3y1KvOi4IZVVV3XjVR6vV6XRQ4xNHW1r1xtzP39/XpVZloHHxprI0SpZIHySo7O5V5u/n8IvEyRSva&#43;Vtopx1uERqJOpuiK8x69BJQY6B9ENJd8bMMmdKuSyXySOK4FMBYorpBpvSpXnaI&#43;g78XaLOz6Nb1n0sqDUu0IaWUEvvDOwcQk2hOkH6e58h9At1QIpGFKvEXFPdS6UJi/2Q6k0LYEAXn&#43;aq8f7jP8yJZRMPXnrK157GHmfBIf8NJtl4cybodoQ5ImIF3PkYgF5iChynWGLyUClWuwjutdU3TxOhZUTBC930IpG69DDhvkjQXQmRo3mvOGfXZgQnBjhk1xJ8v8OnPgi6&#43;VDcoTmGsLMuQLxSP5cgi/M9x7snmSXiDkgp9Ahz1Agc8&#43;WJAvoK1Jr09uggUGAgh1nVNPnDLVgrBM&#43;xjzpJUip3&#43;l0KgH0jy6rMZcgU6y6FRaUC0wXIs1mZBpFEsOA/eB&#43;&#43;NNVHrhEcQ4M&#43;dc5rpnMLnVcVTOL7eWx&#43;DlMrv9/vdTqA1xVAbo52qAF0Kzzk5cZxZ5wJaWSzPs4eHx/v7hyzLEgx1UwbdWsGcRYoiheBDtNahRS9FMuRTaoIiyRMBXTMyJMF7H2JgsQ02lVopwhJSxMZ5hwpFixijtYbmEgsxCi50phgw54MQCbtgTdM4Hzg6z7EsV0CzjbGvoh4vprM6WCml1nfrCMwYA5RpkqYAWT46fU2hMiklRHRrgYAK0tkyL4rWrveeM54cLq2z1AExBs5F4moSQZT6gE4cZ1CWK&#43;cDY5BlWVmWPUCd9ET7h7HbT4mr0SUOmu&#43;IEkNIPULSAWCtdc5lWhP2IJN6TEFF/ppdhdT/mCpNWVltvlCf4NXxM9mlfZCSIpQpDamNwpMtm0IOwCmCr8SkIXuVkNYMqjqVe3Jcwxu2LgaoVWuxoHx/U5FzbrfbPT09ffv27f4BpfPUO4ym3CwXiAepHMj9ALX1e4NaRXF&#43;V6hVroW4Ajy5vPgULnLu407eT4Pu6K6EHOx2u7/&#43;&#43;ktr/f379wuyE85tK6kY5kNsXHip7PPeGOtzwfhdnnGmc/01JdE7W6WmLiQRVFWVpZDWe56xkNDw9XFv3LZ2L5V9qaw1toz&#43;3lYlj1zcqQytsg9oyUfSXAcM6dbtAEC5Xxn3c2teKls7bxwqJt1UTeO3grM8X1Pw53&#43;sCyY7INGHOY3AwPqwqd3T3uwaF1MqbwRw3oWmrowyLityof/XYLsTHfBhFCMYH3eN2zfO&#43;Yi2awrhA8QQjfO8dqpwQvDsq86CUUvkJH2JDiBvGYwLtfXWo2UqYYAdMXA&#43;&#43;saJympFCau/jmdwkr4E9pJYXFvf2BDiiNCLgAJqb/obvhCadkxnjQ7x6dBgQugaF3aNMz5lfI1QiDhFKutoinx8M0/TZZGlE/L0I6Y6gA/QWJQ/yP/R0Y0yijUubCtUEtPd9OvRCRF06/cESnQ0LuyNM45g2IkHJsRwZ9y2oUTij&#43;L/SSv8nZa66qqIw4lNbxsSOnRrQvOfgAfrR&#43;X/mzuNDfvGm1UsM&#43;DXSDB8f5pijxH10b2D7Lz5&#43;tugfNM0xpiEnaXeMMZUVeW9u90koMUHzIXYON8Q&#43;&#43;efBMBsRF1tA44WeQ3s&#43;iqBtgO&#43;n5X8ix3gnNttN0/PLylaEkMMhOw/P7/cFofAnk7WZ0DVetq8aeWVdSHEqKQ8N6l0rAlXS9SdSUKdKSVei3deT48bp0E6zBE7kHfHsm9eGh6VxeFfGb8nsR4nuN93SwuSeyxi/bgePtm2k8H969IiNFRrdX9/r7MsrRVNF1AkoVxqjuO0S5IPlrxYgFb9ov0zrX75QNBEYNaHCjV2WGVKyMnKZxpwo1Vjl1WrKANXFaXIKWWzv1BV1T/r1XCp4nEK5gXg&#43;OsIZczT8N81Hu2fxdGDQPZoY70vKa3x6BEzTz&#43;rtR9DLX8lJSe/uUCBxnPDEctvaOWP9TUFXmaG/wF1Xpu/L4OW4usgQ5e1QwzLf2SWIM0A9L/IpJkc/nD0FRhzHh2CvfFuynH7dUgtX1VznNQ3tHxHZdRUHiB0LpiPc87XRDNaWKK23nmdKQHTbZ9PRJzHL5egmyeX552sXy1s60zVB6n082Hr9hJZIyFeiOqkqL31wYW0qH&#43;YTTASlF4yyKby94dXZ&#43;o5N3Oyv18s3xvmYBeEqYIzYe4&#43;6QHlTwSXUh9mHjlNETsgNja40CZxHLTw3DUES7TdsZ81SqMB/an6rxYPOCMunyJdEVyS/ud3QYqVGRd2xpW51EqoU8kNZzV75tIUH6cmx8n6PyEekASIC9FHuBhYJocArdjKeOc/H5&#43;&#43;2H75nIBMANZx/1LWkQ6vWxTvson0JUiN&#43;u7dxhrxuMCkYbPYZkgBSNIEl/OMgDxwpAasDyFKcejJvGnMzG4F88vwRhcxTK0BPrk2&#43;Lj&#43;Fo4OIa2qi112NBAOYYbgxKhtMFRNBysXp3gXafBeqn3fUECnzNfWrwulxHjSUJ95d3KN9cJF2DNhkuPfT9ZPHUA7oWx3e9M0MaQNTaJz7uVlc4CGzmuYJRovpb8F&#43;vvOHkhV1TbsGvdQZrmGdjnn9NOnflwO41ymtGfqVykmHkKwxqQlFTGgceict86OSqH3UJI8kaTQ&#43;33Y12C9C&#43;uoJb8wQPCJmGhrhgohUgo0JekjpbxE0zRXb1wkV/YqShM1AeEZlfEPZaDdRL4GMLSYUkQseu85Y&#43;WqzLvNIpumeX5&#43;fnl5vmIHJIcpAFxFBLE2WE8OQeNql&#43;Vafh1sbiEJAPDe7Xe77XbjnEsLY/I811ofo6HvIehcsBAhXM9o7KM6lfGWsLmbmqMnw03nvhn6ARQTrqv93jt/O1iUJwQCfeCzMaCZu7u0Ir9rXJOCxbekq8cbaBFvhED741Lv3WoCQwdk&#43;nYGXI1TkYGl0ILxlMfxeR7ZJYlZrRVEG45d3eZ5QyT9PXXAe1zg0Zohgg/RxaRafiWfWKRVcMmkOxubP4ewm5P8OV8BnBxU0BpXbU7BL9QDaWclJtJe5jeDVAh&#43;YGn4X8UDGHkEA4K4Y/iYJSVXItGP/UiLGmF6fL7vpaBHIG7EmtTBlkBWgJtnVV6retHuFRECLRKei3G/xyiCDoO7aW55JB3jQkwplTf1B65lIopkxgEDqbSivQn6GXzdMfTWQr9yJ6QOpi3eKdD264igtF0h00rTBBC0UagFAGOM9/4q0jSNff8OBHRhMegmgY&#43;gBfslcImUGaeLsoxVXVcV0BbQIURrzXa7JTT0vbZprx79RRDQWQV6VR8A5tIlDh5xaofnixMjTtbfdUCe7/fVZrPZ7bYQKTnX&#43;c1mY&#43;17s6N7yeBvqYGHFIHUgBSKzqhZmG6z8OoMK2d2PZipHztAKVWuyrWxtMdDJMSGCeFQJUxv0rCY4I3/dT6dhTHDQBUrMilO1/82UHVukOOd9be5oavVWkqVhH66zyA174ejgZJw/Y3tn&#43;MnughZBJX22V9c9oIsirP4c3xzu2dwlmVKvYkP13VdluXoOSLLU7g665MCADfGKd88F4VedJGryOXXXtT6umnzMA09bSFzkJi&#43;cJvzN91DEq31vy7Ofzh/5qTELxOiFDznXzpMoxYmNCQaTQ&#43;dy&#43;hDJ4OFFiO7kAsXxBkBO567AFaAEmeYQ&#43;&#43;hy9YHvBnjJ1MTj9PtTj4yMvAQr5IDcRb12F8Lz31Vx&#43;y8o6Iu0FFJAcTD0cEXypWLxy3qHoa2kBXJHLo1NvHu9QG3IOiSR7r02UtquJiG8NzNY5WX0g3XByRMKbRnSDLas68v&#43;xHMICnEbIg2pJNwEuxy&#43;EaJPmt9wBvLZ7mlcpDHOPwwrCTlgF43AHkWJSfc&#43;GhJGcx4paNJfwdfZ8LuJ/e3mqpfHaQwzuCg84sADsYCdFnQ78Hg3k9AVoCL0QauaPdewV53Tp5ZczGaynjydMmDqpbU3yZmHfReWj5/kBi68KndqycEIvo&#43;BeKzTPEOi7V0Dgun0xZH11Ac0MesD3hdoOG9JwiaVqHH2DQNbVXgL8Mv20UA3RqYo1YstYLeT68LcgIoEQU/Wtp6DVo4OY6p7YC0OcTz09O&#43;2ltjXQjOuZ8/n9IGEmc3hyZSpwDY2H7pH&#43;4WkE8gPK3JEnTW0w1cs6kDbWbo1QqinZ&#43;9aYyl8wad8877gy1U&#43;s9TSfftnW0OegydD/SJM6BvEq2jQXNI6lYQLS8&#43;/75vHnRmMFF1D2CZ1nd3d0rKtHKLti22gbbvWN7QrhFtaPAT1e8BpahciCA4U5JLAoguo3OP9J6n3goSWZ4/CLFer9OFpmm22812u03H0y5HYiOpXxu7JWBfpQtatWR8zGTU3cEqZ/XCvOq&#43;TKb1MwAF4/BsZToIVYuJZSdTBOw1/hW&#43;2MqtdlVTZMZHnbQxGzvM42Pp1QoaYm3D/dHPqw9aCAzlz9cZ/ImgW&#43;EdwNBBN5kUqQ8&#43;sRPUknj0QurT31yAU9vqfaprBmBDTGZAJjltefNpnaCWA9lT6/&#43;6SdOmv1EoKn7crnpnUCdd085bjDJhQeSSTnmli1MRp4XHBhw4BMcnJx5Xct4xpnPE29Uvrjvu&#43;bOl6yS1RxThNG0nasGEHFN2Sxzm0fuHX&#43;fLnrFVwUkrCHr5c3r0f7Qf8IaAAafteiPrG5szoQRPcbslzD6Jhi0hzvl5AZkpSrh/4j6BP8D5whdZWv816LDXU66qSfoAQFMqkRAX7k39LjN0IY0v&#43;m4dfWhCaELw4&#43;DPl6P0Km34nsXIQFMaixZCp7Opz2Tq8mSRIY13wAEyOgNn94a/CaH20YZe/fKpIFh68cHfwbBsv/c9CENOvSrRN4EdeG0Uewt8tGV4Fw6CQfFXd4fyiBh48BwobhMzKZQQFMgE0c3khXw9y25Mh/qPVJHOdHa0aKk96NB7doSftMcdkVXXUOCJdu&#43;h123hlnZFquBt3kukJK10dJx3IZ0Sl7ZIYF0eI5OcgcBmtFd9DPQBRKBl/BxE4ACC0&#43;nFOOM4E8Hz4LyXHGJ3Ih09Gj9RipynZUz42lIwwQmZYBEvsvg6brnkTAmeOkAL/rorHW8P1FqSpTG0DEcnRQsJjs6AdHrMbrer68pau9ls/vvf/&#43;Z53leaAksp4EeYM/I9IT9t/g&#43;dGiY6uygCCDqvEF&#43;VfknlrQ2bvanSZtzto/E/KdAmAQbRurraOVdHa01jGiaMiz5GJURGYELa9gaNOSlMqX2dF7nq0ikh4T909h9&#43;TxYaY6CFkJQ26tFXhNRU1nlqnLCXdN6i4tgByUDCXxjeKfpjL9kbjf36sZsxw9E67AMpZVEU6/U6y7LxDnDONXWdgOg///zz77//FkKkIUqLaNCCjt3KLAJ/2rncz5D2bKY0A2hTxHbxB&#43;ftOjo6MKluvBnsGZ1&#43;T28baQPr3JlVcFAUrigdcDKxUFAoWpIdCF8DOp8y02JV6ExLKcVrVA6AE9c442mBOL4/sThADPSCKPDHUmDTId&#43;C&#43;N5LZU4jSaYyb6fFW&#43;a34i1lBB7sLpbn&#43;Y8fP/7973///vvv6lh1pBOGy7L88ccPxvh//vPn09NTio6FEIxFihGU1lmWCXXYhdB6NG0TvPdNY7x3QogsyzKdkdvDkxECIcoAYiCRY4jeOwLDHY5Npa2WHBzYKBjXAIo8DEFSA&#43;UQna5onbUx1IJnWVbkudJqIAQ6j4QSVdKHEHzTNNa6lJZJhzZOrkrnhNVba&#43;mk8KCkynN8FVrI3nJ8WLTfg9jSSfohUJGiyLKErfGyLIuiSBuh8D7eMvRv8ZWMsc5X1f75&#43;Xm/3ydl0DTNy8vLdrsNMd7d3X/79ltZlP0WJUd2J479uq6fnp53&#43;72U8oEoz7PBs972XQTn7H6/e9ls9/sqy/Lvv//&#43;cH&#43;ntGItKAtvLXVIx7a&#43;vLxU&#43;30EWK9X3779vlqVw7xK3m7D/Br5qKrq58&#43;fu91OCHF///Dt229FUfRFelECXYc577abzc&#43;fT8baPM8fHh4eX19kxOLGDjNms9lsXl6wSFF8wxe5V3QMtlLq8fHxx48fd3d3bQccu8jQbWrfnXLYcfP5efP8HCI8PDx8//4dX3U6xhdCqPbVP//8s91upVK/ERVF3p7yPHjbPunAmma73fzEPquKovzXv/71&#43;PCgtRoI1S7vtBWJcb/fJ26GEO/v7/7444/1ep3G2tuXaguFGHe73d9//b3ZbqQQj7/99v3376nPRtwrKumcfX5&#43;&#43;fuvv42xeZH3LzLl6&#43;JgretnImtMUa6&#43;//HH4&#43;OjpqnZnmKewOa0Zf0EA98YVck0SluooPtelKtVmWqZKp5m7n63N8YIJVdlOZVx3T4Lxb43TVPVjbVWU4yIxuZ4/CSNEnzEfk8zmuV5lpTbcauGSLsxZoetaoQQZblarVZaq6kXaXf4r&#43;vdfh98UFqV3YvMZAQ52m6maZoQgtbZ6m5dFIU86uPxfaSm2hE7Sqr85HnxqUh/qqckmk9y6p&#43;SkKz&#43;KVNFEnfQSiZKx7yONmyIkR20asmL9Gki7bn7Qs6c89o3LB0oPmzVwZ0nZsAxg46hwXPR7IMA3nxK2nz9SULSPlMe&#43;5aYkoRskrZLctZmnnKQ6HdQIsmnk&#43;NpBpVr0dBzY/lLQL7&#43;zqlqZ&#43;Kow3ee790kTJ6fnquq6vbXYUrr9Xq9Wq/19Aql0UEw/7gx9h22Z3jzwbtP7eus0tg5fuF5bO8y4GnU5L2gnsNqydxy1nnhOAGaKCvaePTk8B&#43;Fmo8R/GOeLAnBw0Tu10iEYL/fH&#43;zNdPyAGaExM0kPNnycqXN0a8iDO4852FvMdV1ba1vkhzOlNFn2WT&#43;w5ut/Z1rDaJ7E8vr/LwAA//&#43;lAV0gTveDkQAAAABJRU5ErkJggg=="
     data-sizes="auto"
     width="300" alt="Histogram of time estimates."
     loading="lazy" />


</a>

  
  
</figure>This graph from the original version helped convince PMs that estimates weren&rsquo;t promises.</p>
<p>I had a good amount of experience providing estimates, and had read a lot on the topic. I knew there were teams that did better and I wanted to help our team improve.</p>
<p>The original tool was loosely inspired by one <a href="https://www.joelonsoftware.com/2007/10/26/evidence-based-scheduling/">Joel Spolsky described ten years earlier</a>. He has several important ideas on his process regardless of your project methodology. But his idea of using Monte Carlo simulations had stuck with me since that article had been new. After failing to find a tool that included it, I wrote my own.</p>
<h2 id="are-the-project-estimates-any-good">Are the Project Estimates Any Good?</h2>
<p>Fundamentally the simulations are only as good as the estimates provided. For any project I have been able to compare my simulated project estimates to final hours my work fell within one standard deviation of the median.</p>
<p>The confidence measure helps more than I expected. Originally, I added the measure of confidence because I needed something to determine how often the simulator should assume people are just plain wrong – and by how much. While I could have hard coded a solution I did not know how to pick good values. I knew that my confidence varies by the task. I also knew the less confident I am the more I am likely to be wildly off. So decide to make confidence an estimator provided variable, and use that to pick the size of overruns.</p>
<p>For every 10% you reduce the confidence, the simulation will allow the upper bound of the estimate to increase by the size or the entered upper bound. On a task you estimate at 7-10 hours, a 90% confident estimate will allow overruns up to 20 hours (just in the 10% of times that aren&rsquo;t in the 7-10 range), and 30 hours for an 80% estimate.</p>
<p>That extra box also immediately helped me feel comfortable with my estimates. Knowing that the simulator would offset <a href="https://en.wikipedia.org/wiki/Optimism_bias">optimism bias</a> for me I could stop trying to do that myself. My estimates can use tighter ranges trusting the software to offset expected bias.</p>
<h3 id="a-value-of-the-graphs-in-project-estimates">A Value of the Graphs in Project Estimates</h3>
<p>The graph has turned out to be the most important feature. Initially I included it because I wanted to play with D3 and have something more impressive than numbers to show. What I discovered was a reminder of the importance of data visualizations – even simple ones.</p>
<p>As I said before I created this tool when working with project managers who simplified all estimate ranges to a single number and held everyone to that number. The first time I presented numbers from the simulator those project managers picked the median and complained I made it too hard. The median <em>was</em> better than what we had before, but not enough to treat as a promise.</p>
<p>When I started presenting the graph those same people immediately started to change how they talked about the project. By visualizing the impact of uncertainty over several tasks they could see that the project might run far over my estimate – or far under. The more uncertainty, the longer the tail on the graph.</p>
<p>Suddenly they were comfortable talking about risks from overruns, finding ways to help clients understand the possible risks, and being understanding when a task proved harder than expected.</p>
<p>The graphs tell the story, and empowers the team to have an honest and productive about project estimates.</p>
<p><a href="/estimates/">Estimate your own project timeline.</a></p>
]]></content:encoded> </item> <item>
      <title>Announcing Two New Snowfakery Faker Providers</title>
      <link>https://spinningcode.org/2021/12/announcing-two-new-snowfakery-faker-providers/</link>
      <pubDate>
        Sat, 04 Dec 2021 20:09:43 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=1779</guid>  <description>This week I helped create two new faker providers for Snowfakery: Faker Nonprofit and Faker EDU</description> <content:encoded><![CDATA[<p>For the last two years I&rsquo;ve been fortunate to serve as a leader of the <a href="https://github.com/SFDO-Community-Sprints/DataGenerationToolkit">Salesforce Open Source Commons Data Generation Toolkit project</a>. That project has produced and inspired a variety of efforts, including <a href="https://github.com/SFDO-Tooling/Snowfakery">Snowfakery</a> and a <a href="https://github.com/SFDO-Community-Sprints/Snowfakery-Recipe-Templates">collection of starter recipes</a>.</p>
<p>This week, along with my colleague <a href="https://github.com/allisonletts">Allison Letts</a>, Salesforce&rsquo;s <a href="https://www.linkedin.com/in/paulprescod/">Paul Prescod</a> (the creator of Snowfakery), and our fellow project contributor <a href="https://GitHub.com/eehjunggnujhee">Jung Mun</a>, I helped create two new faker providers for Snowfakery:</p>
<ul>
<li><a href="https://pypi.org/project/faker-nonprofit/">Faker Nonprofit</a></li>
<li><a href="https://pypi.org/project/faker-edu/">Faker EDU</a></li>
</ul>
<h2 id="what-these-faker-providers-do">What These Faker Providers do</h2>
<p>The use of Snowfakery is growing. The more we use it, the more we want the data tailored to specific projects. And the more we find places where the <a href="https://faker.readthedocs.io/en/master/">Faker project&rsquo;s</a> providers do not have quite what we want. In particular the project does not (well did not) have providers for nonprofits and education specific data.</p>
<p>The Nonprofit provider currently just provides organization names:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ snowfakery snowfakery_nonprofit_example.recipe.yml --target-count <span style="color:#ae81ff">10</span> nonprofit
</span></span><span style="display:flex;"><span>nonprofit<span style="color:#f92672">(</span>id<span style="color:#f92672">=</span>1, nonprofit_name<span style="color:#f92672">=</span>Eastern Animal Asscociation<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>nonprofit<span style="color:#f92672">(</span>id<span style="color:#f92672">=</span>2, nonprofit_name<span style="color:#f92672">=</span>1st Animal Foundation<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>nonprofit<span style="color:#f92672">(</span>id<span style="color:#f92672">=</span>3, nonprofit_name<span style="color:#f92672">=</span>Upper Peace Alliance<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>nonprofit<span style="color:#f92672">(</span>id<span style="color:#f92672">=</span>4, nonprofit_name<span style="color:#f92672">=</span>Southern Peace Home<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>nonprofit<span style="color:#f92672">(</span>id<span style="color:#f92672">=</span>5, nonprofit_name<span style="color:#f92672">=</span>Unity Home<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>nonprofit<span style="color:#f92672">(</span>id<span style="color:#f92672">=</span>6, nonprofit_name<span style="color:#f92672">=</span>Western Peace Home<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>nonprofit<span style="color:#f92672">(</span>id<span style="color:#f92672">=</span>7, nonprofit_name<span style="color:#f92672">=</span>Upper History Foundation<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>nonprofit<span style="color:#f92672">(</span>id<span style="color:#f92672">=</span>8, nonprofit_name<span style="color:#f92672">=</span>Upper Friends Committee<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>nonprofit<span style="color:#f92672">(</span>id<span style="color:#f92672">=</span>9, nonprofit_name<span style="color:#f92672">=</span>Eastern Pets Center<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>nonprofit<span style="color:#f92672">(</span>id<span style="color:#f92672">=</span>10, nonprofit_name<span style="color:#f92672">=</span>Northern Animal Foundation<span style="color:#f92672">)</span>
</span></span></code></pre></div><p>For the Education provider we have a bit more. You can generate college names, departments, and faculty titles.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ snowfakery snowfakery_edu_example.recipe.yml
</span></span><span style="display:flex;"><span>Account<span style="color:#f92672">(</span>id<span style="color:#f92672">=</span>1, Name<span style="color:#f92672">=</span>South Carolina University<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>Contact<span style="color:#f92672">(</span>id<span style="color:#f92672">=</span>1, FirstName<span style="color:#f92672">=</span>Roberto, LastName<span style="color:#f92672">=</span>Stanton, Title<span style="color:#f92672">=</span>Associate Professor of Microbiology &amp; Immunology<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>Account<span style="color:#f92672">(</span>id<span style="color:#f92672">=</span>2, Name<span style="color:#f92672">=</span>French<span style="color:#f92672">)</span>
</span></span></code></pre></div><p>The providers can of course run as a standard faker community provider. Once you are <a href="https://faker.readthedocs.io/en/master/#basic-usage">setup with Faker</a> just add the new providers with pip:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>pip install faker-edu faker-nonprofit
</span></span></code></pre></div><p>Then you can use the libraries in your code:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> faker <span style="color:#f92672">import</span> Faker
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> faker_edu
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>fake <span style="color:#f92672">=</span> Faker()
</span></span><span style="display:flex;"><span>fake<span style="color:#f92672">.</span>add_provider(faker_edu<span style="color:#f92672">.</span>Provider)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> _ <span style="color:#f92672">in</span> range(<span style="color:#ae81ff">10</span>):
</span></span><span style="display:flex;"><span>    print(fake<span style="color:#f92672">.</span>institution_name())
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> faker <span style="color:#f92672">import</span> Faker
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> faker_nonprofit
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>fake <span style="color:#f92672">=</span> Faker()
</span></span><span style="display:flex;"><span>fake<span style="color:#f92672">.</span>add_provider(faker_nonprofit<span style="color:#f92672">.</span>Provider)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> _ <span style="color:#f92672">in</span> range(<span style="color:#ae81ff">10</span>):
</span></span><span style="display:flex;"><span>    print(fake<span style="color:#f92672">.</span>nonprofit_name())
</span></span></code></pre></div><h2 id="how-we-got-here">How we got here</h2>
<p>A few months ago I posted on how to <a href="/2021/05/snowfakery-custom-plugins-part-1/">extend Faker to create nonprofit organization names</a>. Allison took that as a starting point to create <a href="https://github.com/allisonletts/faker_highered">a similar project</a> to generate names of colleges, departments, and academic titles (and a <a href="https://github.com/allisonletts/faker_phone_NorthAmericanNumberingPlan">greatly improved phone number generator</a> but that&rsquo;s not included since it&rsquo;s more general). Both of these projects were good proof-of-concept but were rough around the edges. So this week, with Paul&rsquo;s guidance and Jung&rsquo;s input, we contributed the more polished versions to the community.</p>
<p>During a virtual working session on Wednesday we restructured the projects, cleaned up code, added sample recipes for Snowfakery, and published them to PyPi. By publishing these as Faker providers on PyPi, and not as Snowfakery plugins, they are available to a wider audience. By having them owned by a larger open source community we are expecting them to enjoy long-term support.</p>
<p>Both are still just getting started. For example the nonprofit one still just generates organization names, but would benefit from job titles, program names, and more. The EDU provider right now just handles colleges, but is expected to generate other education related data in the future. We also have a plan for a third provider to help improve the diversity of the names generated by Faker to make our fake data more representative of real communities.</p>
<p>The Data Generation Toolkit project has been a great example of what happens when you bring people from a wide variety of backgrounds together to solve technical problems. Like the larger Data Generation Toolkit team Paul, Allison, Jung, and I all have different backgrounds, skills, and experiences. By coming together we are able to help each other find better solutions than any one of us would have found on our own.</p>
<p>It&rsquo;s been an exciting week, and I&rsquo;m looking forward to more to come.</p>
]]></content:encoded> </item> <item>
      <title>Build Cycles of Respect</title>
      <link>https://spinningcode.org/2021/10/build-cycles-of-respect/</link>
      <pubDate>
        Mon, 01 Nov 2021 02:46:42 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=1756</guid>  <description>Build developers should build cycles of respect with their colleagues.</description> <content:encoded><![CDATA[<p>In consulting we should expected developers to do all the same basic things as everyone else on the team. That includes supporting a culture of mutual respect with other team members.</p>
<p>We should explain our work clearly, be effective in meetings, and take feedback well. In consulting especially, we should engage with clients professionally, effectively, and happily. We should not be isolated off on our own teams working from specs we didn&rsquo;t write, for clients we haven&rsquo;t met. Basically, we need to be good team members and we can be expected to be that way. Developers, like most everyone else, do their best when when surrounded by people who treat them with respect.</p>
<p>One of the things I really like about my current job is that we have a respectful culture. It’s not that we don’t have disagreements, at times energetic ones, but we work through those challenges as a team of experts with differing perspectives. We are all expected to be experts who can collaborate with other experts, and to explain our work to clients.</p>
<h2 id="cycles-of-disrespect">Cycles of Disrespect</h2>
<p>But that hasn’t been the consistent norm since I shifted to consulting. I have been on teams, and seen teams, that routinely insult the basic professional behavior of developers and other technologists. In those settings leaders made it clear that the standard of behavior was lower for developers than other team members. Most people I know end up adjusting their behavior to meet the standards set for them. Set a low standard of behavior get bad behavior.</p>
<p>I want to be clear that I have no intention justifying the harassment, bullying, and assault that is too common among developers (and more generally by men in the workplace) – that is not the challenge I&rsquo;m addressing here ( <a href="/2017/10/we-can-do-better/">although I&rsquo;ve addressed those issues before)</a>. There are behavioral problems in places that don’t permit and cover up that kind of behavior. Developers and other IT specialists are often still allowed to act as a grumpy trouble maker, or aloof superior jerk. We are told our brains work differently somehow allowing us and our colleagues to ignore healthy social conventions. And by allowing it, stating that we expect it, and taking no actions to correct it, we encourage that behavior.</p>
<h3 id="signs-of-trouble">Signs of Trouble</h3>
<p>On more than one occasion, at more than one employer, I’ve been told things like:</p>
<ul>
<li>“You’re talking techie now, I’m not listening anymore.”</li>
<li>“Developers hate meetings and never contribute productively.”</li>
<li>“You just have a thin skin and act defensive of your work when questioned.”</li>
</ul>
<p>Often the person will laugh as they say these things like we have some kind of shared inside joke about some basic lack of professionalism. There are lots of reasons why people dismiss developers with those kind of statements, but that doesn&rsquo;t stop them from being destructive.</p>
<p>When that’s your work environment, it’s tempting for developers to degrade to match expectations. Who takes feedback well when told upfront they have a thin skin? Who likes being in meetings with project managers who explicitly state their contributions aren’t welcome? What expert thinks it&rsquo;s funny when you stop them and say you are not listening?</p>
<p>This builds a cycle of disrespect between developers and their colleagues, dividing teams and impeding progress. When people are treated with disrespect while still performing critical tasks, I expect to see them act with disrespect is exchange. That is no okay, but it very human.</p>
<h2 id="breaking-the-cycle">Breaking the Cycle</h2>
<p>Respect is a two way street which makes it important to break the cycle on both sides. Everyone on a project needs to respect the roles we each have and the contribution we each bring. Those may be, and usually should be, vastly different across the team – otherwise there is no point to having a team at all.</p>
<p>As team members who are often in a position of some power – in part because we are hard to replace in the current job market – developers should take it upon ourselves to be the first to build respectful practices with colleagues.</p>
<p>We can, nicely, point out when we hear statements that feel isolating and rude. We need to try to understand why someone acts intimidated by the technical detail and find ways to help them along. Developers should make a point of soliciting feedback from team members and processing ideas with them. Everyone ought to build personal relationships across our teams to help improve everyone&rsquo;s ability to work through hard problems (there is <a href="https://scholar.google.com/scholar_lookup?title=The%20strength%20of%20weak%20ties&amp;journal=Am.%20J.%20Sociol.&amp;volume=78&amp;pages=1360-1380&amp;publication_year=1973&amp;author=Granovetter%2CM">a bunch</a> <a href="https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.900.9076&amp;rep=rep1&amp;type=pdf">of research</a> <a href="https://scholar.google.com/scholar_lookup?title=Knowledge%20transfer%3A%20a%20basis%20for%20competitive%20advantage%20in%20firms&amp;journal=Organ.%20Behav.%20Hum.%20Dec.%20Process.&amp;volume=82&amp;pages=150-169&amp;publication_year=2000&amp;author=Argote%2CL&amp;author=Ingram%2CP">on this question</a>).</p>
<h2 id="creating-a-cycle-of-respect">Creating a Cycle of Respect</h2>
<p>To build an ongoing cycle of respect take more than just breaking the old patterns. Developers are often in a position of leading by example and so that is a great first step. Asking friends and colleagues to make an effort with you will help build a re-enforcing cycle in a small group, which makes a great second step.</p>
<p>Understand that cultural change of an organization is hard, but usually it is possible on project teams. So it may help to start with just one team and making a real effort to improve communication and collaboration with the team. From there build out and try to draw others into your new patterns.</p>
<p>When teams work together well, understanding the project as a whole, they do better work. That puts everyone in a position to add ideas, raise concerns, validate suggestions, and adjust to changes.  When teams allow any member to work in isolation they losing the shared vision and project failure.</p>
]]></content:encoded> </item> <item>
      <title>Being Nice vs Being Kind</title>
      <link>https://spinningcode.org/2021/09/being-nice-vs-being-kind/</link>
      <pubDate>
        Sun, 26 Sep 2021 14:49:16 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=1748</guid>  <description>Giving kind feedback is better than being nice. Make sure you tell the truth when giving reviews.</description> <content:encoded><![CDATA[<p>A few years ago during a job interview at a nonprofit organization, the Executive Director asked me about the culture of the job I was leaving. He had noticed that I was stressing the importance of good feedback during my interviews and wanted to know why it was so important to me. Indeed, part of why I was job hunting was the job I had rejected the notion of mistakes – everyone’s work was always good. I told him that, and that I do my best work when I get honest feedback. He responded by drawing a distinction between being nice and being kind. He was sure everyone I worked with was quite nice, but they didn’t sound very kind to him.</p>
<p>Being nice when giving feedback just means saying positive things.
Being kind when giving feedback requires helping another person understand how to improve.</p>
<p>It was one of those moments in life where someone offers you words to explain a struggle you’re having and suddenly things make more sense. I knew I was unhappy in the job, but his insight brought into focus the reasons I wasn’t fitting in. Being told my work was great did not mesh with my understanding that it’s <a href="/2016/07/always-make-new-mistakes/">important to admit we all make mistakes</a> and find ways to avoid repeating them. My desire to examine my own work caused conflict, let alone my efforts to introduce peer feedback.</p>
<p>The CEO at that job once told me that if people heard their work wasn’t perfect, they wouldn’t want to come in the next day. He didn’t seem to realize that getting dishonest feedback causes the same thing. And seeing no chance for improvement was even worse. There was no room to revisit problems that lead to near failure and ongoing technical debt for the client. Instead they convinced clients the technical debt was a feature, and used it to sell support contracts.</p>
<p>All the feedback my colleagues and I got was nice to hear (“This is great.”, “The client will be thrilled”). But unrelenting positive feedback didn’t help us improve as individuals or as a team. Our leadership gave team members a false sense of success and held the company back from improving.</p>
<p>The thing about being kind, is that sometimes you have to tell people things they don’t want to hear. That can be hard, and to do it well requires you to care about the other person. If want people to like everything you say, it will be hard to be kind.</p>
<p>Giving nice feedback involves offering a string of hollow platitudes that leaves people with a false sense of achievement. That makes people vulnerable to failure when they move forward without understanding their weak foundation. Giving kind feedback requires you to provide an honest assessment of a person&rsquo;s work and helping them recognize errors. Kindness requires listening to people when they push back, and finding ways to help them find ways to excel as they move forward.</p>
<p>When all was said and done the opportunity wasn’t the right fit for me. Turning down their job offer was probably the hardest career decision I ever made. But they and I left good enough impressions with one another that I recently started serving as an volunteer advisor to the program I would have been running. That service has allowed me to reaffirm my sense that it was the right decision not to take the role both for me and for the organization.  And it has given me a chance to help give them some kind feedback to help – I hope – improve their operations. I try to be as kind to them as an organization as they were to me as an applicant.</p>
]]></content:encoded> </item> <item>
      <title>Why and How to Write Good How-To Articles</title>
      <link>https://spinningcode.org/2021/02/why-and-how-to-write-good-how-to-articles/</link>
      <pubDate>
        Sat, 27 Feb 2021 22:54:10 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=1596</guid>  <description>Writing how-to articles and sharing instructions is one of the best ways to help the community</description> <content:encoded><![CDATA[<p>Part of contributing to any open source project, or even really being a contributing member of any community, is sharing what you know. That can come in many forms. While many projects over emphasis code, and most of us understand the value of conference talks, good how-to articles are some of the most critical contributions for any software platform. There isn&rsquo;t much point to a tool if people cannot figure out how to use it.</p>
<h2 id="why-do-i-write-how-to-articles">Why do I write how-to articles</h2>
<p>I’ve <a href="https://www.drupal.org/u/acrosman/issue-credits">contributed code</a> to Drupal, some of it even good and useful to others. But usually when I hear someone noticed something I created it’s blog posts about how to solve a problem.</p>
<p>When I struggled to find the answer to a question I expect it is a candidate for a how-to post. I am not so creative that I am often solving a problem no one has, or will want to, solve for another project. And I am good enough at what I do to know that if I struggled to find an answer it was probably harder to find than it could been.</p>
<p>That helps me find topics for articles that are helpful to the community and benefit me.</p>
<h3 id="how-to-articles-help-others-in-the-community-use-tools-better">How-to articles help others in the community use tools better</h3>
<p>The goal of a good tutorial is to help accelerate another person&rsquo;s learning process. The solution does not have to be perfect, and I know most people will have to adapt the answer to their project. I write them when I struggled to find a complete answer in one place, and so I&rsquo;m hoping to provide one place that gives the reader enough to succeed.</p>
<p>Usually I combine practical experience earned after digging through several references at various levels of technical detail – including things like other people’s blog posts, API documentation, and even slogging through other people&rsquo;s code. I then write one, hopefully coherent, reference to save others that digging extra reading.</p>
<p>The less time people spend researching how to do something, the more time they have to do interesting work. Better yet, it can mean more time using the tools for their actual purpose.</p>
<h3 id="how-to-articles-serve-as-documentation-for-me-colleagues-and-even-clients">How-to articles serve as documentation for me, colleagues, and even clients</h3>
<p>The best articles serve as high level documentation I can refer back to later to help me repeat a solution instead of recreating it from scratch. When I <a href="/2016/11/lessons-learned-from-my-first-drupal-8-projects/">first wrote how-to articles</a> I was solidifying my own learning, and leaving a trail for later.</p>
<p>They also came to serve as <a href="/2017/01/drupal-8-plugins-are-addictive/">documentation for colleagues</a>. When I don’t have time to sit with them to talk through a solution, or know the person prefers reading, I can provide the link to get them off and running. Colleagues have given me feedback about clarity, typos, and errors to help me improve the writing.</p>
<p>I have even sent posts to clients to help explain how some part of their solution was, or will be, implemented. That additional documentation of their project can help them extend and maintain their own projects.</p>
<h3 id="how-to-articles-give-me-practice-explaining-things">How-To articles give me practice explaining things</h3>
<p>One of the reasons I started blogging in the first place was to keep my writing skills sharpened. How-to articles in-particular tend to be good at helping me refine my process in specific areas. The mere act of writing them gives me practice at explaining technology and that practice pays off in trainings and future articles. If you compare my work on <a href="/category/drupal/">Drupal</a>, <a href="/category/salesforce/">Salesforce</a>, and <a href="/tags/electron/">Electron</a> you can see the clarity improve with experience.</p>
<h3 id="how-to-articles-give-me-work-samples-to-share">How-To articles give me work samples to share</h3>
<p>When I’ve been in job applicant mode those articles give me material to share with prospective employers. In addition to <a href="https://github.com/acrosman/">Github</a> and <a href="https://drupal.org/u/acrosman">Drupal.org</a>, the how-to articles can help a hiring manager understand how I work. They show how explain things to others, how I engage in the community, and serve as samples of my writing.</p>
<h3 id="how-to-articles-help-me-control-my-public-reputation">How-To articles help me control my public reputation</h3>
<p>I maintain a blog, in part, to help make sure that I have control over my public reputation. To do that I need inbound links the help maintain page rank and other similar basic SEO games.</p>
<p>From traffic statistics I know the most popular pages on this site are technical how-to articles. From personal anecdotes I know a few of my articles have become <a href="/2019/01/drupal-8-batch-services/">canonical</a> <a href="/2017/05/cached-json-responses-in-drupal-8/">descriptions</a> of how to solve the problems.</p>
<p>When I first started my current job we had a client ask if I could implement a specific feature that he’d read about in a post on <a href="https://drupal.org/planet">Planet Drupal</a>. <a href="/2017/06/controlling-block-visibility-with-a-custom-field-in-drupal-8/">It turned out to be mine</a>. Not only was I happy to agree to his request, it helped him trust our advice. My new colleagues better understood what this Drupal guy brought to the Salesforce team. Besides let’s be honest it’s fun when people cite your own work back at you.</p>
<h2 id="writing-your-own">Writing your own</h2>
<p>You don’t have to maintain a whole blog to write useful how-to articles. Drupal, like most large open source projects, maintains <a href="https://www.drupal.org/documentation">public wiki-style documentation</a>. <a href="https://pages.github.com/">Github pages</a> allow anyone to freely publish simple articles and there are many <a href="https://sfdo-community-sprints.github.io/DataGenerationToolkit/DataGenGuide">examples of single-page articles out there</a>. And of course there is no shortage of dedicated how-to sites that will also accept content.</p>
<p>The actual writing process isn’t that hard, but often people leave out steps, so I’ll share my process. This is similar to my general advice for <a href="/2017/05/writing-good-directions/">writing instructions</a>.</p>
<h3 id="pick-your-audience">Pick your audience</h3>
<p>It&rsquo;ll be used more widely than whoever you think of, but have an audience in mind. Use that to help target a skill set. I often like to think of myself before I started whatever project inspired the article. The higher your skill set the more you should adjust down, but it&rsquo;s hard to adjust too far, so be careful is aiming for people with far less experience than you have – make sure you have a reviewer with less experience check your work. Me − 1 is fine, Me − 5 is really hard to do well.</p>
<h3 id="start-from-the-beginning-and-go-carefully-step-by-step">Start from the beginning and go carefully step by step</h3>
<p>Start with no code, no setup, nothing. Then walk forward through the project one step at a time writing out each step. If you gloss over a detail because you assume your audience knows about it add reference links. You can have a copy of a reference project open but do not use it directly; it&rsquo;s there to prevent you from having to re-research everything.</p>
<h3 id="list-your-assumptions-as-you-go">List your assumptions as you go</h3>
<p>Anything that you need to have in place but don’t want to describe (like installing Drupal into a local environment, creating a basic module, installing Node, etc) state as an explicit assumption so your reader starts in the same place as you do. Provide links for any assumptions which are likely hard for your expected audience to complete. This is your first check point – if there are no good references to share, start from where that article you cannot find should start (or consider writing that article too).</p>
<h3 id="provide-detailed-examples">Provide detailed examples</h3>
<p>Insert code samples, screenshots, or short videos as you progress. Depending on what you are doing in your article the exact details of what works best will vary. Copy and paste as little reference code as possible. This helps you avoid accidentally copying details that may be revealing of a specific project&rsquo;s details.</p>
<p>If you look at mine you’ll see a lot of places where I include comments in sample code that say things like <a href="https://gist.github.com/acrosman/945d29162d3ba0e0101333638dd88295#file-jsoncontroller-php">“Do useful stuff”</a>. That is usually a hint that whoever inspired the article had interesting, and perhaps proprietary, ideas in that section of code (or at least I worried they would think it was interesting). I also try to add quick little asides in the code samples to help people pay attention.</p>
<h3 id="test-as-you-go">Test as you go</h3>
<p>Make sure your directions work without that reference project you’re not sharing. This is both so your directions work properly and further insulation against accidentally sharing information you ought not share.</p>
<h3 id="end-with-a-full-example"><em>End</em> with a full example</h3>
<p>If you end up with a bunch of code that you’ve introduced piecemeal, provide a complete project repo or gist at the end. You’ll see some of my articles <a href="/2020/11/generate-sample-data-for-salesforce-npsp/">end in all the code being displayed from a gist</a>, and <a href="/2021/01/salesforce-lightning-web-components-with-url-parameters/">others link to a full repository</a>. Far too many people simply copy and paste code from samples and then either use it blindly or get stuck. Moving it to the end helps get people to at least scan the actual directions along the way.</p>
<h3 id="give-credit-where-credit-is-due">Give credit where credit is due</h3>
<p>If you found partial answers in several places during your initial work, thank those people with links to their articles. Everyone who publishes online likes a little link-love and if the article was helpful to you it may be helpful to others. Give them a slight boost.</p>
]]></content:encoded> </item> <item>
      <title>Salesforce Lightning Web Components with URL Parameters</title>
      <link>https://spinningcode.org/2021/01/salesforce-lightning-web-components-with-url-parameters/</link>
      <pubDate>
        Sun, 31 Jan 2021 19:37:04 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=1579</guid>  <description>A security change invalidated nearly all tutorials on LWC URL parameters. This one fixes that.</description> <content:encoded><![CDATA[<p>A couple weeks ago I needed to create a Salesforce Lightning Web Component (LWC) that pulls values from URL parameters. While the process is very simple it turns out the vast majority of examples on the web are out of date due to a security update Salesforce made sometime last year – and so I spent a frustrating afternoon throwing ideas at the wall until a colleague stumbled into a comment on a blog post that was an incorrect example by a highly trusted expert noting the needed fix.  So, in the hopes of shortening the search for anyone else trying to get this to work, I’m offering an example that works – at least as of this writing.</p>
<p>To be fair the <a href="https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.use_navigate_add_params_url">official docs are correct</a> but it is easy to look passed an important detail: <em>if you do not put a namespace on your value the parameter will be deleted.</em></p>
<p>That change was the security update, before that you could have any value as your parameter name now you have to have __ (two underscores) in the name.  Officially the docs say that in the left side of those underscores you should have the namespace of your package or a “c” for unpackaged code. As far as I can tell at least in sandboxes and trailhead orgs you can have anything you want as long as there are characters before and after the __ (which kinda makes sense since package developers need to be able to write and test their JavaScript before they build their package).</p>
<p>So your final URLs will look something like:
<code>https://orgname.my.salesforce.com/lightning/r/Contact/0034x000009Xy5gAAC/view?c__myUrlParameter=12345</code></p>
<h2 id="basic-lwc">Basic LWC</h2>
<p>Now with that main tip out of the way on to a full example.</p>
<p>My assumption going into this is that you know how to create a very basic Hello World quality LWC. If not, start with the <a href="https://trailhead.salesforce.com/content/learn/projects/quick-start-lightning-web-components/create-a-hello-world-lightning-web-component">Trailhead Hello World example project</a>.</p>
<ol>
<li>
<p>Create a new component to work with, mine will be very simple to help keep the details clean, but you can fold this into more interesting code bases.</p>
</li>
<li>
<p>Update the component’s meta.xml file to set <code>isExposed</code> to true, and at least a target of <code>lighning__RecordPage</code> (although any target will do if you know how to use it), and configure the target to connect to <code>Contact</code> (although again any settings you know how to use are fine here).</p>
</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#75715e">&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34; ?&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;LightningComponentBundle</span> <span style="color:#a6e22e">xmlns=</span><span style="color:#e6db74">&#34;http://soap.sforce.com/2006/04/metadata&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>   <span style="color:#f92672">&lt;apiVersion&gt;</span>50.0<span style="color:#f92672">&lt;/apiVersion&gt;</span>
</span></span><span style="display:flex;"><span>   <span style="color:#f92672">&lt;isExposed&gt;</span>true<span style="color:#f92672">&lt;/isExposed&gt;</span>
</span></span><span style="display:flex;"><span>   <span style="color:#f92672">&lt;description&gt;</span>Example Lightning Web Componant to read URL parameters.<span style="color:#f92672">&lt;/description&gt;</span>
</span></span><span style="display:flex;"><span>   <span style="color:#f92672">&lt;targets&gt;</span>
</span></span><span style="display:flex;"><span>       <span style="color:#f92672">&lt;target&gt;</span>lightning__RecordPage<span style="color:#f92672">&lt;/target&gt;</span>
</span></span><span style="display:flex;"><span>   <span style="color:#f92672">&lt;/targets&gt;</span>
</span></span><span style="display:flex;"><span>   <span style="color:#f92672">&lt;targetConfigs&gt;</span>
</span></span><span style="display:flex;"><span>       <span style="color:#f92672">&lt;targetConfig</span> <span style="color:#a6e22e">targets=</span><span style="color:#e6db74">&#34;lightning__RecordPage&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>           <span style="color:#f92672">&lt;objects&gt;</span>
</span></span><span style="display:flex;"><span>               <span style="color:#75715e">&lt;!-- This is setup to run on contact but you could use any sObject--&gt;</span>
</span></span><span style="display:flex;"><span>               <span style="color:#f92672">&lt;object&gt;</span>Contact<span style="color:#f92672">&lt;/object&gt;</span>
</span></span><span style="display:flex;"><span>           <span style="color:#f92672">&lt;/objects&gt;</span>
</span></span><span style="display:flex;"><span>       <span style="color:#f92672">&lt;/targetConfig&gt;</span>
</span></span><span style="display:flex;"><span>   <span style="color:#f92672">&lt;/targetConfigs&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;/LightningComponentBundle&gt;</span>
</span></span></code></pre></div><ol start="3">
<li>In your JS file beyond the main <code>LighningElement</code> you need to add imports for <code>wire</code>, <code>track</code>, and <code>CurrentPageReference</code> from the navigation library:</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-js" data-lang="js"><span style="display:flex;"><span><span style="color:#66d9ef">import</span> { <span style="color:#a6e22e">LightningElement</span>, <span style="color:#a6e22e">wire</span>, <span style="color:#a6e22e">track</span> } <span style="color:#a6e22e">from</span> <span style="color:#e6db74">&#34;lwc&#34;</span>;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">import</span> { <span style="color:#a6e22e">CurrentPageReference</span> } <span style="color:#a6e22e">from</span> <span style="color:#e6db74">&#34;lightning/navigation&#34;</span>;
</span></span></code></pre></div><ol start="4">
<li>Add a tracked value you want to display inside the main class:</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-js" data-lang="js"><span style="display:flex;"><span><span style="color:#66d9ef">export</span> <span style="color:#66d9ef">default</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Parameter_reader</span> <span style="color:#66d9ef">extends</span> <span style="color:#a6e22e">LightningElement</span> {
</span></span><span style="display:flex;"><span>  <span style="color:#960050;background-color:#1e0010">@</span><span style="color:#a6e22e">track</span> <span style="color:#a6e22e">displayValue</span>;
</span></span></code></pre></div><ol start="5">
<li>Next use the wire decorator to connect CurrentPageReference’s <code>getStateParameters</code> to your own code to get an use the URL parameters:</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-js" data-lang="js"><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">@</span><span style="color:#a6e22e">wire</span>(<span style="color:#a6e22e">CurrentPageReference</span>)
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">getStateParameters</span>(<span style="color:#a6e22e">currentPageReference</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">currentPageReference</span>) {
</span></span><span style="display:flex;"><span>   <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">urlValue</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">currentPageReference</span>.<span style="color:#a6e22e">state</span>.<span style="color:#a6e22e">c__myUrlParameter</span>;
</span></span><span style="display:flex;"><span>   <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">urlValue</span>) {
</span></span><span style="display:flex;"><span>     <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">displayValue</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">`URL Value was: </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">urlValue</span><span style="color:#e6db74">}</span><span style="color:#e6db74">`</span>;
</span></span><span style="display:flex;"><span>   } <span style="color:#66d9ef">else</span> {
</span></span><span style="display:flex;"><span>     <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">displayValue</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">`URL Value was not set`</span>;
</span></span><span style="display:flex;"><span>   }
</span></span><span style="display:flex;"><span> }
</span></span></code></pre></div><p>From the code sample above you can see that we’re getting the values from currentPageReferences’s state child object, and then attaching them to our tracked value we created in step four.</p>
<ol start="6">
<li>Update the HTML file to display your value ideally leveraging the SLDS along the way:</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#f92672">&lt;template&gt;</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&lt;div&gt;</span>
</span></span><span style="display:flex;"><span>   <span style="color:#f92672">&lt;lightning-card</span> <span style="color:#a6e22e">title=</span><span style="color:#e6db74">&#34;Url Sample&#34;</span> <span style="color:#a6e22e">icon-name=</span><span style="color:#e6db74">&#34;custom:custom14&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>     <span style="color:#f92672">&lt;div</span> <span style="color:#a6e22e">class=</span><span style="color:#e6db74">&#34;slds-m-around_medium&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>       <span style="color:#f92672">&lt;p&gt;</span>{displayValue}<span style="color:#f92672">&lt;/p&gt;</span>
</span></span><span style="display:flex;"><span>     <span style="color:#f92672">&lt;/div&gt;</span>
</span></span><span style="display:flex;"><span>   <span style="color:#f92672">&lt;/lightning-card&gt;</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&lt;/div&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;/template&gt;</span>
</span></span></code></pre></div><ol start="7">
<li>
<p>Deploy all this code to your org.</p>
</li>
<li>
<p>Go to a contact record, and edit the page. Add your new competent to the side bar. Save and activate the page.</p>
</li>
<li>
<p>Return to the record page, the component should appear and say &ldquo;URL Value was not set&rdquo;.</p>
</li>
<li>
<p>In the address bar add to the end of the url: <code>?c__myUrlParameter=Hello</code>, and reload the page, the component should now read &ldquo;URL Value was Hello&rdquo;.</p>
</li>
</ol>
<p><figure>
  <a href="/wp-content/uploads/2021/01/Screen-Shot-2021-01-31-at-12.48.47-PM.png" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    
    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2021/01/Screen-Shot-2021-01-31-at-12.48.47-PM.png" alt="A screenshot of the sample component displaying the provided text of &amp;ldquo;hello&amp;rdquo;." loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2021/01/Screen-Shot-2021-01-31-at-12.48.47-PM.png 526w"
     data-src="/wp-content/uploads/2021/01/Screen-Shot-2021-01-31-at-12.48.47-PM.png"
     src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAAA/CAIAAACnwFc8AAANe0lEQVR4nOxc6XLbSJKurAsnT8luu2NievcJdt//MTZifu2f/eHpkNeSzBNHnROoBCCQAmXJbVnSmF9EtymgqpCVmZUnSO69J2e8HOhLE/CrgzvnXpqGXxq8qmpCIHx&#43;2BbB2MVvmi949EjyODL6kT/Wch49&#43;v6fj2TO/WEPr0z4/99uH7Ob&#43;094JA&#43;eJIGXwlP5PTr98fo4HMY/fdm1kz0J/thDg/ZKOw0eIquZ2K/ajSRwR9ZwYjfYHxMWxvfPHd7Hi7iKJx5IIM93D4RuTdKucEDPIaXDpw33CGPHe7j98UgFxs3CyP6O9jIA35Rhvx7p9t02YPhUgPFn&#43;S6E8u2OYTD&#43;bquDzYP33vmeewd7aWZ1THGDHbS3whLed/rRjCHD6&#43;G50Mn4G7oIhNBu8kBzun11mwI4aRZh1CYEan3LmxOPPmQm98CcO2AK4J6HbEORHD0xTPGkE9qAjOGW7uYhXRBmjZEHBGg30JGhAFoZ&#43;P4EhKv46P764JnfjqwDkYD7wrnucA6uTAD8GDMBDkUyopwtk1vNuOcEenBPwAM5Pk9hx81evSedbuIAf2fIPJIfuIq3PBzRCQNN6e2Yh5Zlh4oKnV3w3YIHOwwiwBHDYd36nvSnYdyikN42Ds9qa45IS3pvu2Cg4/6A4QcaBaeik8PRzchjDUGV8nz0tA5OfatuFGDAxvbxrQ6So1sw&#43;A8/HJ4nQMVod&#43;yHAmjo9PTekW/NDkBQKKCBH7TVUTwxd2bzpP3pz/7heYWja4O7/s4Q3VnXfiN0sKnD2QM290sNb/RCBOCCgbXeHvocSgmnQGlLHwzl3q/Y&#43;To/IJd05mtUZ2DoB4/W6hQ4LAvDQw&#43;dzwzsuFvcH/gA6ETb3jpgyqH2HFgDOLaZfsD&#43;oXLcLeV7co/P8V30EcjsbReQE16UEL7IRFHbUjnjPG6JAggGWcRiSQWncF9tevL8AesJGeVur3r&#43;UDXGvfrJWLpjLhyxanh9jJgjkvyDdLaO6sTc3vQNlfy&#43;8GCw5YFaj5sq/nGZ3G5ru1FWoRkFRkki6WIi5nkkOwmMRMqPD5Xvu&#43;jjyIEQcip2PJr54Oe/ArhH2ygNRzg9GA6dCrm/2QA&#43;n8TK2E2haw3OExpOgOQ0T8Qsj1sBnPFs4JxRziilcBe8E0&#43;BiHCdM3rq7JzxQ8AxeDi2MIBBxZiZHuZfg&#43;t9ujo&#43;7YwT4KRzK34skj&#43;C9V47VzmrnXP37B8DkJRGlAmgZ8P1SPD2X99lB6eHOu8Laz7X5VVVbowy/jgZlJTORfR7nF7KKGbsdKXkjDvwu4/fYpfx/kbV/7O&#43;/cf2642qjXdH&#43;bOk9GOc/vdsKaZLQSnvk9ROVAAw/Hz/lnMOqz2tU3oKhuWgN4QgAOiqTn5QBjqEb&#43;yP&#43;6rr/91v/rFdrbXyxDNCBQUK4Lw3IRdaazUX8u9JvhCSd8UQrbW1lgXYAMYY59x7b4xp0nHeuCKtdVVVxhghRBzHQoihHzpMze5IxOvOOWttsxRjlLE3JAk&#43;cu1EbOsIqazdGlUg1yjNGJ8JmTCunF1rtbemsGarde2s75Ija&#43;12u93tdnmep2m63&#43;93u12WZWmaGmOKonDO5XnOOV&#43;tVtdfvmhjJpPJxcVFmqa0w/BwIHMppch37OjhUt77JEmklADAGMO5z83Bv4g7AQwrCkcV&#43;f6GJ955EjO2lHLKZc7FpYznUhJPPtfl/xVbFZxznx&#43;ijq9Wq89XV&#43;9/&#43;41Sent7e3V1NZlM0jRVShX7PeP8w4cPQoirq6t/fvrEOMcjstvtrLVSCBlFxpi6rq21SIgQIkkSQkhZlkopRikB2O/3ztosy1g4T2maTqfTKIpeuQy6KKgPgw6rTvfBAKZc/D3Jf09SAU3Mk3EeMzYVQnt3VZX00Jk458qiWK/X&#43;WQym06Lori5vl6tVm1FBSDLssViQSlVSlVVxTlXdb3dboui2Gw2nLE8z2ulyrLUAYyxNEmm06nzfr1eW2O4EIJzG6wQo9Q6B4TMF4s//vjj8vLyLQigQ1v7fjgUDa0MSemEi4zxiDJPiA7VdI7R573ZjYew1hijjdFa10qZ/V5pnWdZnCRoxKWU8/l8tVptNpvrm5uyanB7e2uCRSLe48nYbjZxkhhj9vt9cyyUak6S1lVZAgAelJBe8qqq5gHoYH48534QWgH4A8v/UG3Feb835p9VAQAfomQpI9tER9VXra5VpTrrP0Sjg96XQaPLoqAAjHMJkOe5lJIHYy2EmEwm79&#43;/N8bc3t6uVqvWQ1hLgz1pxBDOU57njNLdblfXNQDEcWyMUVpTAG3Mbr8HQtI0dW/kfadjJ/xNqh3xO6uL0tTOVtautFLOXtXljar3RkvKjhI0xljjcLOsrKrrL1/qup7OZpxza8x0NmOMAYAQIjTJPGMsjmMppVKqYW4UUcYm0&#43;lkMlkulwDAOc8Cc51zWmuldV3XgvPZbCaEsNYmSWKtzdL03bt3jahCRPSacSiAQVV3vGcY4lXjfO2MI01WnDBeWvNVq8IaT/xSRHBYPeecLxaLv2m9Wa&#43;NtfPFIs9zIYQxJo5jDDSzLOMd0D8DgFLKGCOlzPM8juM8zwFgOp1KKZ1zUghCyHq95pwvl8ssz6Mo8t7XdV1VFaV0Pp&#43;jAF6z/RnxAV1Xb7RNRgSlKeMJY9q72tpbUjOjtHMqxIiMQsxYyngoRbSzKKUNIzifz&#43;fWWs55kiSUUudcn22hmUZpXVxcYARpjMHxUkrMG0gIanEuhjeT6XQ&#43;n19eXqIIMVpVSuGANDzoJzHye3EvD/D3/t&#43;BAcyE/CPNN0bdqtqG7hQ2EfG4YCb8tySbcEH7t0mCxc&#43;yLAn&#43;tg/hh0AxMMZQi1EYaJSgwwGNwVgJzpXWaN96T&#43;s7YBLwytX/CYkYhCDnUkb/NVvOhVxphaWI4QBJ2aWM/yPN50Kywc6Rg99UxseM6RHHMao8Jtivn9GnMCaAE6AAEy7&#43;M528k3HtmsR/eBcIMICEsYyLmLLnroZi4NQ&#43;&#43;s1y/2kCgMYK0Yw1XHYnTkmjxUDoT6mDvmm&#43;93iCAO5Y/MA7eWc8Ea89SPi3x1kAL4yzAF4YZwG8MJ7mhPvkaJjy9JF&#43;/2F4vZ97lFv9RbpHl2pfrDsk6ZXjCQLA7ooxBjMmY4wK8N6LAACQUnLOsVKG6SiyCXMl7EdizWfYa&#43;xFd/&#43;t9Z6bRxLVWhtjsESB6ZvvKnRaa6xvD5uar1YYTxCAc64oit1uJ4RgjO33&#43;/V6vd/vifdxkmBqulgsJpOJtXazXld1jckqpTSKIsYYVspC7aAt3Xjvsc/FOWeMIROH3xvEuyjI4bDdbrfZbKSUWZZJKXEdrXVRFNvtFgBmsxk2NRljWE16nTJ4ggCstfv9/vr6GivGt7e3nz9/3u12nDERGodxHDPG0jS11m53u5vrawi6iXqKBc66rqfT6Ww2k1LiGarrusmxp9M0TZGDWE1D3mmlrHM8dGM4Y/lkkiQJo3S9Wn369IlSOpvN4iRpdF8pY21Zluv1mhByeXmJbcs4jhfzeT6ZvM7OzGMFgApojCnL0jlnjNlut&#43;v1ervdNtyXMqprrXVZltZatBjb3a6qKuI9DbpvQjeRAJRl2YiNc/xQFIUU4uPvv797964syz///HO9XmPBOY7jqq61UkJKa20Sx799&#43;HBxcZEmSVlVq9VKG7Ner4HSsiyN1jwczbIskdS21p2mzWrhCL5hASDpaAr2&#43;30Z4IPJMFpLISB4hSIgTVM8DfvdDkvcm&#43;1WKZUGS1WEfiEQsi&#43;K/W6HFc35YmGtrev65ubm5vraeR9JGcdxWVVa6yRJgJAqjtMsm06nPtSZZRTx0MlZBRBC8ixLswx1RSllg5MAgKosjTHPzMnvxFOKcZTGcZym6Wq1qquKUbpcLid5DpSiadahN7vdbtE0L5fLVkjeO&#43;&#43;tMUmapkkSxXFzIIyRQvD53DuXZdliPs&#43;yzDk3m82Qg&#43;17JYw553prjmaEUpokCXYOhl4dWzd9XIAfkjiOgjY8Jxu/H08QAGMsy7L379/j3gTnMor6Y2GtxVYUuug4jj9&#43;/IhW2FqLL&#43;1EUYT&#43;sAp6jZVk55wQYhE6ZfhKDzbWgRDrHH6WUiINWZblofmFD8LmzGKxqKqqsTMh8kG/jT5fa934gMUiiqJXaH&#43;eWA0FiKJouVyim0Wt7wN/G957QNWLooiHFlie5xg&#43;YWiIHEeR4CskFN8iCfEr&#43;pI4jvsoCN93O4qCEFEUNXYp8BRXQ7/ddxT6qBf7PK/TAz85EWssb&#43;DU8CW10QwIW&#43;1Ysh/Ny/oV8I/wRktjWzA8HQ4bfgtmmF5hk7IfdrDgvbzvdXL/yQI4lWGObm/wVcDHbv67k6aHCXjNONeCXhhnAbwwzgJ4YTwggLfxat9bx7gTxt8rcf7UF6fP&#43;GEYeTfUeaKtq5WplR7&#43;rsEZz4GRE&#43;C8r5T9umlyy0hwCt/&#43;&#43;tgZ341RAZBSOWfrban4G3i5721j3Ac0MtC&#43;0m7w4yxnPAtGBQDh96iY9/7M/efGqVJE&#43;wNJP5maXxDjAoD&#43;5yJ&#43;OkG/GkYEAIQwCpKDFM//lvMvjzEBAIkEzDMxTYUU5zDoeTEiAEpJLOg8lxfTOJKvtI/xb4N/BQAA//96s&#43;GS&#43;OdZtwAAAABJRU5ErkJggg=="
     data-sizes="auto"
     width="526" alt="A screenshot of the sample component displaying the provided text of &amp;ldquo;hello&amp;rdquo;."
     loading="lazy" />


</a>

  
  
</figure></p>
<h2 id="what-about-sending-the-value-to-apex">What about sending the value to APEX?</h2>
<p>Now, let’s go one step further and send this parameter over the APEX and post a response.</p>
<ol>
<li>Create an APEX class, and create a public static method using the <code>AuraEnabled</code> decorator.</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span> <span style="color:#a6e22e">@AuraEnabled</span>(cacheable<span style="color:#f92672">=</span><span style="color:#66d9ef">true</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">static</span> String <span style="color:#a6e22e">reflectValue</span>(String value) {
</span></span><span style="display:flex;"><span>     <span style="color:#75715e">// Really you should do something useful here.</span>
</span></span><span style="display:flex;"><span>     <span style="color:#66d9ef">return</span> value;
</span></span><span style="display:flex;"><span> }
</span></span></code></pre></div><p>In this case we’re starting with a method that just passes back the same string it was handed, but obviously you can do whatever you want here.</p>
<p><em>BE CAREFUL ABOUT SECURITY!</em></p>
<p>If you take an ID as your parameter make sure you are thinking about what happens when someone sends an ID for an object they should not see, is for an object other than the type you expected, and other similar things. The platform can help you but security is your job here, take it seriously!</p>
<ol start="2">
<li>
<p>Create <em>good</em> tests for your class, and deploy the code.</p>
</li>
<li>
<p>Import the new function into your JS file:</p>
</li>
</ol>
<p><code>import reflectValue from &quot;@salesforce/apex/valueReflection.reflectValue&quot;;</code></p>
<p>Update the <code>getStateParameter</code> handler we wrote before to call this function as a <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">JavaScript promise</a>:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-js" data-lang="js"><span style="display:flex;"><span>  <span style="color:#a6e22e">getStateParameters</span>(<span style="color:#a6e22e">currentPageReference</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">currentPageReference</span>) {
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">urlValue</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">currentPageReference</span>.<span style="color:#a6e22e">state</span>.<span style="color:#a6e22e">c__myUrlParameter</span>;
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">urlValue</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">reflectValue</span>({ <span style="color:#a6e22e">value</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">urlValue</span> })
</span></span><span style="display:flex;"><span>          .<span style="color:#a6e22e">then</span>((<span style="color:#a6e22e">result</span>) =&gt; {
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">displayValue</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">`URL Value was: </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">result</span><span style="color:#e6db74">}</span><span style="color:#e6db74">`</span>;
</span></span><span style="display:flex;"><span>          })
</span></span><span style="display:flex;"><span>          .<span style="color:#66d9ef">catch</span>((<span style="color:#a6e22e">error</span>) =&gt; {
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">displayValue</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">`Error during processing: </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">error</span><span style="color:#e6db74">}</span><span style="color:#e6db74">`</span>;
</span></span><span style="display:flex;"><span>          });
</span></span><span style="display:flex;"><span>      } <span style="color:#66d9ef">else</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">displayValue</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">`URL Value was not set`</span>;
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>  }
</span></span></code></pre></div><ol start="4">
<li>That’s it! Deploy your code and reload the page, and your values should pass through to APEX, come back and get displayed.</li>
</ol>
<p><a href="https://github.com/acrosman/lwc_example_url_parameters">The complete SFDX project for this example is up on Github.</a></p>
]]></content:encoded> </item> <item>
      <title>SC DUG April 2020: Remote Work Round Table</title>
      <link>https://spinningcode.org/2020/04/sc-dug-april-2020-remote-work-round-table/</link>
      <pubDate>
        Thu, 16 Apr 2020 01:50:31 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=1415</guid>  <description>This month&amp;#39;s SC DUG was a round table discussion on working remotely during the Covid-19 lock down. We had actually planned this topic before the crisis emerged in full, but found ourselves having to pivot our talking points a fair bit.</description> <content:encoded><![CDATA[<p>This month&rsquo;s SC DUG was a round table discussion on working remotely during the Covid-19 lock down. We had actually planned this topic before the crisis emerged in full, but found ourselves having to pivot our talking points a fair bit.</p>
<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
      <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/Q65OXiiEM3s?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
    </div>

<p>The discussion centered on things that people are dealing with, even those of us who work remotely on a regular basis. A few resources were shared by people on the call, including <a href="https://pantheon.slack.com/apps/A11MJ51SR-donut?next_id=0">Pantheon&rsquo;s Donut Slack Bot</a>.</p>
<p>If you would like to join us please <a href="https://www.meetup.com/SC-Drupal-Users-Group/">check out our up coming events</a> on MeetUp for meeting times, locations, and remote connection information.</p>
]]></content:encoded> </item> <item>
      <title>Thoughts for the Newly Remote Worker</title>
      <link>https://spinningcode.org/2020/03/thoughts-for-the-newly-remote-worker/</link>
      <pubDate>
        Thu, 19 Mar 2020 01:37:16 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=1394</guid>  <description>Due to Covid-19 right now huge number of people are suddenly working remote. Some wanted this for a long time and are suddenly getting the chance; some didn’t really want a remote job but now are forced to try it.</description> <content:encoded><![CDATA[<p>About three years ago I wrote up some of <a href="/2016/11/yes-i-wear-pants/">my thinking on what you need to succeed in remote work</a> and I still stand by most of that advice. But right now many of those suggestions may need to be goals you are working towards.</p>
<p>A few days ago my friend Johanna, who like me routinely works from home, learned she’ll be working from home while she and her partner try their hand at homeschooling and offered this tweet:</p>
<p><a href="https://twitter.com/hanabel/status/1238502158997356545?s=20">https://twitter.com/hanabel/status/1238502158997356545?s=20</a></p>
<p>She’s both absolutely right (and smart, so if you’re on Twitter you should <a href="https://twitter.com/hanabel">follow her</a>), but also a little wrong. This is not what work from home <em>normally</em> is like, but <em><strong>this is</strong></em> what work from home is like <em><strong>in this moment</strong></em>.</p>
<p>Right now a huge number of people are suddenly working remote for the first time. Some of you probably wanted to this for a long time and are suddenly getting the chance, and some didn’t really want a remote job but now are forced to try it.</p>
<p>While some companies already have the tools and habits in place to make remote work successful, most probably don’t. What’s more, many people are now also doing childcare/homeschooling at the same time. So let’s be clear this is a terrible way to start working remotely. But here we are, so let’s talk about ways to use enough duct tape to make it work.</p>
<h2 id="your-boss">Your Boss</h2>
<p>Lots of people probably have bosses that are deeply uncomfortable with this whole thing. They may have fought allowing remote work for long time because they worry about monitoring remote work and have no experience with remote management–those fears are likely still there and will put them off their game. Managers who are uncertain about basic working conditions can make bad choices that make a bad situation worse – like trying to monitor everyone on video conference all day. I’ve worked remote for bosses that didn&rsquo;t trust me if they couldn&rsquo;t see me, it&rsquo;s hard and makes it hard to be successful. Long-term if they don&rsquo;t learn to adjust you should probably find someone better to work for, but in the short run that’s probably not an option (and hopefully they will adjust) so let’s talk about strategies you can use to get through.</p>
<h3 id="check-in-early-in-the-day-so-they-know-youre-up-and-running">Check in early in the day so they know you’re up and running.</h3>
<p>This should be something informal like a quick email to verify a meeting or other detail, a chat message just greeting them warmly, or something similar. Basically give them a sense that you are around and active before they ping you to find out if you remembered to wake up. You don&rsquo;t want to sound needy or like you&rsquo;re asking their permission to do work, as that can encourage micromanagement instincts.</p>
<h3 id="check-in-again-at-the-end-of-the-day-letting-them-know-youre-leaving">Check in again at the end of the day, letting them know you&rsquo;re leaving.</h3>
<p>Again this should be something informal and simple that gives them, and you, a sense of closure to your work day. This helps avoid them feeling like you just disappeared while they adjust to the routine.</p>
<h3 id="leave-a-documented-work-trail-with-timestamps">Leave a documented work trail <em>with timestamps</em>.</h3>
<p>Think emails, notes from meetings, hours tracking and billing systems, Word documents with update timestamps, version control systems, and other things that you can point to that will remind them you really were working even though they didn’t see you (and if things get ugly something you can show others to prove you were working).</p>
<h3 id="start-early-or-work-late-a-few-times-early-on">Start early or work late a few times early on.</h3>
<p>Again this is about helping them see that you really are working hard even though they can’t see you. You still need to maintain work/life balance so don’t do this every day, or even most days, just enough that they are able to notice the effort in a crisis.</p>
<h3 id="suggest-new-or-better-tools-to-help-support-the-sudden-remote-culture">Suggest new or better tools to help support the sudden remote culture.</h3>
<p>They probably know things aren’t working super well, and a chance to blame tools may be welcome. So research and suggest tools that make things better. Try to spot the things that have them uneasy about the situation and offer tools that might help with those challenges.</p>
<h2 id="your-tools">Your Tools</h2>
<p>On the topic of tools, if your team just went fully remote you probably are lacking some tools to do all the things a great remote team has in place. You aren’t going to fix that overnight, but don’t let the perfect be the enemy of the good here – a tool that your team uses is better than the perfect tool that no one adopts.</p>
<p>So if you need to pick a chat client try the low hanging fruit first. You&rsquo;re a Microsoft shop with 365 setup? <a href="https://products.office.com/en-us/microsoft-teams/group-chat-software">Use Teams</a>. You a Google apps shop? <a href="https://gsuite.google.com/products/chat/">Use Hangouts</a>. Salesforce? <a href="https://www.salesforce.com/products/chatter/overview/">Chatter</a>. Use <a href="https://medium.com/@laura.noren/zoom-configurations-5-mins-for-privacy-and-security-29f1514b2e23">Zoom</a> a lot? Well their chat is terrible so <a href="https://slack.com/lp/three?utm_medium=ppc&amp;utm_source=google&amp;utm_campaign=d_ppc_google_us_en_brand-hv-exp-messaging&amp;utm_term=slack&amp;ds_rl=1249094&amp;gclid=EAIaIQobChMIyqHRpteg6AIVCGyGCh1KdwApEAAYASAAEgIzB_D_BwE&amp;gclsrc=aw.ds">use Slack</a> (everyone else should probably default to Slack too). Some of those tools are far better than others but each has a niche they serve very well, and maybe your team will switch one day but get started now and worry about using it really well later.</p>
<h2 id="your-family">Your Family</h2>
<p>Don’t sweat the kids and pets interrupting. My current team was nearly 100% remote before all this started. We’re professional, have a strong team work ethic, and work hard to make sure our clients see that. And you know what, people’s kids and pets get in the way sometimes. Rarely does it matter for more than a minute or two. Right now, we&rsquo;re running into a lot more of that than is normal. So are our clients. It&rsquo;s going to be just fine.</p>
<p>Normally we try to limit interruptions, but honestly pets and kids are welcome cute distraction more often than not. My dogs wander my office and often end up on camera. My boss’s cat frequently strolls across his desk during check ins. Other people’s children come in and wave to all the people on their parent&rsquo;s computer screen. Sure there are times we need to focus and someone’s dog really really needs to bark at that cat outside the window. Or a child needs their parent’s attention the very minute we’re trying to solve a hard problem. It’s just part of how things flow, and within my team we understand it as a part of work from home since it gives us all more time with the people that matter most to us all (hint: not our colleagues). Family, in whatever form they come, are part of what makes us who we are and allows us to see each other as a more complete person.</p>
<p>Yes, in this moment when kids are suddenly off from school with few places having formed any reasonable plan for education continuity, even for experienced teams we are expecting it will be disruptive. The entire American workforce is going to have to learn to deal with either their kids, or their colleagues kids, suddenly being around. Do your best to maintain focus and professionalism, but expect cracks, and let those imperfections help you get to know your colleagues better.</p>
<p>The next few weeks or months will be a lot of remote work duct taping even for experienced teams. You, your team, and your families, will learn to get better at this over time. Embrace that you’re learning, expect mistakes, and just plain do the best you can at the moment.</p>
]]></content:encoded> </item> <item>
      <title>Crash Teaching Online</title>
      <link>https://spinningcode.org/2020/03/crash-teaching-online/</link>
      <pubDate>
        Tue, 17 Mar 2020 23:03:35 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=1402</guid>  <description>This has been an interesting week for academics as we move to online instruction, perhaps for the first time. Here’s what I’ve learned and the order in which I found it helpful to tackle the sudden move.</description> <content:encoded><![CDATA[<p><em>This is a guest post by my wife Elizabeth Georgian. She&rsquo;s a professor at a local university and is one of many scrambling to move all her courses online.</em></p>
<p>This has been an interesting week for academics as we move to online instruction, perhaps for the first time.</p>
<p>At my university, we heard on Monday that we’re going online next week. Needless to say, this has been a pretty chaotic few days. Here’s what I’ve learned and the order in which I found it helpful to tackle the problem. For context, I’m a history professor at a regional public university, teaching four classes, with a lot of general education students. I mostly teach face-to-face, but I’m online in the summers.</p>
<h2 id="email-your-students-right-away">Email your students right away</h2>
<p>Contact them even if it’s just to let them know that you’re working on a plan. Give them a time frame of when you expect to be able to share more information. If you’re planning on taking your course in the Learning Management System (aka an LMS such as Blackboard or Moodle) offline while you work (more on that in a minute), tell them that, otherwise they’ll panic. Most importantly, let them know that you care about them and that you know it’s a stressful time for everyone. If your counseling center is offering remote help, tell them how to access it.</p>
<h2 id="let-go-of-trying-to-be-perfect-and-forget-about-best-practices">Let go of trying to be perfect and forget about best practices.</h2>
<p>We aren’t teaching online—that takes a lot of time to do well—we’re teaching remotely in an emergency. The most helpful article I’ve read so far was “ <a href="https://anygoodthing.com/2020/03/12/please-do-a-bad-job-of-putting-your-courses-online/?fbclid=IwAR2asxqgjk3_I6-tqr_a-jfEcZ_Oj_Zf-4xdlqNXfPrUTsF5eHMWbf-mFEY">Please do a bad job of putting your courses online.</a>”</p>
<h2 id="figure-out-whats-most-important-for-the-rest-of-the-semester">Figure out what’s most important for the rest of the semester.</h2>
<p>Here are some things that might be your top priority:</p>
<ul>
<li>Delivering content</li>
<li>Helping them complete a particular project</li>
<li>Supporting students with limited technology</li>
<li>Making sure you set up your classes in a way that allows you to care for your own health needs or for your loved ones.</li>
</ul>
<p>You can’t do it all and now’s not the time to try, so decide what matters most right now.</p>
<h2 id="ask-what-technology-your-students-can-access-where-they-are">Ask what technology your students can access where they are.</h2>
<p>Depending on your student body and location, maybe all of them will have laptops and high speed internet, but some of us teach at institutions where students may need to finish classes on their smartphone or are returning to rural areas with limited internet access.</p>
<h2 id="decide-if-you-want-to-teach-synchronously-asynchronously-or-both">Decide if you want to teach synchronously, asynchronously, or both?</h2>
<p>Asynchronous instruction is easier for students who have to share computers with partners, who are switching to remote work or learning, it accommodates parents who are suddenly home schooling, and it helps students with limited internet access. But there’s a benefit to real time options too. For some of our students, we are the adult in their life they feel connected to and it’s important to preserve that connection. Optional video office hours or reading discussions can help them stay connected to the class and the university without hurting their grades if they can’t participate.</p>
<h2 id="plan-ahead-and-minimize-changes">Plan ahead and minimize changes.</h2>
<p>The more of the class structure and assignments you can preserve, the less confusing it will be for your students and the easier it will be on you. Free response assignments will take longer to grade but are faster and easier to set up in most LMSs. If you’re concerned about your students’ access to high-speed internet, keep new work based in printed resources your students already have whenever possible. Avoid timed tests or quizzes or ones that require remote proctoring. Planning assignments you can send by email or snail mail if needed will save you time and effort later.</p>
<h2 id="find-or-become-a-mentor">Find or become a mentor.</h2>
<p>If you haven’t taught online, try to find a mentor in your discipline who is comfortable with your LMS. If you have, help out your less experienced colleagues. Distance learning experts are over loaded and they may not understand the needs in your particular discipline.</p>
<h2 id="hide-your-course-from-your-students-temporarily-warn-them-first">Hide your course from your students temporarily (warn them first).</h2>
<p>Students tend to get nervous when they see you making changes in the LMS. Particularly if you’re making substantial changes or creating new assignments, you will set something up wrong, screw up a deadline, or rethink an assignment, and you want to be able to fix that stuff and make changes before you take the course live. Just don’t forget to reopen access.</p>
<h2 id="communicate-regularly-with-your-students">Communicate regularly with your students.</h2>
<p>It’s a lot easier for them to disconnect from online class than it is in a face-to-face class, particularly right now when they’re stressed, suffering from vacation syndrome, or both. Since they may not be used to online learning, they will need more routine reminders about deadlines, particularly if you’ve adjusted them due to an extended spring break.</p>
<h2 id="dont-forget-to-be-human">Don’t forget to be human.</h2>
<p>It’s fine, even helpful, to let your students know you’re stressed too or that you don’t have all the answers. If you’re doing video lectures or office hours, go ahead and introduce them to the people or pets in your home that may wander on camera—I always let my students meet my two greyhounds before they show up uninvited. Now is the time to set some boundaries between work and life, maybe that means not checking your email after dinnertime or taking a walk at lunchtime. Taking care of yourself will help you be a better teacher.</p>
<p><figure>
  <a href="/wp-content/uploads/2020/03/IMG_0298-1024x768.jpg" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    
    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2020/03/IMG_0298-1024x768.jpg" alt="Two greyhounds laying on beds on a hardwood floor." loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2020/03/IMG_0298-1024x768_hu_c22a02690df5deb7.jpg 680w, /wp-content/uploads/2020/03/IMG_0298-1024x768_hu_7815b5925d9de474.jpg 850w, /wp-content/uploads/2020/03/IMG_0298-1024x768_hu_17834947b85709db.jpg 1020w, /wp-content/uploads/2020/03/IMG_0298-1024x768.jpg 1024w"
     data-src="/wp-content/uploads/2020/03/IMG_0298-1024x768.jpg"
     src="data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDIBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAGAAgAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AJceWcVL1FS3EXz76irzDuC3PyOn901o6cd9wqf3jWd92b/eFWLGTyrmJ/8AbrqpHNVPTrS0jtJI2jXb5g&#43;YVrQx&#43;WpX&#43;GoLVBNbRSewqxtdD1&#43;Wuw5jkvFQ8u5Vx/EtYFschf8Aero/Fw&#43;WJ/rXJ2svz/iK56h0dD022jzbRfQU&#43;SAbGC9TVeLz5LKIxsF&#43;UVXaC937nk49jXRc5/ZGZrRCXKJn7q1hWcv78/U1pa4&#43;y7Bzn5ea5S61NNOtmlz82Dj8a56p00iLxb4hEFubSB/mb71eYX0uVz3NX9Qu3urmSRzlmPFYt7LyormOkI5Kltv9Yz1U8zipreXy0oA9ak/eQVV9qvkeW/l1n3LxRS4LAH61mAyd9hD&#43;lSF8bWH1qvLcQGP5mX86pXOoRQQK4kB7da0Mz0Gx8bPbWaRGPOxakfx3PIPkjFePXuuXB&#43;SNwtZf/CQ38Umwy1r7Uy9mex33iGfUdqyKoRay7W5ieeQpIMg4xmvL7vxJqHl8S7VqCx1u6ikEmXIznNID3mHW71YRGJeBS/2peSf8vDV5xY&#43;Kbie3yqjIqb/hILwj7wX8Kz9qzT2R2N9dFIZJpZMnHevONY1U3LhAfkUYp&#43;rX9/cWhxK1cjNJcZwW5opsfsi9JMPWse8mzP1qOUy/3zUPU81oBaEtS&#43;bxVAffqXNBoex61qkenbXY7pG/hrhtQ1CW7uGlBYBu2ak1K&#43;lvrtppM4qpvXH3KzNhjyOQAXP51lXt5Ms4RSSi1euZPnXsKoXMeZN6fMtaUjGqD3uYQcHfVW7kkk2OKUkjquKTeV4xWpzAk5kXZIKtW8jfZtrJtVT1pLIR&#43;ZmUblqe5uYNmyOLLVkBqaDLvumTjDCui&#43;y/7X6Vg6ThbTd5W2X1Pate31BYx/pM8f51lVOqkOlGwYfkVzGrQmOTzEHFdOdTs5D/AK2Oo7qO3vLchHRj7Vzr92dH8Q4KSRzUVaF/a/ZpSlZ5612nMEfWpai6UscnPz0AdPvf0pN7&#43;lLvzR5clZmxFLD5g6VQa3nicsi7krTk3j&#43;Ko93bNZ3F7Mz/ADmG3zYD/OnedGSv7n9KvfuzVmKKIp9wVp7Qz9kZaY3ttixVeJI/teT1rRvUAjcQFS9ZKW88cRL9WoMjobuSSOw3wYkXHzKKztHtYtVu3hlBRyPl5qfR7kY8qT9auzWV3HcpcWSxrt9qAG3Pg67iH7h/M/Sq0fh7WIcuEK4966dLrU5I0y6qe9Si6uN&#43;HfNZe0NVTOAvftKybLpWDepqnJHXomt2CX2kSN5Y85BuBrzdnIJU9RXTS/eCqfuxKKjzzUlAHURyf7NSea/&#43;zVaiuY6glOe9VjmrPlk0eT7UAUeQe9JcX0kceErSjt1d&#43;SBVecWFpPmZvNH91a1Mqphz3cuQ6kq3etESmW2R85&#43;WpZP7JvXwiOlAS0jiMMMv/fVaHMUoZtsu8HGK6Gx1wYEbmuLmkkEzhOmaQTSjvzR7IXtT0n7WDHvR6I7xRJliK8/iv7yMY3nFTfbLmT78hrP6qbe1O01rxBFDYvFC&#43;&#43;Rxt&#43;lcCxLMSepqRmJzk5qKtaVP2ZlVqhUvaouvSr8tr5VhFI/G/NahSNUXKH&#43;CpPM/2KqxVZw9cB3C&#43;ZJSfvn/AIqWgUARvAz/AHnNIbGM9eTVn93/AHqXKUzX2Rg3MP2S53J0NRGDzIyyP89bN1CLiPpWFKZLaXZXRSqnDVpFVgVbB60mcVeAjnG5&#43;P8AaqtLb90&#43;atjlIvMqXzOKrdDUgoAXnNSUAZIA6mtm10X92JLh1X0XuaQFHTtOkupwxG2PufWtPVUkMCLs/dJ90VvQWsTQxIg8vbyferGoWkckICVze1O6lSP/2Q=="
     data-sizes="auto"
     width="1024" alt="Two greyhounds laying on beds on a hardwood floor."
     loading="lazy" />


</a>

  
  
</figure>Henry and Petey.</p>
]]></content:encoded> </item> <item>
      <title>SC DUG February 2020</title>
      <link>https://spinningcode.org/2020/02/sc-dug-february-2020/</link>
      <pubDate>
        Sat, 15 Feb 2020 20:32:40 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=1380</guid>  <description>For SC DUG Feb. 2020 I gave a talk on the importance of self-directed learning for professional development as a developer – or really any other modern career. The presentation runs a hair over 30 minutes, and parts of the discussion are included as well.</description> <content:encoded><![CDATA[<p>This month for SC DUG I gave a talk on the importance of self-directed learning for professional development as a developer &ndash; or really any other modern career. It was an extension and revision of <a href="/2019/12/on-being-self-taught/">my December blog post on the same topic.</a> The presentation runs a hair over 30 minutes, and parts of the discussion are included as well.</p>
<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
      <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/ybNI6UeYzlI?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
    </div>

<p>We frequently use these presentations to practice new presentations, try out heavily revised versions, and test out new ideas with a friendly audience. If you want to see a polished version checkout our group members’ talks at camps and cons. So if some of the content of these videos seems a bit rough please understand we are all learning all the time and we are open to constructive feedback.</p>
<p>If you would like to join us please <a href="https://www.meetup.com/SC-Drupal-Users-Group/">check out our up coming events</a> on MeetUp for meeting times, locations, and remote connection information.</p>
]]></content:encoded> </item> <item>
      <title>On Being Self-Taught</title>
      <link>https://spinningcode.org/2019/12/on-being-self-taught/</link>
      <pubDate>
        Mon, 23 Dec 2019 12:00:00 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=1279</guid>  <description>Over time I’ve come to realize that the further you get into your career, the less the distinction between being formally trained and self-taught means anything; eventually we are all mostly self-taught.</description> <content:encoded><![CDATA[<p>From time to time conversations come up among developers, and other fellow travelers, about being self-taught vs getting formal training. Over time I’ve come to realize that the further and further you get into your career, the less the distinction means anything; eventually we are all mostly self-taught.</p>
<p>I’ve written before about <a href="/2016/10/what-i-learned-by-getting-a-degree-from-a-liberals-arts-college/">the value of my liberal arts education</a> and I stand by my assertion that what I learned in that setting was, and is, valuable to my life and work. But just because something was useful to life does not mean it was the only way to acquire the skills. It’s a good way for many people, but far from the only way.</p>
<p>For anyone in a technical field, and most professional fields really, to succeed over time <a href="/2017/02/are-you-moving-forward-or-backward/">you need to learn new tools, skills, and techniques</a>. The tools I knew when I graduated college are all largely outmoded or significantly upgraded, and I’ve had to learn a variety of technologies that didn’t exist in 2001.</p>
<p>Within the Drupal community lots of people talk about being self-taught, sometimes with pride sometimes with embarrassment, but in truth very few people were formally trained on the platform. Lots of very successful developers in the Drupal community (and beyond) have degrees in fields like religion and art history, not computer science, and have taught themselves how to do awesome things. In fact, I’ll argue that just about every Drupaler taught themselves most of what they know about Drupal. How they did that can vary widely, but we are a community with few formal training programs and lots of people who stumbled into Drupal trying to solve a non-technical problem. Even advanced workshops at conferences dig deep into one small area and expect you to generalize that knowledge to your projects, which I count as self-teaching. For example, I had a friend ask the other day about how to control the PDO connection settings in Drupal 7 &ndash; which I didn’t know how to do, but knew they were similar to Drupal 8 &ndash; so I sent him <a href="/2017/10/drupal-8-remote-database-services/">my Drupal 8 instructions</a> and he figured it out how from there. He’s now taught himself how to do what he needed for that project and in the process generalized the approach for whatever he may need next time.</p>
<p>So then it is important for all of us to find, and hopefully share, techniques for self-teaching &ndash; even for those who have some kind of formal training. Here are my suggestions for people who are starting out and haven’t yet found the pattern that works for them:</p>
<ol>
<li><strong>Assume you first solution is wrong</strong>. Most of us have, or will, stumble our way through a project where we don’t really know what we’re doing without a lot of support. We usually learn a great deal in the process, and launching those projects can feel pretty good cause you’ve succeeded at something hard. It is easy to get into the habit of assuming the solutions from that project were correct because they worked. In truth those projects are really rough around the edges, and just because we got it to work does not mean the solution was good. Assuming the first solution is good enough forever is how you become an <a href="https://daedtech.com/how-developers-stop-learning-rise-of-the-expert-beginner/">expert beginner</a> which then takes <a href="/2017/04/fixing-the-expert-beginner/">a lot of effort to undo</a>. Once you have a working solution, step back and see if you can think of a better one, or see if you now can guess better search terms to see if someone else wrote up a different solution to the same problem. Admit your work could be better and try to improve it.</li>
<li><strong>Learn a few more programming languages.</strong> Most people who are self-taught from the start, and even some who have a BA/BS in Computer Science, only know 2 or 3 programming languages (PHP, JS, and <a href="https://stackoverflow.com/a/5239256/24215">CSS+HTML</a> are often the only languages new people learn at first). One of the courses I took by chance in college forced me to learn 8 in 16 weeks. It was grueling, miserable, and darned useful. I can still learn a new language in just a couple weeks and rarely do I hit a language construct I don’t recognize. You don’t need to go that far. When I first started out a mentor told me you should learn a new language every year, and for several I did. Some of <em>those,</em> not the languages I learned in college, are the ones I use most day-to-day. All told I’ve spent time writing code in more than twenty different languages. That many isn’t terribly useful but the more languages you learn, the more you learn to understand the elements of your primary language.</li>
<li><strong>Learn basic algorithms and to measure complexity.</strong> The kind of thinking that goes into formal algorithms will help you be a better developer overall; badly thought through processes is the place I tend to see the largest gaps between developers with and without formal training. Any college-level CS program will put you through an algorithms course that teaches a variety of specific algorithms and force you to understand their structures. If you didn’t go through one of those programs, <em>this</em> is probably the course that will help you the most. On the one hand most of us rarely rewrite these algorithms as on modern platforms some library or another will provide a better version than we are likely to craft for our project. <em>But</em> learning what they are, when they are used, and how to understand their performance is useful for any project that involves lots of data or processing. <a href="https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-006-introduction-to-algorithms-fall-2011/">MIT has a version of their algorithms course from 2011 online</a>, or find one through another provider. Even if you just watch the lectures (really watching, not just vaguely have them on while cooking and cleaning), you can learn a great deal of useful information. I learned a lot watching those lectures as it refreshed and updated my understanding of the topics.</li>
<li><strong>Find and learn from mentors.</strong> Notice I used a plural there; you should try to find a few people willing to help you learn your profession, and more generally help you learn to advance in your field. Most of us benefit from learning from the experiences of multiple people, and who we need to learn from changes over time. I had the great experience of having a few wonderful mentors when I was first starting out, and much of the advice they gave me still serves me well. Some of it contradicted, and resolving those contradictions forced me to learn to do things my own way and find my own solutions.</li>
<li><strong>Learn other platforms.</strong> This is both a protection against future shifts in the market, and also a way to see how things work from outside your current professional bubble. Drupal developers can learn a lot from writing a WordPress plugin, or better yet an add-on for a platform in another language (think about Plone, Gatsby, or Hugo). Or try to learn to work with a platform like Salesforce or AWS. Other platforms have different communities, different learning styles, and different patterns. Like understanding additional languages, different platforms help you broaden your understanding and provide insights you can bring back to your main work.</li>
<li><strong>Learn to give and take criticism.</strong> Part of learning is getting feedback on your work, and part of being on a team is sharing feedback with others. If you took art or music classes in high school or college you probably learned some of the basic lessons you need here, but if you didn’t, consider taking one now at your local community college or art center. The arts are wonderful for getting experience with criticism. For all art is often open to interpretation, it also requires specific skills. If you play off-key, it sounds wrong. If your sculpture collapses under its own weight, the project failed. If your picture’s subject is out of focus, you need to re-shoot it. Sure there are brilliant artists who can violate all the rules, but if you have never experienced an art critique you are not one of those artists. The experience of getting direct, blunt, and honest feedback will help you understand its value and how to give that feedback yourself.</li>
<li><strong>Share what you think you know</strong>. We learn a great deal with we teach others. Both because it forces us to refine our thinking and understanding so we can explain it, and because learners ask questions we cannot answer off the top of our heads. This can be user group or conference presentations, internal trainings for your team, mentoring junior developers, writing a blog, or anything else that gets your from learning to teaching. It’s okay if you’re not 100% right, that’s part of how we learn. A few years ago I was doing a joint project with a junior developer who asked me a lot of questions, and pushed hard when she thought I was making mistakes. When she asked why I was selecting a solution or setting a pattern, she was never satisfied with “because that’s the best way to do it.” She wanted me to explain <em>why</em> that was the best way. If I couldn’t walk her through it right away, I went back and hunted for reference material to explain it or if that failed I tested her counter ideas against my plans to see if I was missing something. While I was usually right, not always and we did make changes based on her feedback. More importantly it forced me to show my work in fine detail which was a good exercise for me and gave her insights to help her do better work.</li>
<li><strong>Find your own patterns.</strong> At the start I said this list was for people who didn’t have their own patterns yet. In the long-run of your career you need to figure out what you need to know to get to where you want to go next. Eventually you will need to find a pattern that works for you and the life you are living. No one can tell you what that is, nor how to learn it all yourself. Experiment with learning styles, areas of work, roles, and types of projects as much as you are able until you feel your way to the right solutions for you.</li>
</ol>
]]></content:encoded> </item> <item>
      <title>Some Things Every Developer Should Read</title>
      <link>https://spinningcode.org/2019/11/some-things-every-developer-should-read/</link>
      <pubDate>
        Mon, 25 Nov 2019 23:25:52 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=1271</guid>  <description>Here is my list of works that I think every developer should read at least once in their life.</description> <content:encoded><![CDATA[<p>Every developer needs to be learning new things all the time. We need to have a good grounding in the ideas that have come before us and those that are emerging around us within our field, and we need to understand the larger social impact of our work. To be fair this isn’t just true of developers, but we are a field that has a bad habit of arguing our work is totally new and original – which is rarely true in any meaningful way.</p>
<p>Part of that push for constant learning is to read books about software development, about life, about business, about writing, and really anything that pushes how and what you think. There isn’t really a settled cannon of things every developer must have read but there are definitely some works you need to be familiar with the ideas in (even if you haven’t read them) to keep in conversations over lunch at a conference like the <a href="https://en.wikipedia.org/wiki/The_Mythical_Man-Month">Mythical Man Month</a> and the <a href="https://agilemanifesto.org/">Agile Manifesto</a> (both of which came up over a lunch at my last conference). There is also a much larger set of works that many developers benefit from reading even if they aren’t really about software.</p>
<p>So here is my list of works that I think every developer should read at least once in their life. I’m breaking the list into two pieces: specific books I think every developer should actually read, and a category of types of things that every developer should be on the lookout to read on a regular basis. I&rsquo;d love to hear suggestions about should be added and what I should have read myself.</p>
<h2 id="specific-books">Specific Books</h2>
<p>These are some specific books that I’ve found helpful for making me a better developer. None of the ones here are directly about programming – that’s not an accident. Many of the books I’ve read about development and the creation of software were helpful and I am glad to have spent time with them but these are works that helped me think more broadly about the craft and the when, why, and how I write code.</p>
<ul>
<li><a href="https://smile.amazon.com/Design-Everyday-Things-Revised-Expanded/dp/0465050654"><em>Design of everyday things</em></a>: While many of the specific recommendations for how to fix some devices are out-of-date and flawed (I will never forget reading that all office phones needed to be easy to use was a two-line digital display while working at a desk with a proof the display had not solved the problem), the general philosophy holds up. Also, it will make you justifiably angry at every poorly installed door you struggle to open.</li>
<li><a href="https://smile.amazon.com/Zen-Art-Motorcycle-Maintenance-Paperback/dp/B00ZT1W1DO"><em>Zen and the Art of Motorcycle Maintenance</em></a>: This is a long, slow, dense read. And if I hadn’t need assigned it in college I probably never would have gotten through it. But I find myself coming back to its discussion of quality all the time.</li>
<li><a href="https://smile.amazon.com/Technically-Wrong-Sexist-Algorithms-Threats/dp/0393356043">Technically Wrong</a>: This is the newest book on this list, and it makes the cut cause the ideas are so important. I had the opportunity to see <a href="https://youtu.be/UcjT63hl4l4">Sara Wachter-Boettcher speak at DrupalCon</a> before she published the book and it was one of those talks that changed how lots of people in the room think about software and the role of our work in people’s lives.</li>
<li><em><a href="https://smile.amazon.com/Elements-Style-Fourth-William-Strunk/dp/020530902X">Elements of Style</a></em> (aka &ldquo;Strunk and White&rdquo;): I was assigned to read this in a history course in college and then again when I was promoted to Web Director at AFSC – cause the Director of Communications wanted to be sure I remembered the importance of writing <em>well</em> in that job (I did, but I re-skimmed the book anyway). If everyone wrote English like Strunk and White suggest writing would be much better on the whole – although fairly boring. Read it not because their rules are perfect, read it because you should think about the rules of writing when you break them.</li>
<li><a href="https://smile.amazon.com/Blah-What-When-Words-Dont-ebook/dp/B005GSZZFG"><em>Blah Blah Blah</em></a>: This is something you should read after you’ve read a lot about writing clearly since it rather pitches the reverse concept: sometimes a rough picture is clearer and more useful than a carefully written description.</li>
</ul>
<h2 id="things-that-push-and-inspire">Things that push and inspire</h2>
<p>These are examples of works that are helpful to push boundaries. The specific examples I cite may or may not be valuable to you, but they are examples of things within the category I’m describing.</p>
<h3 id="books-that-show-you-code-youd-never-write">Books that show you code you’d never write:</h3>
<p>These are books that talk about code and concepts that either have no application to your work, or are ways of showing off what a language can do – even when you shouldn’t follow the example. I have two examples here from opposite ends of the spectrum:</p>
<ul>
<li><em><a href="https://smile.amazon.com/Hemingway-Wrote-JavaScript-Angus-Croll/dp/1593275854">If Hemingway wrote javascript</a></em>: This book is brilliant. It’s a series of examples of how various writers might have completed common CS class programming assignments using JavaScript: DO NOT WRITE CODE LIKE THIS. It shows off how wonderfully flexible JavaScript is as a language, and presents some of the worst possible solutions to those problems along the way. It is a great read that will teach almost anyone a few things about JavaScript, and push you to think about different ways to approach a problem. It is a light, fast, and entertaining read.</li>
<li><a href="https://smile.amazon.com/Beautiful-Code-Leading-Programmers-Practice/dp/0596510047"><em>Beautiful code</em></a>: This is a fairly dry read. It is made up of series of examples of truly well written code: WRITE CODE LIKE THIS. It looks at code in a variety of languages, not all of which are in common use, solving problems that are sometimes familiar and sometimes rare (in part because of the code you’re reading). It is a slow dense, and at times boring read, but it’ll give you insight into what other people will find graceful in your work.</li>
</ul>
<h3 id="a-college-textbook">A college textbook</h3>
<p>I mean actually read and actual textbook. Sure if you went to college someone assigned bits of pieces of these things to read, maybe they even assigned all the chapters in order. But how many people actually did all the reading in order? That doesn’t mean the professors weren’t right that those things are useful – they do not get assigned for the professors health (and if you think professors get rich off assigning their own books you need to spend time learning about the economics of academic publishing).</p>
<p>I have a couple around that I kept as reference after college, and one or two I’ve now actually read end to end. I will grant you these are not exciting works. I don’t do this as a regular reading habit, but it’s worth having done. If you don’t have one around, most libraries still have books and often a few reasonable high level textbooks.</p>
<h3 id="articles-by-someone-whose-ideas-you-dont-like">Articles by someone whose ideas you don’t like</h3>
<p>If you aren’t used to doing this I should be clear that this is about getting outside your comfort zone on topics you think you know a lot about, and reading things that push you to justify – or better yet modify – your understanding of the field. This doesn’t have to mean going and reading material you find deeply troubling or revisit ideas you know are morally reprehensible. Bothering with ideas from ideologies of hate is unlikely beneficial for most of us, think closer to home here. In this category I’m talking about project management practices you think are overblown: love Agile, read people who point out where it routinely fails; hate Agile, read some material about why it always works when done right. For me it is sometimes reading people who still argue technology is morally neutral. But best is often to find a topic you are still trying to resolve your own thinking on and absorb some uncomfortable ideas and wrestle with them.</p>
]]></content:encoded> </item> <item>
      <title>In Praise of B Students</title>
      <link>https://spinningcode.org/2019/10/in-praise-of-b-students/</link>
      <pubDate>
        Sun, 13 Oct 2019 23:00:16 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=1250</guid>  <description>There is nothing wrong with just being good at something.</description> <content:encoded><![CDATA[<p>When I was in school I was a solid B student. I thought of myself as a B student and I worked hard to make sure I was always working at least a B average. I worked hard, but not too hard. Likely I could have been an A student if I’d worked harder, but I would not have been as happy. I didn’t feel the drive to be the best all the time, just good enough to keep up with what I was learning. Most people brag about being A students, but that wasn’t me and it has worked out pretty well in the long run.</p>
<p>For me a B student is someone who not only gets actually Bs most of the time in school but also knows how to work hard to get the grade they want, and how to relax so they recover and enjoy their lives along the way. If they fall a little short at some point they are perfectly capable of working a little harder to make up the ground. Life is not a sprint, it&rsquo;s a marathon, we all have to save a bit for later. If you are used to running full out all the time, you do not always have the ability to step it up a little extra when needed nor how to relax and recover without stopping. In a world where we seem to be moving from <a href="https://www.parents.com/parenting/better-parenting/what-is-helicopter-parenting/">helicopter parents</a> to <a href="https://www.businessinsider.com/snowplow-parents-calling-employers-college-helicopter-parenting-2019-3">snowplow parents</a>, there are still people that <em>have</em> fallen short from time to time, so they know how to pick themselves up and push forward.</p>
<p>There has been <a href="http://www.bbc.com/future/story/20180219-toxic-perfectionism-is-on-the-rise">plenty written</a> and <a href="https://www.ted.com/playlists/710/how_perfectionism_fails_us">said</a> about the flaws of perfectionism so you don’t need to trust me, and I’m not going to waste time making the case that there are problems with pushing kids and college students to be a perfect A student all the time. And there are problems when companies only want to hire people who have those backgrounds.</p>
<p>In our current test-driven education culture there is a lot of push for kids to be the best. And the highly competitive nature of admissions for some top colleges can make it seem like a kid has to be perfect to succeed in life. But life isn&rsquo;t <em>Top Gun</em> there actually <em>are</em> points for second place, and really more or less all the others (well paychecks and some level of happiness anyway). More importantly people who are used to a bit of failure can excel when faced with tough jobs that require a lot of on the job learning and trial and error work. That describes pretty much every modern office job, and lots of others – watch a plumber work on an old house and you&rsquo;ll see plenty of trial and error being required to solve even basic problems.</p>
<p>Failure is a part of life. We all need to know how to acknowledge we made mistakes, how to recover, and how to ensure we <a href="/2016/07/always-make-new-mistakes/">don’t make the same mistake again in the future</a>. People who earned a lot of B&rsquo;s in school are familiar with all those things. We sometimes got lazy and ended up with a C instead of B – to stay a B student we then worked harder and got ourselves enough A&rsquo;s to offset our missteps and bring our averages back up. Sometimes we really didn&rsquo;t understand something and had to struggle through to make sure we stayed on pace.</p>
<p>B students also often know the difference between learning and getting the right answer on an assessment (a skill I would have told you I had but did not need anymore until I starting having to pass professional certification exams on a regular basis). We learned how to pass the test without knowing all the information, but knowing enough to get the grade we wanted. Getting a perfect score on an assessment is only useful if the assessment is perfect – most college professors and anyone who has taken a certification exam can tell you there are no perfect assessments. I had to pass tests in college, and I need to complete and maintain certifications now, but I don&rsquo;t need to have every piece of information crammed into my brain all the time – that&rsquo;s what Google is for. Once I pass, I’ve passed – it feels better to get more right answers, but as long as I get enough to pass I’m certified.</p>
<p>When I was in the 6th grade we had a whole day dedicated to studies skills taught by a guy named Mr. Gallagher. He wasn’t a regular teacher at my school, and I have no idea where they found him or what happened to him later, but some of what he taught us that day has stuck with me both in terms of skills and philosophy. He emphasized the need to understand how a test was written, both in terms of following directions so you didn’t give up silly points and so you know where to focus your time (hint: time goes first into the places you are likely to earn the most points), and when to guess and when to work through an answer carefully (again be greedy about points not the number of right answers).</p>
<p>Mr. Gallagher was the first person to put the idea into my head that the point of going to school is to get good grades instead of learning. I can still remember our teachers pushing back on that argument the next day, and I eventually arrived at the conclusion that they were both right: the purpose of <em>school</em> is to learn, but the purpose of <em>tests</em> is to get good enough grades so you can move forward in school. The thought exercise itself helped me see that learning material and passing a test weren’t actually always related. I had a teacher later who helped me further abstract this concept when he pointed out that he could easily write tests we all passed or all failed, so the purpose of the test writing was to find a measure of what he thought we should be able to do (that teacher and his wife were <a href="https://www.marketplace.org/2019/09/30/adventures-in-housing-the-boarding-school-dorm-parents/">recently on Marketplace</a> – thanks Bill that simple lesson was super useful in college and beyond). If pass and fail are at the whim of the test author, and they aren’t <em>actually</em> playing against me personally but really tracking a group of people, then I can play it as a game where I need to get myself into the top 80%. If I learn to play at that level reliably I’m going to do pretty well and I don’t have to stress being perfect all the time.</p>
<p>Yes, there are <a href="https://www.ussoccer.com/teams/uswnt">things in life that you cannot do unless you are one of the best</a>. Not to mention the fact that the playing field isn’t level, which means some people have to work a whole lot harder than others to earn the same B and a report card full of Bs doesn’t get read the same for everyone. But we cannot all be the best, and pretending that’s not true doesn’t level the social playing fields.</p>
<p>And of course there are plenty of moments we need to strive to be as close to perfect as we are capable. But we also have to hit deadlines and get things done even if we know the work will be less-than perfect. Anyone who works in software development has to deal with this on a regular basis. As much as we may want to be perfect, shifting project requirements, project timelines, platform weakness, and our own mistakes all get in the way. We do the best we can with the skills, time, teams, and the tools we have. We need to know how to accept that we cannot fix every flaw and still get things done well enough to ensure the project is successful.</p>
<p>So when you are hiring people consider looking for people who already know how to be second best. People who know how to do really good work, but also know how to take risks, try something new, and in the process fail. People who know how to get things done well enough to be successful, even if it’s not perfect. We aren’t perfect, our work isn’t perfect, our world isn’t perfect, so don’t pretend your team has to be perfect.</p>
<p><strong>Authors Note:</strong> <em>Last month I failed to post to this blog for the first time. If you look back over the record you will see at least one post each month from the time the blog starts through August 2019 – then I missed September. Oops. I could make all kinds of excuses (I really did get sick right at the end of the month so my planned post was delayed a week), but the truth is I had time and material, I just didn’t get anything done. So now to make up for it I am trying to post every weekend this month.  I missed a goal by a little, so now I compensate to make up for it – then I’ll hopefully go back to my nice reliable routine. What can I say? I’m okay with a B.</em></p>
]]></content:encoded> </item> <item>
      <title>Docksal Pantheon Setup from Scratch</title>
      <link>https://spinningcode.org/2019/06/docksal-pantheon-setup-from-scratch-with-fun-pull-init/</link>
      <pubDate>
        Tue, 25 Jun 2019 12:00:40 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=1132</guid>  <description>Docksal has support for a project init command that helps setup projects for Pantheon. Since I had to run a dozen Google searches to make it work I figured I&amp;#39;d write it up.</description> <content:encoded><![CDATA[<p>I recently had reason to switch over to using <a href="https://docksal.io/">Docksal</a> for a project, and on the whole I really like it as a good easy solution for getting a project specific Drupal dev environment up and running quickly. But like many dev tools the docs I found didn’t quite cover what I wanted because they made a bunch of assumptions.</p>
<p>Most assumed either I was starting a generic project or that I was starting a Pantheon specific project – and that I already had Docksal experience. In my case I was looking for a quick emergency replacement environment for a long-running Pantheon project.</p>
<p>Fairly recently Docksal added support for a <a href="https://blog.docksal.io/docksal-integration-with-acquia-pantheon-platform-sh-and-handmade-drupal-and-wordpress-hostings-3852ad3063b2">project init command</a> that helps setup for Acquia, Pantheon, and Pantheon.sh, but <code>pull init</code> isn’t really well documented and requires a few preconditions.</p>
<p>Since I had to run a dozen Google searches, and ask several friends for help, to make it work I figured I&rsquo;d write it up.</p>
<h2 id="install-docksal">Install Docksal</h2>
<p>First follow the basic <a href="https://docs.docksal.io/getting-started/setup/">Docksal installation instructions</a> for your host operating system. Once that completes, if you are using Linux as the host OS log out and log back in (it just added your user to a group and you need that access to start up docker).</p>
<h2 id="add-pantheon-machine-token">Add Pantheon Machine Token</h2>
<p>Next you need to have a Pantheon machine token so that terminus can run within the new container you’re about to create. If you don’t have one already follow <a href="https://pantheon.io/docs/machine-tokens/">Pantheon’s instructions to create one</a> and save if someplace safe (like your password manager).</p>
<p>Once you have a machine token you need to tell Docksal about it.  <a href="https://docs.docksal.io/tools/terminus/">There are instructions for that</a> (but they aren’t in the instructions for setting up Docksal with <code>pull init</code>) basically you add the key to your <code>docksal.env</code> file:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>SECRET_TERMINUS_TOKEN=&#34;HASH_VALUE_PROVIDED_BY_PANTHEON_HERE&#34;
</span></span></code></pre></div><p>Also if you are using Linux you should note that those instructions linked above say the file goes in <code>$HOME/docksal/docksal.env</code>, but you really want <code>$HOME/.docksal/docksal.env</code> (note the dot in front of docksal to hide the directory).</p>
<h2 id="setup-ssh-key">Setup SSH Key</h2>
<p>With the machine token in place you are almost ready to run the setup command, just one more precondition.  If you haven’t been using Docker or Docksal they don’t know about your SSH key yet, and <code>pull init</code> assumes it’s around.  So you need to tell Docksal to load it but running:
<code>fin ssh-key add</code></p>
<p>If the whole setup is new, you may also need to <a href="https://pantheon.io/docs/ssh-keys/">create your key and add it to Pantheon</a>.  Once you have done that, if you are using a default SSH key name and location it should pick it up automatically ( <em>I have not tried this yet on Windows so mileage there may vary – if you know the answer please leave me a comment</em>). It also is a good idea to make sure the key itself is working right but getting the <code>git clone</code> command from your Pantheon dashboard and trying a manual clone on the command line (delete once it’s done, this is just to prove you can get through).</p>
<h2 id="run-pull-init">Run Pull Init</h2>
<p>Now finally you are ready to run fin pull init:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>fin pull init --hostingplatform<span style="color:#f92672">=</span>pantheon --hostingsite<span style="color:#f92672">=[</span>site-machine-name<span style="color:#f92672">]</span> --hosting-env<span style="color:#f92672">=[</span>environment-name<span style="color:#f92672">]</span>
</span></span></code></pre></div><p>Docksal will now setup the site, maybe ask you a couple questions, and clone the repo. It will leave a couple things out you may need: database setup, and .htaccess.</p>
<h2 id="add-htaccess-as-needed">Add .htaccess as needed</h2>
<p>Pantheon uses nginx.  Docksal&rsquo;s formula uses Apache. If you don’t keep a .htaccess file in your project (and while there is not reason not to, some Pantheon setups don’t keep anything extra stuff around) you need to put it back. If you don’t have a copy handy, copy and paste the content from the Drupal project repo:  <a href="https://git.drupalcode.org/project/drupal/blob/8.8.x/.htaccess">https://git.drupalcode.org/project/drupal/blob/8.8.x/.htaccess</a></p>
<p>Finally, you need to tell Drupal where to find the Docksal copy of the database. For that you need a <code>settings.local.php</code> file. Your project likely has a default version of this, which may contain things you may or may not want so adjust as needed. Docksal creates a default database (named default) and provides a user named&hellip;“user”, which has a password of “user”.  The host’s name is ‘db’. So into your <code>settings.local.php</code> file you need to include database settings at the very least:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span>$databases <span style="color:#f92672">=</span> <span style="color:#66d9ef">array</span>(
</span></span><span style="display:flex;"><span>  <span style="color:#e6db74">&#39;default&#39;</span> <span style="color:#f92672">=&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">array</span>(
</span></span><span style="display:flex;"><span>      <span style="color:#e6db74">&#39;default&#39;</span> <span style="color:#f92672">=&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">array</span>(
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;database&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;default&#39;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;username&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;user&#39;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;password&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;user&#39;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;host&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;db&#39;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;port&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;&#39;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;driver&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;mysql&#39;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;prefix&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;&#39;</span>,
</span></span><span style="display:flex;"><span>      ),
</span></span><span style="display:flex;"><span>    ),
</span></span><span style="display:flex;"><span>);
</span></span></code></pre></div><p>With the database now fully linked up to Drupal, you can now ask Docksal to pull down a copy of the database and a copy of the site files:</p>
<p><code>fin pull db</code></p>
<p><code>fin pull files</code></p>
<p>In the future you can also pull down code changes:</p>
<p><code>fin pull code</code></p>
<h2 id="bonus-points-do-this-on-a-server">Bonus points: do this on a server.</h2>
<p>On occasion it’s useful to have all this setup on a remote server not just a local machine. There are a few more steps to go to do that safely.</p>
<p>First you may want to enable Basic HTTP Auth just to keep away from the prying eyes of Googlebot and friends.  <a href="https://docs.docksal.io/service/web/http-auth/">There are directions for that step</a> (you’ll want the Apache instructions). Next you need to make sure that Docksal is actually listing to the host’s requests and that they are forwarded into the containers.  Lots of blog posts say <code>DOCKSAL_VHOST_PROXY_IP=0.0.0.0 fin reset proxy</code>. But it turns out that <code>fin reset proxy</code> has been removed, instead you want:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>DOCKSAL_VHOST_PROXY_IP=0.0.0.0 fin system reset.
</span></span></code></pre></div><p>Next you need to add the vhost to the docksal.env file we were working with earlier:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span> VIRTUAL_HOST=&#34;test.example.org&#34;
</span></span></code></pre></div><p>Run <code>fin up</code> to get Docksal to pick up the changes (this section is <a href="https://blog.docksal.io/installing-docksal-on-a-remote-server-digital-ocean-scaleway-etc-ed0c230ddb82">based on these old instructions</a>).</p>
<p>Now you need to add either a DNS entry someplace, or update your machine’s <code>/etc/hosts</code> file to look in the right place (the public IP address of the host machine).</p>
<h2 id="anything-i-missed">Anything I missed?</h2>
<p>If you think I missed anything feel free to let know. Particularly Windows users feel free to let me know changes related to doing things there. I&rsquo;ll try to work those in if I don&rsquo;t get to figuring that out on my own in the near future.</p>
]]></content:encoded> </item> <item>
      <title>SC DUG November 2018</title>
      <link>https://spinningcode.org/2019/02/scdug-november-2018/</link>
      <pubDate>
        Mon, 04 Feb 2019 13:00:28 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=1008</guid>  <description>Kaylan Wagner&amp;#39;s Presentation on applying gaming lessons that are useful at work.</description> <content:encoded><![CDATA[<p>This fall the <a href="https://www.meetup.com/SC-Drupal-Users-Group/">South Carolina Drupal User&rsquo;s Group</a> started using Zoom are part of all our meetings. Sometimes the technology has worked better than others, but when it works in our favor we are recording the presentations and sharing them when we can.</p>
<p>In November <a href="https://www.drupal.org/u/keso">Kaylan Wagner</a> gave a draft talk on using experiences in the world of online gaming to be a better remote team member.</p>
<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
      <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/Jctng6ORAnc?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
    </div>

<p>We frequently use these presentations to practice new presentations and test out new ideas. If you want to see a polished version hunt group members out at camps and cons. So if some of the content of these videos seems a bit rough please understand we are all learning all the time and we are open to constructive feedback.</p>
<p>If you would like to join us please <a href="https://www.meetup.com/SC-Drupal-Users-Group/">check out our up coming events</a> on Meetup for meeting times, locations, and connection information.</p>
]]></content:encoded> </item> <item>
      <title>Waterfall-like Agile-ish Projects</title>
      <link>https://spinningcode.org/2018/11/waterfall-like-agile-ish-projects/</link>
      <pubDate>
        Fri, 30 Nov 2018 22:38:18 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=846</guid>  <description>In software just about all project management methodologies get labeled one of two things: Agile or Waterfall. There are formal definitions of both labels, but in practice few companies stick to those definitions particularly in the world of consulting. For people who really care about such things, there are actually many more methodologies out there but largely for marketing reasons we call any process that’s linear in nature Waterfall, and any that is iterative we call Agile.</description> <content:encoded><![CDATA[<p>In software just about all project management methodologies get labeled one of two things: <em>Agile</em> or <em>Waterfall</em>. There are formal definitions of both labels, but in practice few companies stick to those definitions particularly in the world of consulting. For people who really care about such things, there are actually many more methodologies out there but largely for marketing reasons we call any process that’s <em>linear</em> in nature Waterfall, and any that is <em>iterative</em> we call Agile.</p>
<p><figure>
  <a href="https://preview.redd.it/i2aeyrivmjoz.jpg?width=640&amp;crop=smart&amp;auto=webp&amp;s=b92dc174a27bbef5174ef120c8b2b6df42227a95" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    <img class="rcf-image external-image" src="https://preview.redd.it/i2aeyrivmjoz.jpg?width=640&amp;crop=smart&amp;auto=webp&amp;s=b92dc174a27bbef5174ef120c8b2b6df42227a95"alt="Classic cartoon of a tree swing being poorly because every team saw it differently."  loading="lazy" />

    </a>

  
  
</figure>Failure within project teams leading to disasters is so common and basic that not only is there a cartoon about it but there is a web site dedicated to generating your own versions of that cartoon ( <a href="http://projectcartoon.com/images/project.jpg">http://projectcartoon.com/</a>).</p>
<p>Among consultants I have rarely seen a company that is truly 100% agile or 100% waterfall. In fact I’ve rarely seen a shop that’s close enough to the formal structures of those methodologies to really accurately claim to be one or the other. Nearly all consultancies are some kind of blent of a linear process with stages (sometimes called “a waterfall phase” or “a planning phase”) followed by an iterative process with lots of non-developer input into partially completed features (often called an “agile phase” or “build phase”). Depending on the agency they might cut up the planning into the start of each sprint or they might move it all to the beginning as a separate project phase. Done well it can allow you to merge the highly complex needs of an organization with the predefined structures of an existing platform. Done poorly it can it look like you tried to force a square peg into a round hole. You can see evidence of this around the internet in the articles trying to help you pick a methodology and in the variations on Agile that have been attempted to try to adapt the process to the reality many consultants face.</p>
<p>In 2001 the <a href="http://agilemanifesto.org/">Agile Manifesto</a> changed how we talk about project management. It challenged standing doctrine about how software development should be done and moved away from trying to mirror manufacturing processes. As the methodology around agile evolved, and proved itself impressively effective for certain projects, it drew adherents and advocates who preach <a href="https://en.wikipedia.org/wiki/Scrum_(software_development)">Agile and Scrum</a> structures as rigid rules to be followed. Meanwhile older project methodologies were largely relabeled “ <a href="https://en.wikipedia.org/wiki/Waterfall_model">Waterfall</a>” and dragged through the mud as out of date and likely to lead to project failure.</p>
<p>But after all this time Agile hasn’t actually won as the only truly useful process because it doesn’t actually work for all projects and all project teams. Particularly among consulting agencies that work on complex platforms like Drupal and Salesforce, you find that regardless of the label the company uses they probably have a mix linear planning with iterative development – or they fail a lot.</p>
<p>Agile works best when you start from scratch and you have a talented team trying to solve a unique problem. Anytime you are building on a mature software platform you are at least a few hundred thousand hours into development before you have your first meeting. These platforms have large feature sets that deliver lots of the functionality needed for most projects just through careful planning and basic configuration – that’s the whole point of using them. So on any enterprise scale data system you have to do a great deal of planning before you start creating the finished product.</p>
<p>If you don’t plan ahead enough to have a generalized, but complete, picture of what you’re building you will discover very large gaps after far too many pieces have been built to elegantly close them, or your solution will have been built far more generically than needed – introducing significant complexity for very little gain. I’ve seen people re-implement features of Drupal within other features of Drupal just to deal with changing requirements or because a major feature was skipped in planning. So those early planning stages are important, but they also need to leave space for new insights into how best to meet the client’s need and discovery of true errors after the planning stage is complete.</p>
<p>Once you have a good plan the team can start to build. But you cannot simply hand a developer the design and say “do this” because your “this” is only as perfect as you are and your plan does not cover all the details. The developer will see things missed during planning, or have questions that everyone else knows but you didn’t think to write down (and if you wrote down every answer to every possible question, you wrote a document no one bothered to actually read). The team needs to implement part of the solution, check with the client to make sure it’s right, adjust to mistakes, and repeat – a very agile-like process that makes waterfall purists uncomfortable because it means the plan they are working from will change.</p>
<p>In all this you also have a client to keep happy and help make successful – that’s why they hired someone in the first place. Giving them a plan that shows you know what they want they are reassured early in the project that you share their vision for a final solution. Being able to see that plan come together while giving chances to refine the details allows you to deliver the best product you are able.</p>
<p>Agile was supposed to fix all our problems, but didn’t. The methodologies used before were supposed to prevent all the problems that agile was trying to fix, but didn’t. But using waterfall-like planning at the start of your project with agile-ish implementation you can combine the best of both approaches giving you the best chances for success.  We all do it, it is about time we all admit it is what we do.</p>
<p><figure>
  <a href="https://www.commitstrip.com/wp-content/uploads/2018/11/Strip-Plus-qua-coder-la-feature-650-finalenglish.jpg" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    <img class="rcf-image external-image" src="https://www.commitstrip.com/wp-content/uploads/2018/11/Strip-Plus-qua-coder-la-feature-650-finalenglish.jpg"alt="Cartoon of a developer reviewing all the things he&rsquo;s done: check technical specs, unit tests, configuration, permissions, API updates and then says &ldquo;Just one small detail I need to code it.&rdquo;"  loading="lazy" />

    </a>

  
  
</figure>Cartoon from <a href="https://www.commitstrip.com/en/2018/11/20/one-final-detail/?">CommitStrip</a></p>
]]></content:encoded> </item> <item>
      <title>Thoughts on Hacktoberfest 2018</title>
      <link>https://spinningcode.org/2018/10/thoughts-on-hacktoberfest-2018/</link>
      <pubDate>
        Thu, 01 Nov 2018 01:15:25 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=837</guid>  <description>This year I took part in Hacktoberfest. Partially to see what it&amp;#39;s all about, partially to get involved, and partially the free t-shirt.</description> <content:encoded><![CDATA[<p>This year I took part in <a href="https://hacktoberfest.digitalocean.com/">Hacktoberfest</a>. Partially to see what all the fuss is about, partially to get myself involved in projects I didn’t know about, and partially for the <a href="/2017/03/why-i-wont-wear-your-free-t-shirt/">free t-shirt</a> (which do come in men’s and women’s cuts).  If you haven’t run into this project before it’s an effort by Digital Ocean to get people to participate in open source projects. Once you sign up they count all public pull requests you make on Github toward a goal of 5. I participated both as a developer, and by tagging a few issues on my own projects so people would find them.</p>
<h2 id="as-a-developer">As a developer:</h2>
<p>It was a great excuse to go find new projects and look at ways I can contribute.  While I’d have plenty of experience on open source projects, often they have been outside Github or are repos I have commit access to – so I don’t open a lot of pull requests on Github. That meant that Hacktoberfest was a chance to find new projects and practice a basic process for contributing code to teams.</p>
<p>In that regard it was a pretty good success. I opened six PRs on four different projects. Mostly they were small stuff like linting code, updating packages, or tweaking a README file.</p>
<p>In terms of drawing me into projects we’ll see. I did keep up with one after I finished the 5 required (hence having six PRs), but I didn’t dive into anything truly hard on that project.</p>
<p>In terms of getting me to provide truly useful code think that was limited. The largest piece of code I wrote was initially rejected so I re-wrote in a different style, and then re-written by the project maintainer the day after he accepted the PR. He was really nice about it, and it helped him get something done that had been on the to-do list for a long time, but even that was example code to be used in classrooms (which was why he was so concerned about style – he didn’t want it to be idiomatically correct for Python he wanted to clear to beginners).</p>
<p>It did give me a chance to play around in other people’s code bases and I did resolve some issues for people that would have otherwise lingered longer than they already had.  It also forced me to meet other people’s standards, lint to their specifications, and pass their automated tests – all good things for everyone to do now and again to see if there are solutions you like better than the ones you use every day.</p>
<h2 id="as-a-project-owner">As a project owner:</h2>
<p>Once I got through the contributions I needed to get a shirt, I figured I’d look over my own projects to see if there were issues I could label for beginners to help them find ways to get started. I listed several issues are both Hacktoberfest and good first issues. Almost all the ones I flagged as good first issues got PRs opened – sometimes more than one.</p>
<p>I got two problems solved that I wouldn’t have known how to solve without a bit of research, and those were great. But most of the PRs were simple things that took me longer to solve collaboratively than it would have taken me to solve myself. That’s okay, in part because some of my PRs caused the same problem for their project maintainers, and because it forced me to final learn how to setup CircleCI so the code gets checked and tested automatically when PRs are opened in the future.</p>
<p>What I don’t expect it caused was anyone to be truly interested in the project and helping it move forward over time. So while I solved a couple small problems, I did not get new help that going to keep engaging. That made it useful as a sprint, but not useful to helping build great projects.</p>
<p>But even if there is room for improvement my shirt is ordered and on the way.</p>
<p><figure>
  <a href="/wp-content/uploads/2018/10/Screen-Shot-2018-10-31-at-8.11.24-PM.png" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    
    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2018/10/Screen-Shot-2018-10-31-at-8.11.24-PM.png" loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2018/10/Screen-Shot-2018-10-31-at-8.11.24-PM_hu_17dc5838956dacba.png 680w, /wp-content/uploads/2018/10/Screen-Shot-2018-10-31-at-8.11.24-PM_hu_a58947b16a9ce2f9.png 850w, /wp-content/uploads/2018/10/Screen-Shot-2018-10-31-at-8.11.24-PM_hu_6fee052cbb0fdd1c.png 1020w, /wp-content/uploads/2018/10/Screen-Shot-2018-10-31-at-8.11.24-PM_hu_7fbe9b9cbe4f76f7.png 1360w, /wp-content/uploads/2018/10/Screen-Shot-2018-10-31-at-8.11.24-PM_hu_eab529e600f2b8e0.png 2040w, /wp-content/uploads/2018/10/Screen-Shot-2018-10-31-at-8.11.24-PM.png 2144w"
     data-src="/wp-content/uploads/2018/10/Screen-Shot-2018-10-31-at-8.11.24-PM.png"
     src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAABTCAIAAADY9pgdAAAn6klEQVR4nOy9R5NkR5IfHu4hnkjZVdXVAg0MsJjd/6w6/I0HGmlGoxlv&#43;0n4EXniiTzwQvLAWZs1YASABtBoUSrFEyHcaRHxMiurKrO6ge1uzhoZ21uDSvFePHcP95/LUv/wD/8xHM&#43;5LuXFApcrLjVPKwx9fX7&#43;&#43;YPpv/0P/&#43;5f/ft/c/LkkVRS/L91eDnrnn/9x//6n/7z//wv/&#43;3s5evgw93PMHP8H4j/D5sXlTv6hGbj&#43;KaRMB3z2NCDWtoVN61ATF&#43;jEDwxfdwn&#43;pe0AIBCGOh73&#43;fyjy3xBQuh7PEzGpfYWixLMJ5LFFKi6Dh&#43;Ln4YAKVUf24n4NbTwkakmBnSg32gtXujG78Sb/4bbm9VMNx5Mb8eT4BGJmQUhIgEmgNxY7HpwXpRGxACEZVSSqsP9lA/e1FakdYAWyrkn4fE8O3iuVnb61yTGEBsvg5p7V4NEeMrgQBgD5l3r7zLhs0V1OPmG6/GyjsU3MrxShmrFSuZ9c9mA4CAt7m4s4u33fp9LiKytl8uV855paRSCtOSUjJzCGFLvrzBSCAhfAhEjAgsBAUSYmBefq74UaJ42NOKOt25EEK8bLp&#43;VMQUSSzTIqJ8I6VUVVVaa5H5tG8dEP9hqWf&#43;haWZUgK1uBTC6WNbaPaaFQrM3x1U143vE5EPwXvBAlU8I3GX78aGSJfBHMH1S5wf4eBjbL8dQlgul99//2OzXpuiqKtK6XhEi7LkxBsK8Xj44EMIAFAUhZSy6zrnHCTieudhuHmSrETfSNDEAGO0RNk0Td/3ujBFUSqlQHDfW2IuTFzee&#43;ecEKKuRycnx1LKW2Tdapg9VL/5fGoa1jYoKkpmob2V5LEjbHtBgqWM/&#43;A2C5nY93Z9cbW&#43;uCIfqslofPzAjGuUb7ETTNGgB&#43;eCdcQstcIstt6T94mK5i28jLxj51zbNqtmXUYSCxVPgswH0TnPST0557z3gKh15E&#43;0k0ScpHg4GlkOCCTKeDISDxBBKYkoMzPiW&#43;lUZIYF511SQT54HwKIQRe9Re7uMCKZ1kGDqBl6R32vjC0qw5XqFa6saD1rTZMx1ZWI5hdu0pG61frNn57/9IfvXGePnjz85G9&#43;PS/MQcIlbRCxVG&#43;75Wp9dtFcLgIFWZWqLJjZrhvqbV3X45Ojaj7TVSm1Ain3aratWSqM0ckyhYRAsO&#43;1jgJbloVSKtsJADDGKKWyzCazgRtDfa3WEZEpnhwAUJGb0ntPRFnhZKXk08paiDcayRhTliUkDt2i91ZsGdKt7mCD/HRqrARR74Pu69KXpe4qCEC2JD0K4zEbw3hb&#43;7OIMtsuV5cvXvVNXxjtu56JeJ8sxL1679quW6zWb84vfnhx8d0PizfnUZiqEiIDKKxb5WgynTx4&#43;nj27Mn49Liaz8y4VkWB8gZTOT9FohkJ8MS&#43;64kCAvTWlmU5nU7rtCJNk5Xems13tMMD19Onb5n3rVneXmprM/ZK3fD1DS8GTuzyXoAaFwiSgbrOrTtoNE&#43;FVkIidAGbFrsefBC3MR/qoqjGo9Jo6G1Zl7oqo8Du20TobXNxdfXjTxfPf7z8/sXlDy&#43;Wr8761doTeYlBxt3rQIXAtixX3/908c3z6ZNH008ezZ49mTw&#43;LSYjlOqasclOSGV0PS5gUCyCSCJorcuqLMtKG6O0RngrKnlv6yD0uq067phSwep0ppmFZxZNw8tLIUbYoLhay9WV1ARtCyHcPjsIuizq2WQ8G2sQ9XSsq3Kv/iEfmqvFq6/&#43;&#43;OIf/&#43;nsT9&#43;v35x3y1U6Lkwgg8SQMVw8nsH2Pqzb9uxy&#43;cPLq&#43;cnza8v&#43;O9p/qtPzKgG2EoZRKkrqmJ&#43;TCMPAiipci1hbNS0NHVhCmPwACT9KCyB&#43;&#43;51bYcHlaTmI209rbrgemf7PlAvWsB1C00HfQEJsd2&#43;CHE0oYWpT450VRbTEUgczNquumD21i5evn7xu69f/Par1asz33UUfXRgqamsqap0Eb0&#43;6QO2LXQ99RH&#43;Udu7dcuBytm0Pp7H43XjmEctXBSFUDqCmLQ0ilpiqVFKjADN&#43;2u4BdcUgR2g&#43;f4X79PAW4KLW2Zg0EMqGnfitg/LhtfWO/AcJAQWgZLmuU19Iuq7bvHm/OLs0rIQxtjedYu1qSuU1S7bIyhs2quXr8&#43;e/7h8c&#43;6bVhBFRkmksvQPjmg&#43;rWsoZKBVD28InBccon513sejcNG8PrOrpj56IOQ1GAbBkoMJjp1DKY0ptIomlG237oJgSkTe6B/ePCgzRIgZbaYx5kMcBYDbgIg3DhfnkMKOS7A1A&#43;pPL9umC1eNf9PAgp0tiAhlwgl790iB1leL77760/dffdNergzAbH4RAum6VEUhd4QrsqppF28ulheXbRNVmcq00YpHFc1n7sHc1wIxBGhV49AG7HvhQ7LbwbV9v1j5to9oZKs&#43;mYEZmWRwYLvIAIUFoGffdhG50wbOJxCJIuooGownYnaatubx/S6&#43;&#43;yvvCvx&#43;eqr//vuF9&#43;QCO6FtTWwYmATv0TzDhRJZz1&#43;8/O4P3y6vukKq06NmNJ88/KLn3YBdtL/UNe3qYtGtGucsBAJUaBDLUkwmYTppxvO2VMCEdTOdwQMScrmgpiVPUaStc03r2o68Zy42gZYoSTKieyW4kEqWRYKZTBE/hkBJAtIRGH6IhO0zcNr6BO&#43;H5PvIk3cpblJ/Q5Fr&#43;7B9Vb25stGXkVjWKEemLWTfbvi3//oR0buu65t23TmvuOt631vKtnorqQme903XLlfp3ei8p1sbUZU0nYTxpKvGjSqcZ6kN1WHcN7pdk&#43;CoBElEl63tXdOS9aK&#43;IUCUYLgQQqYwoUKIKopZcZT2rH0goT4QImLZuoZEd9iopw9D/RsLALYw4E4YNP4yBOOeHBUIoBWWddWMiwWrq25fMPvGpaNUReQHrAUrwXg33pHUiG87ajvhI073TDYwBg8JOGIIbH1nZWdZW&#43;od&#43;5CctRAsBZ2wdnDed13IDtStq8cDlkNykeZMJEIQPl4ckje1DeRmXQQbkHYNjTjHKTdCeyDMuXfd8xkAEV2XhMkpg4B4IgFh&#43;/kBHASKkqQeztLpBvRS9SR7ghBF54ACgsEJmB7NT588HI1aI&#43;XRfDKaT1SRLNt1dCcqK2QyWpVVQX3hE0ecs3q1MhdnY5Rd4RyZ0obCdlO7wGYZeus5BAQdVbtBJTlJ&#43;&#43;52ki8a3eCs6H0ITATJbY3eOxEmtZOVVcihDpe4foDW28sO/hpxxrqHyL3rkeFmba9caJyNFDASsfPce1ISprWqDW79ZWJue7pa&#43;8YG9e0FCZSEqlflVWEuEXwgKQ7ZYIES68nk6ZefG1N0y7UUOJ6Ojp89KRMYvSEISo4ezE//4jNBYfHqTF1crpYL0TnRdfLiYuQC6qsJKfYR0lTBat&#43;JEGRVFrPxdP5gNp/NnjyqjubS6FseRhL/4JwjorZtIQmcFEAAIVn/HMSIeioQhCCtjcS9SestZYniOcghhxAVX8ihDgCRokfxmMEOS3IcgjkbF1UUhTFGpDOKIKoCJ3NTSuGJlk1YNH5cyi&#43;f1o/nRinMt3SeX13ar39s7CWrr9xpROWq9GLkeew9iOj6Hsx/AWI5qo8fn6rAq5dvRKDxydHk5MhU1S5aj9i8LGZPH0klZ08fL169Pv/p5ctvni&#43;&#43;&#43;5FXLbe9CldjXI&#43;irhbILFNgjLWsn5yc/ObLk8&#43;eTebzajapjub6hiMmcvCuaZr1uskBGQRMGSNJgZyP&#43;kqiBAQKKbwTnWSjtcIksRkLDkH8HKRKh0ORygwgYokJBEZ8Fpzz8VRFbYbbZGII8WBiuoKUUmu91RASodRyZIQP4D1bj7Ox/uJR9fmjEgCsI0/cOyIW3591CEKdnfwdo8qRcggW7Qp9Lyji8f0MiBogalVat83zn8g6jSiePhqebedzqFQ1nZiqnJyeHK8&#43;ffDyla7rb1dNk5AlOyeRcBNsiUYJActi9vjh07/5q9Nff1GORtJoVCpFJPcfR4kyiuomXkmCRCJUJhbxTt4jiarWehve2R6CQcDjFjAJKA&#43;2OumKHOlLqndPXEgiKq0RkUTOQ4jeUd&#43;4vo/fbXoKJLSEUSkLjYsmvL6ybU&#43;9p9dXrrFMDMrVR9F5CU7aBvoV9mv0HXobfaJDqb1Er2Bde35JnZ08ORXX6eYbnwIlQaI0xoxqafTqzcXr6aR/ecbWX0el8iPFxwdpdDkejx7M69k0OsD70gPxqlrVVS2lysHLTJSob3wgppSbwW3iLIOloiiyE/COEGhXR9108Pd8EgACZN9bdJZWC4dJhYScAkqP2ll6cd5//aK9XPvei1XHFy1Y0Ep2SyAHrpP9KvLAt&#43;haaVfI9g6Svb6lLLQZVbIqBIAe17IwcMC/j7uLKlmZuqpnk3JUS61Ewlk5L5NwyCCWUitTFioKvrwnORP1gVKaB1HN14hyL2U2odsgaNbmOaqcc2cfxAVj3kZqXRCN5RAou&#43;2lwQDI8XRmdIMMsmdYMbQIvgAFoQdvpV1HBvQrdGu0Lfo2QutDUChSSpvpuDie&#43;67Xs3FiwL0PBiCVKuqqHI&#43;UMb6zKbMCGx4QC5RCKK2LKKcmKv0DlGJm71zTNF3XRbsnsw/AScXnrEuEYAiojamqSimlk5a4P2n8c9ctRmZUxKhIFV6WQaQkPaDXSKoQUpVGnR5V0ujO8VkDf7yA/gp6iyqYMUILFEDZxAy5vZ44hIWifpflfDr/4tNgXX38QEYrdB8Dsk3TxhR1rYz2Agb4nuxGPOMYsUiU68JIJe&#43;7WNLLzlnb9wmVSUS5wYVik66nDA2N0cPvdBhW/Pwqiq0Zud5U1KKSdEXlJFTB03CqgwYySiijjZwIJXSBIE49ywoXKJdLVH50jK5hqRll&#43;qcYlZKKIJA0DLiXsihlNZ8&#43;/PXnTBR1UaHfdrKTPEipUhoyYWFKVi/FooGBIsE4YWsBexy73adHRK0NlyyGagHYBCkgG9Vo1ZLyEUJYazOyzJBnY62GdHeyvdskvthJxuyYgfzO5q2cFNNay92cXTx0inQdylmoRCBKwVEOWlgtGyEvgzxzeNbhvKCHtX98jJO&#43;BigVqyL5TAHIR2MQf4YAIkAgXbJUd3PCGYzqsogIPQpvggzvqFspos30VPF/s/zHx0gBzSS/EQTvyWhfP6jYUgsG8tFGIDNWIRAJOwF67yP1I5sgRdFDpufWSETAmrI6PoRoSBBveWecj9TAD866zhTF7ch2fATJuiBThzJCpyQRaDVeaP37oF636mUjL3v8FXbT0bIcSfPghHCu1Posok/XSdug6zBYoBSyR5mOhRLigHUdwo3vuDgHJ0JEwmEL43gTuolsoBC899bRnRTQ9VV48IO8c33XZ/u9Edgcd4gUjGrfRAnN18lZA87/d8ePzVzMH72bKog8SUYlHS&#43;R4H9K1m&#43;&#43;m48dIEZ3StehmvmRcUKT1AKlU&#43;qHUrdWacK1B8lhAlc9OFAA5YjtTJWvv44GgBwEh76HYCF44Ogei6QNBBz0in/Wysnh0NuQ8t1MGSjAgFmYRUBvnY8feEuZXz4DIbpDNBSXRFps87TSGL0LOneU9XDhbRXMnjKstLbBslt2e6uCsue8Uw0HrIyv52586kLnhGKMWh0kskQXARCGwGPsnUiFJimoDuyVWf60Azfz&#43;URGSVqTKuIheB&#43;4jXMezXnvXCrpCJy05NaYISMHdM653pL34mYya8/lklxLIbMrUJZlrv/JRMlulzxQV3Fr3ap0e5d1m6&#43;wgUC6CuUktJJ9EBwwBAU4U3SsPYK4CqC8077FYIkY&#43;5VsUEUzi5h&#43;JgucRR4QC&#43;3rIzK1wPdRlBjtTIgCbl1yl1I4JW8&#43;AfeoOQYG9MH5eyiSLBbFT1onklseoVNRjMfjDDe36uXdIf/7cA7ivgQFQSHqEtuhXUvylYFPNP9d1ZeSnpNaWT4WTUF94zH0HfRShWIaLa3UrEyEPajydsBoPz4Ouj4EhH7u/oIPtutt16cqwRyc3IbLo20TRBFbtl08BAeKXGCIcShjjLUuh25CCDYttQn639IqHyMBEH2tgL6LHpVdg&#43;3QtUhOClH78BjbJ5V7CGrp8KRwGmnl9dpLR6BImUh6XZEZJdij03EKqGUwI1ZG3K0K/QXbSzFhZ3sXfMSdSkI&#43;ARtJT3oPApPte9t15Px&#43;FTRUD5qqrlOyoI9&#43;WfDrdZMzA0VOi8IALXMUKPvA/9xnuO/xhhMQzae3QF4ARAXO2kq&#43;8v1ZZx&#43;X/Wd1l/3jpcXvV/K8Fd46BeSZtQCZ2cDSRDtGjiWIdBreiw0YVHZRVEfzyeOHrus5RRQzkVIgN4IqM6rMZARSHoahCfApBcawMfEgJaerZ&#43;F62/Oq6HuT6J1dMgQoyrjePQr0Xp41KpKoz8GKcGb5q0urAn5S2QJC68Xzlf760l0u12yFirBHGTGkbnIpNm3t//uqtAcAXZUPnj3&#43;tP/b&#43;dNHvu8pQhjaMiAHbnRRTB8/nJweK2P2WmAWIgjRIL4x5k1VdogZzAxajakK4QjwSAizcRbeV&#43;zh3sfLuAkzdqeUFhqCE8Etnf3mAtor/kaGQtjOi7MuvOl87yPAVQI1g0ooN4JR4dNRSsV&#43;EFyuE3kPO0yO2&#43;zJo2I8Snn2wLlYYVM2mSNoKGXEj9PxkF/btxyIVwi/lfI7pTsiSEFnQiREVPJBUfylNlMpZzxA&#43;xyMey9I&#43;m0PmXwxaUgBbapKooYksejZWn7tGRkCg2V0DJSkXoVyGvU&#43;IISAomOQqYiRUkLPwfvrTEIpi7rSZcE0lKffOl85c52LknczMLuLhfACLgT8XvBXqeJUeC&#43;i3ymEVKqqHml9VJWEUZPqzdm6WYfwYdb2EMCtGFqUj8DQkXKkBUf/gFQK/KQ3VShG2dVKQQg/fD9eSgHR&#43;232ueE8773yu5Ep2QyQiAoxZwvzOVIACrKTmn3IjyD2N1cOMEZKZuli8H2KLAhGGTDa1yG&#43;kKLonA9oDhNw8IJ8Diqx0unbIA6Hhf&#43;56xddNQIoIY4BfqP0fDS2phBEmwQqSK1mxnwKMPrI1M&#43;pAArg&#43;wj/uyYlPCJAQG/Rt&#43;BtdBFyui04CH4jgKweKEuAjrH30vmo8EmVZMpQlFSMSRkScH849yMvLcSpEBqhNYaGZOx1pb8GnLIYpxDFx9wxRwxqZb/UqzdmcRU2znzWK5E3FDblbhHnbAuvVD2uCbAj1Xvlg0z&#43;D7JUpE1EsqiIhfOewgdtPvx5ywhxkuh7a0NJe4Ys&#43;&#43;4j7ifiFe&#43;F62V7pVev9fICfeDrTV3XY2SFySB5EwZTF/qIWXjAHmRQkpM/jeTRt&#43;i0CDaV80iG95ZLel/rkGeVDPXHW9nIB08iemE9uBZdR4FFhqRSb5S&#43;irpdDkG6jWIHddlLoMDRHbNAjBxE8BisAq/WTvbHyKlT5/6M4//dK1UhulTZkS2vJIWsymBqKkbBjEhXpEpWJgU3ZVRBOQHDpHDxKop8tAwu9WJ4oABMWoFqSfpWCk5diH9Gjdpbm3SoiUzc7Em6zwe&#43;v&#43;RhE1O6dYVtPuf6Y4FSwibpehHFn1JkIRTjUM7izxzpQS1AYPAp7O8Ek6oW36diTc8hcBgsdYTjRqMbQ/AgtsUHezYnbs8&#43;&#43;OArhUJt23bbJrrdd7ekSXljl5Nl29RVThpsEoycIxnX3wHYZW3&#43;dcippVoXGMwnp5yo3tZaD2klpoh5bIN2jeijopeGXceySN5ZEZVjCjxT3AgCaiFInfBluqu3LlifsiTJUsdTZMe4gbF3SU8h5NRVRPdKHipLuf21Ics6&#43;B6wqaPnnVfuZScThfW6ef3qVdt1mQSbPAlKiZklWuvg/Wq9ds7matFUlSGN1iH1z2RS&#43;pAbhoGHdjsZVUNKByUJ1Cixbdre9lprY4qUYiOXvl7X9YOjo/FodC0BEUF6cB12K4RuCE2nFG/GQkAUOALLIWiRIobqWCwZyHFYeS96cilEFnWT16odgWsFh1twI/UeuWaxXF8uKIRyVI8fzIq6uocHOdubmoR9cI6IUUmlNaT&#43;UO8c&#43;VSRmSqCcmrxwNVS6iyEruuWy2VuWc2V0ohoisJoraQqqxJSOr7rOu9dqmDEVJtVOue7nMsUwBSGoq5NngsQQ5J5TCQujOnT4oQOE7O5a1uXPjMajaiu5U3SiG13BYWoZ6JZ7jAlWlKhD4GpeUixxA8r019FL8yR7AP2JFO&#43;Fpil0OjaaBv4dkiOmV3Xn/348vvff9O3/eknjz79q7/QhdmfIo5nhSIllqt2sWoWy3a5CsGrqiwnY6W1t7ZNnXtGm2oyLiejcjyupmNTlrd6VAcOpIRXVVUhrUw&#43;4f11ZpOCdy6nyaqqGpQngFbaGL1RTZyTjnAduM45YtjOOyiKQis1nXofvErFp4gSgK11zrnU7VTh3cOKknVFehQtsK4o2eEUZo5ET3nfLjEgtyqzYtvF&#43;3tmF4Tn5EOnUkiSmx6xPeiTmNqmffXidbNqTFU&#43;ti4rlrveJwVqV6vzH356883z8x9eLN6cNVdL772sy2o&#43;1WVp2669vOLOGmNGs&#43;n4aD5//OjhF58ePXtSTsa3u&#43;95yAb7eJxFGLJqItAQ23ZgBYtOdcaYoiim0&#43;lkMslNYUND9rYCZeDndWJoO5fjesjExpjvWt3tnJA9aYacmDR1KCZkxqEYhWJMZhQhUIKewBSVSqpgwpSEUovGE7MP3LtcUbPtcDlcGZf6FBUiWMtdj6lmXeyrXmGKsn/&#43;w4s//Y/ffv&#43;P/3T54lW7WLq&#43;j4ZOSVlXstDButB06ElJacqyHNezR6ft5RUAnPzqmbmp2bI4BBYu&#43;S4kVR4lIFGCoJwPy/MIstnMubOiKD5EQmYfuEoBUQWsiiT7Y9ZRGUrfwoB8LJCXHDRQgaFAVldNyJVHmxjlu9w5lUZJaQQX5LVghH3kz&#43;K/WL7647fP/9fvXnz1h3axSg1fSf8iiKYHKQURhCgOQQi7btqrRb9YoxD1fFbPZ7ca/4Z0rynVZG6KFFGBKKiV4FJCpVAhDKX6ifq5IvqjtSWJoUAMWSqINyZtz5VdR2Xue&#43;GtCA4pSOBSidqIWgvlwi/xbwGxqMsHD4/K0oymY6nVHvFPhfzry6uz5z&#43;e//hidbUIvcWkallKrwwrncKWjDmd7VxULsF1vLz84ac3f/ru&#43;LNP6vl0KNQdbhyfUBlT1GM2YYsXNcJY4Uijxm049zo1vw1k3cXvH2al6lkpZriah7MRXCnVC/CEISVBOLUxgUIhWaiNOoQ7Acr7GIOI1WR8&#43;vmnrrOzxw9NWex9KgrBtl2/alxvfZp7BiAFylDWdjyDshwZLsFzoNB0sFxz11GIMLFdrZdvzpvLK2/tUKe&#43;fTghlOAKCEVuZUnF6MySvOs55GhXasW4WVs4WO88u&#43;MD8iDdChFqLZ6W7mnZ1cFiNBtx4wrTDJJE3N5T2we18zXxru2zSbRd24WmY&#43;viv7A/8pgOSjV5eDx5eLxarbrVmjkCbJqM/dFJMSrmZT9F2/a0OJe&#43;d2xtIBISsDC6LCGXtu1IQvQKBSN56TppnZSylJVB9N53Xdc5Gx2ZoeQtlY0mFJadD0QsyuLapfqAKzo1WkKJAaxdr61N/RCVwflYj0tZ6Oh5NF0IIdmtn5v5jVDPuvXZxZs/fOvbHqWcPj6Nj3kTsIAAZfT09OTTv/&#43;NZyKjXn/z3DUdlCWMR348DqNqUThC18vQdA2MQioWC9V08vDLL5789a/nT051WdwsfB9OKqYmfyXRKNQSgaWX0cMX1/VuA8pMCTbMr3&#43;4FoHbJBLQeb7oe7tq3bqzziPAuJSBIt4pdJSMzoUmnwC4Nc3sbamMXLgl0pwfu24pBNj7UBERyHo6ffTl57IsVF3Kwrz64ScrDU0mvqxX5fyq1ApJgDWTxVSo6aScVebJrz754q//v0/&#43;6svpo4eq2KPcogPDQ71mdn2zgO/0ZQxNoVKqsry2w1n83xeV961c0RcfqXdi0TnovAExqVShsTJYRKs3jPHTEqeVUrlU8vY8uftlJPUHSGNAKYj/oUHJvV9Jo2VkPZ08TB10zWK17FxL4MdjLgtvikaWITLKVWVk6UOsnn1y8uXf/ebpl59Pjua6KPb5wyl9F4L3QUnalFWkGEXyYlOttsqNZ0qJrPflZqTWe6qDu486OTksELTCB2P9sIIHtZxUymiQOLSSUnJiAvHmBPzcmwBIo810DFrJAxZ4&#43;9E0X6acHs2nRw9Ko9Wy0c4a45S1FEUEQzS8OCWlyuLo5Pjh08eToweJ&#43;nuZikrruq7z0L4EciIc0lpXXOWpVzJ7PSCyun/njB4MAwXgOqS693Nbi3kHVuXKgpSbkzip1akyzybqZKrGpVQpDh2IXfS6qE1VyHvqPt/aJE4&#43;OOuEVKNHD4N1qq5CKnaGQ&#43;o192oZU5SFCVRcXWnrpCdrQkdFin9zQU7zSukoraYsUnTv4DY2vRLU98Fal&#43;3ttqcstWEQCEjd8xRCyOK/W6m4LX7eHa6IiDSUc&#43;XKjByWIM41IrjbWEnboEgOi16Hvod/pFAUCksjSxNBZ44SAYo82MqH1JVKYmDAHkV0iAHEfdOe//Tm9YuzZeOjuTlfyfpCGVNNRrBnbNawseyXKsGqaaDrVG9JLgwpF6J3ryhMZChGx2m0wH6FtpUA73yzXq/XTUitDDnUmebEhTwpaAP/h8luqTQId/2ANClxKHMf&#43;oSTfU7hJZISdep&#43;TYrO0/WpGogVKGSrE49dVV3blRS7z6xACaZQhVLMoe1Dbwnguo3HB3Y&#43;3fe6xeYdzG&#43;KhIRmsfrx6&#43;&#43;&#43;&#43;d03V1eNADGd1q631bgu6hQ&#43;20t&#43;ECBR6fiQ8ea2w9aOYVEw5Ag1MJtSF2GqtcS34XQWuctmGOSZuvOAh14Wxo2sbkbrCSLU&#43;kbB&#43;m7b&#43;7bjF9IJYGLA4bIpgkvJfdmZnMoiNwJmFZctPAEJKbkwXBjhhai0nJRFWakoYX3fBB/IR6W/7c8ZGoXUrsf1TqaA2LX9&#43;vXZ&#43;bc/nF20DMLO6&#43;MHI9/&#43;6lA8Ll8b02ZlPAMiOA82IPQmDeHIXpLWQiEopfcGQXd4CTJN92SqMaciIt6PJPEp0J27UgWIIVzKQipZllVd3&#43;gTvsvj3UaBvfMkDu0nbgCJysKfHPtPHvuF80fH9nS2Zr66urRtQ12u4&#43;YMQ1PIX&#43;R&#43;zq0jln&#43;8zRUbOtw4TzxJBcnR3eUQmOm&#43;WFIKHymdZlAn5QDXVhGGgSK3R6IcXChlUZS5UXtTdphOhDE5l7I7RjJ/RqVY9C4GfY9YKJITgavSPznt151dWntyujiZvWhr&#43;KGbNa1xPboghqAn9Z6cZ&#43;9pQEG3rnVoCLXYhGKk0dV8Onn80I56EjAd63o&#43;iSDr3ubGLUjmrJp5Z3zXtlHRh7i1cC8v0/Dcvu/63m6jPduI8aZLMqoRpXRqnLkRj/twGJSVolFN81mQXZiN2vns1bgI7NpVM7tqtXWc9P5A/cA&#43;yjDcZsBb94eI5Xh0&#43;sUzUZRPWiuEqEv18MlxNZ3knM&#43;B3aXqlt56a/Ok9wgJdviVU2beOrsZEHToSmnMhI0muGmiepEKNiNCESGkOmmmHHgoAYQ2ZlfX312/rODpdqM2ABWGqkqEIN9cqrXnhrrx6Lw45tljby5LQYJcYHLMASPgoVQmpLZdEndIf2C7EsvJ6PSLT2aPTjYaNsL8YlwdssCbLKa168a1faLRRveLTad2jtylxJnrcgrw4JNLjCpok0EZRhUkSzxkS/JU7mTzJaUU2N3ZrTcOxM4bN/kEN00kbzidA0qbhFjqomBjWCtct/qHV8Kfh6MuPHm0fjgK5qQ1T40qgT0jkUopRxgqedXtOdpvW2nsg5ZqUk3G18ga4aATkJ&#43;K2HV9u1i5Jtemb3qTtoGoVMfQr5v1xVW3blK6Xx3YFWfHIimWFPNJg89hQw/a0Cj7aF3X5V/z7OgcmNvi&#43;m28Ok13yJboZoCYc5uw2KbDhonFRamNHqq48z7zxJmuh1WDDbBToajtbOTkrC8fy7IGFXYHzudnUYeVzn04BKQU7x5TSX11tu3aq6VtW94IqdiZF5ZTx33bRgYs1&#43;Q9i&#43;LuDrIUB&#43;9zrnz4Kg3EkpukbhpnaTLYDyLkEenD4dh0y8NmPHeqzA8&#43;zQ&#43;Rm0N87anRpr9&#43;26idvkVmp3plGyNMxS7gHfZEugXbiuDikyXQc2MEbv6bBByU2Bk18&#43;Fi5JRyk81iaduOtpncneEAWbh877rVul&#43;tvXWGeL9bx9d9wtez5K4d3Ahhk/ktt3OUtvb5&#43;rab13H4My27lV67bcXDvXbGZvLWAb4VWM1IIEJp4bBfSy1CmKPogL3qL/TyJXT9LgOG6pPrW30w&#43;qcWFnKd7deN620GrNsjkMsT0ucoBG/brmsab10S7H1GZfiDErAdzy1RaqN1dOFkCkqgNvrd&#43;8J&#43;ybCOO5m16E9aD96zUUKx9CvhBWILogPwyCvVvsFVI2joEN&#43;k3n9pMO7nrjRcwNq&#43;DyknvHngjfcxPIMIgWzf9&#43;vWW3tPICwPJ95GHZRUZVnWdb0N92cj&#43;VFTwUTYdbheA5NIxSvxH1nZrsB59A3aFXZLiAYq944MBFCD/7WHB&#43;&#43;vFjqd8OAiyWgXb2yID4MUAjE5a9MJsIeAEGwkJiPOPJ41a3CltNokkLeBs4/EA2ZwDpdrvFpg24Kz2Dby/JwLDc6p83Ns12i7fOCHoOGWATcrYz7Q9uINoqwWJhrY1Px0q3426g6lKP2JkeDDTgPf9RqaKdMkJud87ywMYdG&#43;bRVGaGhysmjPRI4Puoih69WrN&#43;ab79XrM2o62Tvz7XN5fgEhyIsrbNtNk8zmUXKDxu5Uig&#43;2AKWsZ5OTz56FZGYpuuGBU5wrUxkGXa7HJ0fVbIxaHVKNaWac1lUlrcUsRojRuWiaPpAxWkuJqTooI5ZcF/ShE/HAjF2nXp&#43;pFy/xasnOCefUGycvruK7PtWJ7swJ2eQU&#43;JekJH/uiu5oURw9ffKX//r/P/3803699r1Lfzcm0GYoK6RZvFKpYjw6fva0nk0PuXUMYBFXWl0a025qsFI5iwe/Kns11WaspErlwxn8JNX0Xh9pz7ZY&#43;ABdn/7khR8k3XlwQ7PIAPt3ZhlnRTl4wjek460pyZ&#43;70jS&#43;8dG8qMt4CKwLKVFy7RBsndroX6miqsoDfxKIU&#43;/ROeLvtf6xLLvNaI5olhMzplp/pvVIykqIHO/T2nzgPPDu/nbnnm99HCFu9uTuGl0l7rrBH&#43;Ck5lmTUo2KUT2o/ludwhs8n0enHNLakQEArwB&#43;K&#43;APTK13HMLwVzQQVVE&#43;rKqyLD&#43;TWAnQO2bgI84pEPdB203KcvvCvpTkB0Kl76kmjYTohVgIPiNqnePeijRtTEipAQshOoks0wDtj9wnzBvyCrEl485AedgJfm2/wduU5O33Pn6T87ssEEIKMQP4ldIwGvVKCe9FbihHUMYcGfMIsPw/0qW9/37Xiohvv8HXKcmt0tqjjAbb/bEA9eGVN1kIfhohv/xbrENRipsBzlLKBwCzNFrvAzr3e/f2c7Dk9k&#43;r3J&#43;S5E0kjf58GrVBiIkQVe4TvlM1hMxyk&#43;f7qI3aRGJ/Fgm2kr0X8b8lJTmMKPTuz&#43;rvCfNGFx161310/ZOLJ25tQ4jdiVTb12/wQN0y2XdVTQhkrQPwH95f&#43;5e6ECDn3MV1cdCd87CZ/XqLjP87AAD//w&#43;E273i04e/AAAAAElFTkSuQmCC"
     data-sizes="auto"
     width="2144"
     loading="lazy" />


</a>

  
  
</figure></p>
]]></content:encoded> </item> <item>
      <title>Throw away information</title>
      <link>https://spinningcode.org/2018/08/throw-away-information/</link>
      <pubDate>
        Wed, 29 Aug 2018 01:24:32 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=732</guid>  <description>IT workers spend a lot of time acquiring information that promptly goes out of date. Be careful what you bother to memorize.</description> <content:encoded><![CDATA[<p>When I was first starting out in IT I had a senior colleague who commented to me about all the throw away knowledge she’d collected and tossed over the years. She talked about learning early versions of VB, an obscure OS for an old HP minicomputer, the aging phone system we had, and all kinds of other things she’d learned in her career that was, or was about to become, useless knowledge.</p>
<p>Liz taught me a lot of things, but that basic observation about spending lots of time acquiring information that promptly becomes useless stands out in my mind as a useful caution. It has also become something I’ve try to plan around and compensate for as I advance.  For example I almost never bother to memorize an API: I can generally keep the documentation handy which is often updated when new features are added where my memory would lag behind.</p>
<p>It’s also part of why I love puzzles: they keep my brain in practice at gaining and tossing aside detailed information.  There is just about nothing as useless as the things you teach yourself while doing a jigsaw puzzle. The small details that allow you to associate pieces with parts of the puzzle. The ways you sort pieces for a particular puzzle. All kinds of things that really only apply to the puzzle you’re doing and not any other.</p>






<figure class="figure-center">
  
  <a href="/wp-content/uploads/2018/08/IMG_1273.jpg" target="_blank" rel="noopener noreferrer">
    
    

    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2018/08/IMG_1273.jpg" alt="Puzzle underway." loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2018/08/IMG_1273_hu_96be4ca6508899c4.jpg 680w, /wp-content/uploads/2018/08/IMG_1273_hu_25d7c345f0eea558.jpg 850w, /wp-content/uploads/2018/08/IMG_1273_hu_ccf79081d531d7b3.jpg 1020w, /wp-content/uploads/2018/08/IMG_1273_hu_6c938150192d6a55.jpg 1360w, /wp-content/uploads/2018/08/IMG_1273_hu_84621397591db662.jpg 2040w, /wp-content/uploads/2018/08/IMG_1273.jpg 3264w"
     data-src="/wp-content/uploads/2018/08/IMG_1273.jpg"
     src="data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDIBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAE0AgAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AIdO1SOSNa1bbU/KbeF/irzrSdcNtH80Ab61tQ&#43;K3Y4WxU/QUAekReJZIxxip4/F0&#43;fuCuBi1&#43;U/8uI/KpRr9x/z4j8qPZUw9qd6PF86bulRSeL5zH2rhpNfuP4bEf8AfNVZfEdzjH2EL/wGj2QE/iu&#43;/tG8Wd/TFcvJVy/vp7sLmDZ9BWXK0u3oaAOm8L3z6fqYmT0r0aPxfd&#43;XsTFeO6bNdQSb0jL/AIVvR6zej/l2A/CgD0T/AISa79qi/t&#43;7l3jdtBril1bUWxi2z/wGpP7T1X/n1P8A3zR7KmHtTrY9Wlhf7wOarTamyuZNvzH1Fc19v1o/ctf/AB2klvNcMf8Ax7nP&#43;7WfsqYEetaioEjkYJriWPmzGR&#43;lbGrDUZf&#43;PlNv4VgyF/uZoNCKK6Ef8K13/g2NJrdpmgRmkPGR6V5bDJuYD1OK9Y8Is8bCIfcjQfma0pGdU697RvLQpBDu&#43;lH2Wb/n3g/KrEdzxS&#43;d710mZW8mbH/HvD&#43;VVZYJjn/RofyrT82ojJmmBzV7aXDocQwj8KwpdLn5OI67iUA9qyrqKQv&#43;7RSvesgOcsvNt94baWHPArSTbfW744kZcDFOtog2oyQmNVbZ0qZNNaMhxKoZeoBpGhQ0&#43;51C1by5lJVDgNitvzrlV3mYcn0/Sqf22G0QxXA35OVNZdzrTGY7&#43;FXovTNamfsjZh1xNPuts9wCj9cjpTrnXTcSiHTmEmOSTXDajq0Nw6xOoH1qexl23KG2B&#43;UZ&#43;tZ&#43;0NPZmn4liurrQhctlJUb5gK8&#43;81s8k5r0KSO81AMsr4Vx9z2rz69ha0vJY26oa5aprTKmkwm41OJB93OWr1nQSIoGcfxGvMfD42NNcHsNq/jXpGntss419VrUyOkjuvepRdc9axRLxThNz1rUzNzzvel82ssTdOal82gC1JJUWaiMtRebSAqX17DZXRdk5ZfvVgSXEomMyyny5P4c1f1Uh7uFZOjAjisB7jEhX5dqHHzd6zNDRmvo7ragbDxjA4qiYvNk53l8dKPKt44pbrzQ0uM7VNZn2u8Zt6BlPVaDQ1JLCyit2ubtWEq8BfWoB4khgMSw26qBwTiopdbe7tFt5wN4OScVl&#43;UPtO7G6Pq1A/ZnVRaqklrJNG5Rw2N3oK5rxJbeXcJcbvMSVc7vWrkKB4tqxlY5DwetXNcsTLo4RVwIhkGgDJ8P28K2UazffkbdXYq&#43;1QB0FcuIbiyuohHbmRIxir/ANt1I9LL9azEbwkJqUGsFLjVv&#43;fQfnUqSa0f&#43;XdPzrQDejJ9am8zmsCP&#43;2v&#43;eSfnUvla1J/FGtBmb3m8VF5vNY32DVpPv3gX8KP7Iv8A&#43;K/P5UAWtQ8syQuT827isHVNNInZ3yVY8YrV/sS482KSS7Z9jZ24qS8s57m62/diC5zmgDnYYoba4RZOVbqM1cug9s4kiRXjHOKxNRuZRetDGBhGxmtXS1lvoPKlQh1P3h3FZmhh6hPuuGdY/LU9qLfUokjZJE&#43;X2rWudGm1C4MCwNGu7hzUU/gi7jICOGFBsRWTpLGzoz4X7qjtV&#43;zvZbl2tZMsjcc0228N6hZ74UYbWHWqlkL2y1RUaIkbsMSKDKqXP&#43;Et033/ACqzH4ms5E&#43;RWrzWOpY55F6MaBHpP/CTQjpA7Ux/F0cHW1kNee/brgf8tDU0Wo3Hds/WgDuf&#43;E8t/wDn0k/Koj48H8Fm9ch/aE3t&#43;VRSahN7flQB2yeNJpPu2hH&#43;8aJfGM0f/LFfzrgZbqY/xkVG0rsOWNAHaSfEGeN&#43;IF/Oov8AhYF3J/y7piuIPPWpYq0A6c&#43;Iw0xmNpFuPtVu38WzwDbHCiiuUDGrH8G6sxnWf8Jne7PuR/lUR8aX3&#43;x&#43;VcqXOKhyc0Gp08vje/z8m38qpy&#43;L78nJ2Z&#43;lYdRN83WgyP/Z"
     data-sizes="auto"
     width="3264" alt="Puzzle underway."
     loading="lazy" />



  </a><figcaption>The start of <a href="https://smile.amazon.com/gp/product/B01I95LXVM">the cat puzzle</a> at the top of this post as it got started. Stacks of red, white, brown, and green pieces are gathered on lower right while I finished the boarder. The wood grain and basket weave would be sorted during later passes.</figcaption></figure>

<p>There are plenty of studies that show we need to keep our brains active doing different things to help keep them healthy – <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5588550/">some even look at the value of puzzles</a>. Programming, and other tech work, certainly does that by default, but as any of us works with a specific platform we get used to the patterns it uses and therefore slow our rate of learning.  Puzzles also are good for finding practical applications for basic computer science concepts.</p>
<p>Sorting in particular is something that puzzles encourage different approaches not all of which are routinely needed in development work but are good to remember are out there. The concepts of the core of <a href="https://en.wikipedia.org/wiki/Radix_sort">radix sorts</a> – or bucket sort – are extremely useful, and can even be used as a form of compression for a puzzle. My puzzle desk is a bit too small to allow me to spread out all the pieces of most incomplete puzzles, but digging through all the pieces over and over is just a waste of time.  So I often find a basic pattern I can do quick sorts by, and stack up pieces by color, or those with book covers, or other other easy to quantify detail. Then as I move through assembling the puzzle I can grab a stack of those pieces and do another round of sorting and assembly. Like a radix sort, you don’t need to first pass to be useful to make progress on the overall solution.</p>






<figure class="figure-center">
  
  <a href="/wp-content/uploads/2018/08/IMG_1281.jpg" target="_blank" rel="noopener noreferrer">
    
    

    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2018/08/IMG_1281.jpg" alt="Puzzle pieces spread on a desk showing sample sorting collections." loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2018/08/IMG_1281_hu_b12c1661f8f2c89.jpg 680w, /wp-content/uploads/2018/08/IMG_1281_hu_a9aed3c6a69bd85c.jpg 850w, /wp-content/uploads/2018/08/IMG_1281_hu_286cb2eff2b39340.jpg 1020w, /wp-content/uploads/2018/08/IMG_1281_hu_ce4c7b51786642fe.jpg 1360w, /wp-content/uploads/2018/08/IMG_1281_hu_3dd69adf7c60f3a6.jpg 2040w, /wp-content/uploads/2018/08/IMG_1281.jpg 3264w"
     data-src="/wp-content/uploads/2018/08/IMG_1281.jpg"
     src="data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDIBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAGAAgAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/ANR7rzTWzokf2i7Q/wByuSjm&#43;frXW&#43;Hb20toGeaXa7GswOonk&#43;cR1KOmyss6xYeZnzv0qX&#43;3LDb8s36VkaGg/Cj&#43;teZ/ES1MWopPj/WLXePrtg4C&#43;bXI&#43;Obyz1DTUeGTc8ZoA81kqaA4YVD1pVOGBz3rQD3bw9LjRLb/AHBWwsu8n6Vx3h/XLCLR7eN5TvC1qnxBYblbe3HtWYzVaV8L9abcSO0ePSs0&#43;I7DZjn8qh/4SWxZG&#43;9&#43;VI0M1Y3t9ZLDhi2RWprItgfMkIyw&#43;asS81eCa&#43;8xcjAGKhutchlGJFJXb&#43;tc9WkZHL31yxu5FgDeSx61g6pOLQMu/dmux1TW9Mj00xRW22VhjdXmWpXP2iU8100gO1jeLr9pi/OrUc8Wz/j5i/OuQ0zSm1G48mOYYx&#43;VdFF4OIwPtJrpMzS8&#43;L/n7i/Oj7Rbj/l8T86rf8Id/wBPNL/why4/4&#43;TQBY&#43;2W3/P5H&#43;dZepXdo9u6C6VjU58FLz/AKSaz5vB3k5P2jdQBgm5wcDpSiXJHNS3OmGKTZuottMMkoBegDp9MurGO3TzLoK/0rT/ALQ0zH/H6v5VjR&#43;G7NIlknuCv4U46LpUa7zcvtoA0/7S03/n8/Sk/tTTB/y9n8qzF0jTHIAdyv8AerUi8JadJHvSVmoAqy6vpv8Az8N&#43;VVZdX0zZ/r5K2D4R0/HOao3PhbTY/wC9&#43;dFgOX1bU7SWLEDvu965wy8810mvaZaafB5kaMa5GS6T&#43;7QB3ngyLy4GuD/HXZRze9c3poj03T4o3/hWnfb5IpmmJzFj5VoA6fz8dTiiS8SN1Rm&#43;9XHHVnuS0m7HltwvrU0&#43;rMHQucIwrQDpri6CLuBLfSqlxN5q&#43;lc9aXslzcnymPlL1ya13lyvFBmZl1FmTNZcuox210o2fMtbMtc7qNtuuGb1xQaGwmqFo8zfc96qtfpOD5bj0waxp7lxiPrgfpVR7l9w2KFH1oA6G2v3h43ZbP3RXZ213Na2KzmMYx83NeXCdogNh3M1bg1e8tdOxM4MMny/SgDsh4it5XCZwxptzOGGcivMp74xvujkLDNSDxDcbWjZz83egDptYVbqzmUEHC15uwwxHoa7WwnT7MRI2XcetcfqcfkXrqOhas6oHd3FzJLIqBD1&#43;XFJLcSJnz4hvI2rzxUccvlyb/WquqX2ZYQnLbqDQmt0SBGkdSNwwc9zUtpcoVCsgfttYdKzr7UHEao5HX0pTcb9nlDP&#43;NBmaW2FG3IrRgthlWtaOdHgDRZ2j1rm4ZJk81Hzvb3q/ayvHBsZqANCSTNUNRk/cOQm41IbnisK91aZJXXadnTpQBWP7wFjgH&#43;dQymOPbIeVWpEuY5ePl3evc1myrIWeHfxQBejkjZ/MRuD2NboSO704wLztXOD1zXFOTb4GWrcstSktbIyMnP8LUAZTq8LyRFG6/lT7aBpUbgtT5rx7jMkhCt/OjTL9opHGfmb8qANXSoJPM&#43;cfKPfpVDxFEI7hXH8VX7K7zO2Cvzdfeotej8208z&#43;7QBqJLxVa5ieUo6KN1SgVIO1ZmhRe3UhlkVmb&#43;8aRVkQgwN8q/jWptBHIzSLbIqnYu3NAFZCVl2/MzMvLVLbo8e/e&#43;6lSJ4wSzbqOa0MyTzaxtT/AHYcKnDDOc961KilhSUYegDmI4pWVT3HNSGSSOTdt5ZfrVq5gkgcpGWxVZoZiA5B3dBigCrJLuGCvOa1okDWLRbs/Lms8WEpZN6NuY1rW9kbfcTk8fdoA56V5N2MEqKfFIOgXmnX7SxynEe1GpdNGZQxi3HNBoNSaSOXKvt21sx3Bvbfyz6VVu9JllmaSHAU1asrSS2j&#43;dqDMq/8JJ/0x/Wpf&#43;El/wCmX61zlFZmh0f/AAlP/TH9aP8AhKv&#43;mX61zlRUAdR/wlOf&#43;WP60f8ACSf9Mv1rnIxRQBvf8JJ/0y/Wj/hJP&#43;mX61g1FWhmdEfEYPWEGj&#43;31/59x&#43;dc7Rk1maHR/wDCQD/niPzpf&#43;Eg5/1X61zeal8ygDdk1aGb/WW4P40R6tbwfctwv41hZNFAG9/wkH/TL9aik8R5/wCWP61jVF3oA//Z"
     data-sizes="auto"
     width="3264" alt="Puzzle pieces spread on a desk showing sample sorting collections."
     loading="lazy" />



  </a><figcaption>The next puzzle getting started with edges sorted on the left and rough collections forming on the right. That big collection on the right is text and poster edges (puzzle is a collection of classic <a href="https://smile.amazon.com/gp/product/B01MU4SPKJ/">Star Wars posters</a>).</figcaption></figure>

<p>Liz was right. I too learned and dropped VB; that stupidly designed phone system was mine until we replaced it with one slightly less stupidly designed; Drupal 4, 5, and 6 all had particularities I recall only to be nostalgic about the past; and the things I’m teaching myself these days about Salesforce will one day be equally useless. That’s okay, it’s what I signed up for, and if you are finding your own way in this field it’s a reality you should plan on being a part of the rest of your career.</p>
]]></content:encoded> </item> <item>
      <title>Developers need to write more than code</title>
      <link>https://spinningcode.org/2018/07/developers-need-to-write-more-than-code/</link>
      <pubDate>
        Tue, 31 Jul 2018 01:25:03 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=727</guid>  <description>Developers need to know how to communicate. That includes to be able to write well in their primary spoken languages as well as they can writing in their primary programming languages.</description> <content:encoded><![CDATA[<p>Developers need to be able to in write their primary spoken languages as well as they can writing in their primary programming languages. It takes effort and practice, just like programming does. And you get rusty if you stop for awhile, just like in programming. I started blogging in part to make sure I was writing on a regular basis. When I worked at AFSC I was writing and editing everyday for my work, but the next two jobs I had didn&rsquo;t expect much writing from me. I&rsquo;ve written before about <a href="/2016/10/what-i-learned-by-getting-a-degree-from-a-liberals-arts-college/">the value of my liberal arts education</a>, and the last few weeks have been a testament to effort <a href="http://www.hamilton.edu">Hamilton</a> put into making sure I learned the fundamentals of writing.</p>
<p>In my new job we work hard to provide a great deal of information to our clients and to make sure they can understand that information. While each team member brings a different set of strengths and weaknesses to the projects, we are all expected to communicate clearly with each other and our clients. All of us are expected to explain our parts of the project so that our clients can understand our advice and make can informed choices about how the projects should proceed.</p>
<p>In the last month I&rsquo;ve been responsible for presenting basic overviews of platforms and highly technical reviews of parts of projects. I have contributed to large architectural design documents and focused detailed designs for small subsystems. All these materials were done collaboratively by teams of highly skilled technical people, but our client&rsquo;s technical skills are much wider ranging. Often they are experts in other areas who need to use the tools we&rsquo;re building. Others are experts in the technology we work with, and we are serving as added capacity to their in-house teams. We are expected to explain ourselves equally well to all these people, which means we need to both be clear and thorough.</p>
<p>One of the things I try to bring to the project teams is a willingness and ability to edit and be edited.  Because I spent time responsible for all the digital communications of a large organization, I have experience quickly and aggressively editing documents of all sizes. I also know how important it is to have an editor who catches your mistakes, and while I carefully review someone else&rsquo;s work I am always supportive of anyone who is editing a section I wrote. Not everyone is equally comfortable with these roles, but they are things I believe all developers should try to master.</p>
<p>We have socially come to expect that technical people do not explain their work clearly. We are too often allowed to use a great deal of jargon, skip lightly over hard to understand details, and belittle those who cannot keep up. Complex systems are indeed complex so it does take effort to clearly explain and fully understand them. But the vast majority of developers are perfectly capable of explaining what we do when we take the time. And the vast majority of people are capable of understanding clear descriptions of our work.</p>
<p>Developers who are unwilling to take the time to learn to explain their work well do a disservice to their colleagues, clients, and themselves. Their work will suffer from a lack of good feedback, and so will not be as good as it could have been with more support. Those weaknesses will become bad user experiences, bugs, and other flaws in their final products.</p>
<p>A well done code review (one that&rsquo;s meant to be supportive and doesn&rsquo;t include yelling) and a good edit aren&rsquo;t that different. In both one person is looking over the work of another to try to understand it and check for errors. Done well both give a chance for the reviewer to learn from the material and to help the person whose work is being reviewed do their best work.</p>
<p>When we explain our work well we open ourselves of up for feedback. That feedback gives us chances to validate our designs, improve the experiences of our users, and generally create more awesome products.</p>
]]></content:encoded> </item> <item>
      <title>What else should I have asked but haven’t yet?</title>
      <link>https://spinningcode.org/2018/05/what-else-should-i-have-asked-but-havent-yet/</link>
      <pubDate>
        Mon, 28 May 2018 21:03:15 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=650</guid>  <description>I found a great question for a candidate to ask at least once in every interview process: “What else should I have asked you?”</description> <content:encoded><![CDATA[<p>Every time I go through a job search either as a candidate or reviewing applications I try to learn a few things to make sure I am better prepared in the future and to help friends looking for work and talent. I recently completed a job search, so I want to share what I learned this time around.</p>
<p>I found a great question for a candidate to ask:  <em>“What else should I have asked you?”</em></p>
<p>This is actually a question my wife and I started asking several years ago when we were buying large ticket items we didn’t know much about – like cars, houses, and HVAC systems. One of us, I don’t remember who, asked one of the salesman if there was anything he thought we should be asking him and his competitors. He gave us a couple small tips – likely things he thought he could answer better than his competition – and it gave us an insight into details he thought were important. Once we asked that question of all the sales people we had a list of questions to ask that covered more perspectives than we would have been able to figure out on our own.</p>
<p>It&rsquo;s now a staple question we ask when starting anything new. Instead of trying to pretend to be experts we ask people for guidance. Often the answer is “No, I think you covered it.” but sometimes we learn things or are told about discounts, features, or services we would have otherwise missed. Outside of purchasing we’ve found the question can help spur conversations and get people to tell us things we need to know – it&rsquo;s a question we use a lot as <em><a href="/2018/01/i-cant-think-of-a-single-reason-why-were-here-except-that-were-needed/">Guardian ad Litems</a>.</em></p>
<p>Most good interviews include a time for the candidate to ask questions. This should not be a pro forma detail crammed in at the end. If the interviewer is taking your needs seriously they will give you several minutes for your questions that give you a chance to round out who you are as a candidate, this is particularly true when talking with the hiring manager (if they don’t take this seriously you should think about whether or not you want to work for that person). This portion of the interview is a critical chance to gather information about the organization, your potential role, their existing team, and vision of the future. It is also a chance to ask questions that highlight your experience and knowledge. Most advice you will find online will tell you to make sure you have a few questions you want to ask to try to draw out the information you need while showing off that you’re smart and talented. Doing this <em>well</em> can be hard. I discovered that having a simple, and reliably unusual, question that I can ask at the end gives a good last impression and this one has gained me unexpected insight more than once.</p>
<p>The exact wording isn’t important here. I’ve asked several versions:</p>
<blockquote>
<p>Are there other things I should have asked but haven’t?</p>
</blockquote>
<blockquote>
<p>Are there questions you aren’t hearing from candidates that you expected?</p>
</blockquote>
<blockquote>
<p>What else do you think someone should be asking about before joining your team?</p>
</blockquote>
<blockquote>
<p>Are thing questions you would ask if you were in my shoes?</p>
</blockquote>
<p>The idea is to ask an open ended question that shows you know there is always more information to be gained and gets them to think about things they haven’t shared with you, or with other candidates. The question alone often stands out, and if you get them to discuss something with you they didn’t discuss with others that helps you stand out in their minds even more. It also gives them a chance to talk about things they know and you don’t, which can help give a positive impression of you (this is same idea as dating advice that encourages getting your date to talk about themselves in part because it will make them think you’re smarter).</p>
<p>We all tend to want to know the same things when considering a job. This portion of the interview allows you to fill in gaps in their job ads and the conversation you’ve had so far. But since all job seekers want similar information they are asking similar questions. As for showing off, the hiring manager has likely already pre-selected a group that has shared backgrounds they are looking for so you aren’t going to easily stand out from that crowd of people with similar professional backgrounds. But by asking an unexpected question that puts the creativity on the interviewer you might be able to trigger a conversation that gives you that extra attention.</p>
<p>For me the question worked best in group interviews, because finding good questions is hard for me in that setting and it sometimes triggered discussion and debate within the team about things they wanted to hear candidates asking. It gave me a chance to hear a set of perspectives I wouldn’t have heard otherwise, and to see the team disagree about their vision for what’s needed. The most successful was when they fell into a mode of answer each other’s questions. For 15 minutes I moderated a discussion of what the team needed from their newest members and watched the internal team dynamics and politics played out in front of me. Usually the responses more mundane, but still helpful. Never did I feel like it was a foolish thing to have asked since the worst answer I got was a long pause and “Well that’s interesting, but I think we’ve covered everything I think you need to know.” followed by a quick check list of details the person thought it was important for candidates to know (the details of that list helped confirm why I didn’t want to work for that manager).</p>
<p>The question is also practical in a pinch. One of my interviews was rushed, I had just two hours to prepare after a first round interview so I didn’t have time to think of new things to ask. To add to the challenge the interviewer answered most of what I’d come up with before we got to my turn. I think I managed one or two detail questions that mostly clarified something she told me before I switched gears and asked something to the effect of “What else should I ask about before taking the job?” The question allowed me to stand out to her as asking questions that suggested I wanted to make my career move carefully (which was true and a good thing from their perspective too), and got the conversation into a productive place about the team’s role within a large organization. I start the job from that interview this week.</p>
]]></content:encoded> </item> <item>
      <title>Using Composer for Drupal Modules and Private Bitbucket Repos</title>
      <link>https://spinningcode.org/2018/02/using-composer-for-drupal-modules-and-private-bitbucket-repos/</link>
      <pubDate>
        Sun, 25 Feb 2018 18:07:04 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=562</guid>  <description>The majority of resources are focused on using composer for publicly available code but sometimes you need a private repo.</description> <content:encoded><![CDATA[<p>The next installment in my ongoing set of posts to create a public record for things I couldn&rsquo;t learn in one Google search is a process for using composer to track a Drupal 8 module in a private repository.</p>
<p>It&rsquo;s pretty common for Drupal agencies to have a small collection of modules they have built in-house and use on nearly all client sites, or to build a module for one client that has many sites. We are all becoming adept at managing our projects with Composer, but the vast majority of resources are focused on managing publicly available code via <a href="https://packagist.org/">packagist</a>. There are times these kinds of internally shared modules cannot be made fully public (for example they may contain IP belonging to the client). We have one such client that needs a module deployed to dozens of sites, and so I sat down a few weeks ago to figure out a solution.</p>
<p>We use Bitbucket for our private repositories, I am sure there is a similar solution using GitHub, but I haven&rsquo;t worked out its details.</p>
<ol>
<li>
<p>Create private repo for module on Bitbucket.</p>
</li>
<li>
<p>Clone that repo locally, and structure it to <a href="https://www.drupal.org/node/1083580">match Drupal.org&rsquo;s conventions</a> (this probably isn&rsquo;t required, but should allow your module to blend into the rest of the project more smoothly).</p>
</li>
<li>
<p>Create <a href="https://confluence.atlassian.com/bitbucket/oauth-on-bitbucket-cloud-238027431.html">Oauth token for your account in Bitbucket</a>. Make sure to include a dumy callback URL; you can literally use <a href="http://www.example.com">http://www.example.com.</a> If you see references to auth.json, don&rsquo;t worry about that part yet.</p>
</li>
<li>
<p>Add a composer.json file to the module&rsquo;s repo (it only requires module name, type, and the branch alias, but it&rsquo;s good to include the rest):</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;client/client_private_module&#34;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;drupal-module&#34;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;description&#34;</span>: <span style="color:#e6db74">&#34;A very important module to our very important client.&#34;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;keywords&#34;</span>: [<span style="color:#e6db74">&#34;Drupal&#34;</span>],
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;homepage&#34;</span>: <span style="color:#e6db74">&#34;https://www.bitbucket.org/great_agency/client_private_module&#34;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;license&#34;</span>: <span style="color:#e6db74">&#34;proprietary&#34;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;minimum-stability&#34;</span>: <span style="color:#e6db74">&#34;dev&#34;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;extra&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;branch-alias&#34;</span>: {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;8.x-1.x&#34;</span>: <span style="color:#e6db74">&#34;1.x-dev&#34;</span>
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;require&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;drupal/diff&#34;</span>: <span style="color:#e6db74">&#34;~1.0&#34;</span>,
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}<span style="color:#960050;background-color:#1e0010">,</span>
</span></span></code></pre></div></li>
<li>
<p>Add reference to project composer.json repositories section:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;package&#34;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;package&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;client/client_private_module&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;version&#34;</span>: <span style="color:#e6db74">&#34;dev&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;drupal-module&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;dist&#34;</span>: {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;url&#34;</span>: <span style="color:#e6db74">&#34;https://www.bitbucket.org/great_agency/client_private_module/get/8.x-1.x.zip&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;zip&#34;</span>
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div></li>
<li>
<p>Now just run <code>composer require client/client_private_module</code>, and provide the oauth creds from step 3 (note: the first time you do this composer will create the needed ~/.composer/auth.json)</p>
</li>
</ol>
]]></content:encoded> </item> <item>
      <title>A Process to create a Drupal 8 module’s Config</title>
      <link>https://spinningcode.org/2017/12/a-process-to-a-drupal-8-modules-config/</link>
      <pubDate>
        Sun, 10 Dec 2017 18:43:14 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=536</guid>  <description>After a few tries I think I’ve struck on an effective process for creating modules with complex default configuration.</description> <content:encoded><![CDATA[<p>One of the best practices for Drupal 8 that is still emerging is how to create modules with complex deployable configuration. In the past we often abused the features module to do this, and while that continues to be an option, with Drupal 8’s vastly improved configuration management options and the ability to install configuration easily I have been looking for something better. I particularly want to build modules that don’t have unnecessary dependencies but I can still reliably include all the needed configuration in my project. And after a few tries I think I’ve struck on an effective process.</p>
<p>Let’s start with a quick refresher on installing configuration for a Drupal 8 module. During module installation Drupal will load any yaml files that match configuration patterns it already knows about that are included in your module&rsquo;s <code>config/install</code> directory. In theory this is great but if you want to include configuration that comes with other modules you have to figure out what files are needed; if you want to include configuration from core modules you probably will need to find a fairly large collection files to get all the required elements. Finding all those files, and copying them quickly and easily is the challenge I set out to solve.</p>
<p>My process starts with a local development sandbox site that is just there to support this development work, and I create a local git repository for the site’s configuration (I don’t need to connect it to a remote, like Bitbucket or GitHub, or handle all of the site’s code since it’s just to support finding changes to config files). Once installation and any base configuration is complete I export the site’s config to the directory covered by the repo (here I used <code>d8_builder/config/sync</code>, the site itself was at <code>d8_builder/pub</code>), and make sure all changes in the repository are committed:</p>
<p><figure>
  <a href="/wp-content/uploads/2017/12/CleanRepo-300x55.png" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    
    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2017/12/CleanRepo-300x55.png" alt="Simple project base line" loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2017/12/CleanRepo-300x55.png 300w"
     data-src="/wp-content/uploads/2017/12/CleanRepo-300x55.png"
     src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAAAXCAYAAADDXUcwAAAQwUlEQVR4nKRah24kSXJ9kZnVhhzOzC1OBhD0Bff//yNABpD2dseQ7K6qNCGEyazqJmf2pGtMD8kyaSJevHCZ/uUvf7mmGFNMMQYiAuEPPwyA5Llwd6P5zZsH/fcIUCL7uzK4&#43;vPYvaPv&#43;wscQBR3D/hgzPY4M5pfbtzA&#43;mW/z/a7viFzRgRZMBECRR9Xnq/gMfZubr1i12XcvgFCQKAJIUTdRuMVlbPOIWPKnNuYAQFJrxMFu66bJv0y5PcKEEPFHgghANwaWmtDJCpnVwv3ZcreW9v2KPdlbyEMcd&#43;ogbe/5Dlm5lpqzSWXFD8S4mTfMJEptY9SdyPdA0MUOhkIdJEi&#43;wJTbL0DgMj&#43;CIQHG58XAs&#43;sClf5yjcDWAjIASgBxEdEegAhgdFMyCo4Q1lTgcoALni93gHS/FpVpRElVYcoIoQzIh1dedexSNKNB/vJDRUrGEWfE/lFOiOGRyR6QAwTmAvW9kW/ssYpfNT3Gy96TwQU6GiA0T3IWAWBDgiIqFh0frkeAiEdGHGqyGXBssw2Z0pIMd4oUhQoyl/XFbU1xBgxTRNSioihg7Bhp/MbsKiymLEsixpOiv8YaHoMSCdSBdGRgGRK5AuDV3/vCEAsWGSeWeWmzx8cCKLPbIrs91Unwd4LZ4Ae/P2FFQQGMpuDXwn4LYKeJ/A8IdQnTOEXJPoAglmRCI45q3JKu6Kp9R0RcFBLU4sbtttQeVahy19yPdAJU/iswBJFFX6xewqQaQBM5ih8UYst/KpASvQJx/gPmMInZZHGV1zKvwOlgeiAh/ivSOHBlCqg0c0nh21UxYkwEgmIDmjIWNt3HZ9SxuFhxXReMc/fjQUAPDw84HA42G5qRa2MEANqsT3lUnE8HvH4KM8dFSytVTShRjLFi7JrrZ1K9Ce3CnohlFKQKAHhESTKFDYITwQ6mzXXX4H2xZUt1x/cyp/Fgp0FHgnx0UGiygewOiM44wlA6ETCxPq&#43;0B1ObGxQbSyWBb4EhEsCi5XyB7UgUZZ8QweACu4bKq1ur/LMowo20qTC7r5JlJH5O0p7VrCYRR5AOOh4XT0hTIiiFC76jhBwxNlcBk9mucocspaTuRVUZQWZVwBga3jS&#43;7JGAVFTF1LcIRx0/hTknaMTa3JlF9VPjEEtWt2BrPJwxPl8UqXmnJUtzJB5kLLQvjCFAENdRQhIMSjgSslopeqYKU16T94UAAlY5JlUf29cWmCcWRUR5PuJzKK/AfWvpsiwMOhkCuZXsWIoIOIV4A9OUXJvNSWrg67mt9TlTkZf3N2K&#43;D5jW3vnAtClgXMFNbHeBbVlFLog0XlYuAg3i&#43;W0i9q1uADCd1VYgPl3BYH6XVHoCzJ/UwDE9oIFX1RhJsmGINavfj3pM2bB1R1D1M2LQ0B7RQmzrcUiAF2D0iUT1vpF1yVKMhYyPyhjirtS6heg1OQgJXUDa/uKVl9QYoHwWV6vyLmosqpafUUtGXldsa5ZaV/YQKy31oaSM&#43;brjHVeDADiZYO5DXlPnlFFTxUh9utF52jMSPyV0BZCnYCmfppBT8YY7auBgCujfjVFsvtr&#43;SmW3X4z96AUJ&#43;xQGK3wFrf1OCDcRoXU/3OmkDloraCyKniozWjq&#43;4P6WPPlpP6tYVWh6rtNrIyMjnrQ54GMDV/0eYsH4vD12zqisoEGajKjohdb4ONBpbmKqIBBp3VdW7S7/LvSuoDH4s0t2LNAMvjzwcZj&#43;HwLmDKWBsSF0GpBLkWt9nq9qBKLAiCj1Dr8ef8pvlyud9EGDyjVgP2ZHiDK10DZsC6r3k/H&#43;ICDWFEG2trQXpvSvgQmofr12oCVRzQ6ArwM0CzAsAkiRdRS0XLWwUWoMfQosUfWJhyl9GABjS60YQQwQi9Vg6m2i0D38W2P9DECni7UG&#43;VRf4sH2G4j5B5a9gyAt3t8&#43;6STlgdR/h51a2YFjll9s/tujXw3zu0yHVyNUZlRKo1gTSx9vl6xSrAmjFjruLeP6lV&#43;67rtiN5P43qm0N/XuEAY4OOnP9FxiqJlpYYlZ0WHKO90PCKeg1JOU0vYkLRtzBAmPiVNk0anr/UVuWZM6YDT&#43;aRo7sqVAEUULxGr&#43;LxSDNWCSplfniudomp7dzObSNm1wjsN3WafPLhgu9hTKnJg8LsSe3v9TYarbEG3yqQd1pjeZk80lrmNRNviupKoK1cDuZ1y&#43;VbJHbLM95nazlh7Zs18tw9COp3OOE7BCLBVhOtsfkOCkOmI4/GgfK/0w9CoVBQ96KXbJxGipCIxOb2wRqhPT084HA&#43;6QBlfFK4krTQZRs4rkem6LijZAh0BwWZB731&#43;oh7mN2TwnpbvjfPdz471GFsyrsJ8z9r2Fu7z7q1vXB&#43;/blaJH1kwvQXxj97XK39Uy&#43;lokYRvnq9ATRzJUyehGlUKoWpKYT6sFFNMlYizbc9pxKqpBStIhAFMqTyoS9wCNH/lLTXBbXFCrF2eKx74tMY/Ub4Lmvnmu&#43;2P7/b7E&#43;GO&#43;&#43;8L7h47exq&#43;nwfv1NHu5xz2TTeD2nM7Jvi/fsY0vEfXO0UcWTdtS0jfv37heUqIwR4S32N5JuF6uagPEgCozwAwL7NGmZ0BgqO725w8JwGL3J8lpWqWhngFaqtyjcKEodj8Unnj7243eI923Pz9RiHYgajTyd6ieUefuJ/v3mo3OvoxKbFXSWmM&#43;xZU1NPx27W9neaHgH13r&#43;TRDO0N5wdswtudtMwzWk0arPVNE4XNKl0ZFmSZf3bvOfiub1qjzGEZ7KlK9fTk/SozDf&#43;0vya5rbGKMobE&#43;DHq&#43;CNo9LJvc&#43;vZmAA35ct7GY6SaQdkX&#43;9gieBl2WDMxryjdXYQW&#43;xx43Z9f12GeyX2gBB3ZdtuEP0zonT3&#43;&#43;ZSPchsXt3zsqsyZH&#43;XjIW7fN4zoBsE7D5J/PMhTRqQ6aYlmHNh92hRgkBLdbaovA9fPSeVhYrPl4VUT1eKpjB1KFACP9u8KyHQsH6t57ctIJLnJAVallXvT9Ok8UdfD1xYVjvnETwWDyT3QjGr4pGZaByTkgelEt&#43;UAexJZJGSr/cWWMJmlps3Hwvj2S14M2V3xVr52deqYLU8PcTgAK8DLFrM0dTOY6jTCefT0QtBRd1jz6zayJgME&#43;TBec3ZU8PycxfaAfD44SOdDpNWj9TKoqEu&#43;Ca6FfcoPsSkG2APP5blisvrRa8/PDximqIzR8E8z1qkEGVJsHk4WCMlpagKmFLykmWP/BcVruT1spm8ziMuEEFLQNqVKIFor4urQmrVtOlyvaI23tXIk6WbtWLRdIlwPJ1xPp0s0te6&#43;ozL5ar3zg9WVg2jooZRQjX3tmqtfl2zPnN&#43;OOOgwHd2clcp8ZNWGUcVztYg82kWlNJYv5JMs4JNzllLvKx1&#43;gnTdNAAGQhaXZR1yHzTlEZdBLt6fwlQw6uVwH8Y4UKMXRVOphRTbKdFUaRSrHeZJOe1UmUExeQW0jDPy0ZnHB3x7laCFSaUzsRaHACqHKE3girMaC1p9c4sunnqOVpgKqjgyp&#43;0Rm4CpNDQqIDCOoIgBZoKcNJ1FsqqtFIF1E0zGp1f1lY645G&#43;J5mMWSeQUtC/IZYXWedXIOSqoBcFHaaDjtda9g4l7zp3UHkJEBtlS3WdK8ZcwrSSDnua3Cpbla&#43;Y5XeWa2w1A5VD8PIvW3OsVw3/WOe3D6Tr5RU1J56cytj9i6LL/a0qcFfQEWGIYOUrG9LSZK24XICcJ0W4CFA7VrIo&#43;V0LGnXUEaLHGb2gY7696nvV592yAVZhLFqfAEpraiVqaZ49yDtyv1QTljUtbFzZl5ZTs9H3jFnvpcmYTi2mWHC6zKv&#43;3oPe1P0weX&#43;hFE1zSzHqFvCXXB0UxS1/q9YLYNa16ji6v2oZkrlbGrm9rF/urcIAuRjVqyuOWiSysm&#43;vmUDTZQFA8IDSwGMMVWr7CQ5u85p0vb5yzkkXOHyVE3z3f91vw6/JjIJoEaBQffZ697xW5LKOSFY7WGJGVMG5mdLVt5B2AcFbBM68q9Q1jL89a9TNc1tsC7SaQtjchwpvpKY8OmCampY22qTKpBzRSsAyW32dvAdfq61haRkr5ZHKqs8ePX2rAlpQmHTea7t6PQPuKjff37uYdZVAuHib2CuE4yxA36txXXcT58cTPv/yGY&#43;Pj3h9fcXy22/IeXWgrZiDVVLD0I2x5T5w/1s&#43;qaZi3brU0FK4rZa1EeKrzm6IJBXUA4FlE48NJAotZmGbIq1QpF2/YwU/NrD8LgY482gM6TwyQSGQ&#43;K5GIJ60fasxMFWQCN792nZYw5tBbA2FKMqKpoCeiZC4JJ6soxlZO4FRu3EruM3Wd9COtZ8H0PMF2vP2Or4EwMJWR&#43;88nhDDQVs5Bc8o9UXvB5y9mWyt4ICEAFn/0TuKKyqvdl0Ao&#43;cBZms0aSdQAko9CoHWCKfzEZ8/f8LHTx9Vwd&#43;&#43;fvGg1Q9btH3Wsc8k/6B&#43;cg&#43;A&#43;GdCOgPxQIgnAH7IQzt5iyjFRzt4V8/Zlahpfz8c/KRPI7SFrR1ceqHGc94EhAcgPBmY&#43;JXRLhingrh4e/k7gS4JvCZEfsJEn7WFCmcka7yUIUwBX1TBJ7e6uEtN2Q5zoHmH0GMYetKDHcxXFP7uh02idgQNqdppR9VmlMw1K9ym8BGJ/uQ/T9rzvtb/wKX&#43;l/YEjuGf9UxBP&#43;Rh9H9UsAUcFEyNs74r1ypm62ryBYgZh3PD4SQB6Suu81UZVjK04&#43;mISYPn4BnExpqmdPau6N&#43;u9BsAhCdC/IWQHgjxiVRREMteGe0roz3b4PHzdh6gvYizZNAHPUuAcPTCR3XXm53O9&#43;cBHgA6kAHrIyGUzjLGCO27KYiqRL1nxPoJCR/9AMdJbSzosatVD1Ksojxm7dGn8EHbtFF7/WbJOj1fUNp3/dn0UMcjko73aP16/qTr1nawsIK2jxewWGewBoueD&#43;CicxzCP&#43;EQPvm5BAHQN8R2VHY4xj9jok/GLH4eYFco9&#43;NhCZOu86TAEwAs/Fe08IzDtOB4Ft&#43;fsebF030e383KxeLvtO19Gvu3K1aNWtu&#43;X4GR1rK6gOfK9SgES4xE4EQIwpjEaJlRX/zo1kQIbMpt3&#43;3sgNB1VLbcKl&#43;srsCDU2cCYRXKLotKY3XjPMCysU3QVjBZQMPP6uOn8MGpM6pVr/yMrCgkt9KKRuICkipHKQf2bGliad/07J4otbSMSM8ukKrsESSDEKUh&#43;zkDo6beuhXqzfUV4C&#43;qWDsPuCC3q7ogAZwwhp4LVIRXXRf6eQBUdQXqeigj0KuV2vmC3F71zALnVQIQrMPPZ1yvV6QpaTqtzbHWdrWY&#43;w/jTUP0Ru17vMin6f9p&#43;e/SZA3x2BBOpCeDlKpFPL8bC2jv/3/Ijn7J/lY2N3D0o14nD4yKHwKpGwMwPIDen&#43;/sn&#43;B/O2vQtYCWCipy4erNpjQs2xRS3Xfm0fs3JU7DTYB6z78phXcrtmcmdxU03AL5wUY7a5D3MTy21nNDoP/0E0V9K837/xlr&#43;Tf3v3V0SW&#43;fSb7O7SStnkDCVRknFkaaYUF1sYMfv/76K56fn3G5XHC5vCoo9pXD/&#43;9HD4W2VmttLeWXWtusZ82YApHS9dHoRAO1dXe2j3Z7Yz8QmuxQzFD4/mTwXtk/63Hsx2wrSNO0rT9PPzgPcFtcppufo0vmC9tGorvF3C/s3oZuG8tjZI/ygyO76XGt6mcBfzQejWMq2x3PNrJ1SHvmta4Zy5o1FSySekpK3aucf&#43;fH6k6ttdra/wYAAP//npfFw7OcLlMAAAAASUVORK5CYII="
     data-sizes="auto"
     width="300" alt="Simple project base line"
     loading="lazy" />


</a>

  
  
</figure></p>
<p>Now I create my module and a second repository just for it. The module’s repository is linked to a remote since this is the actual product I’m creating.</p>
<p>With that plumbing in place I can to make whatever configuration change I need included in the module. Lately I’ve been creating a custom moderation workflow with several user roles and edge cases that will need to be deployed on a dozen or so sites, so you’ll see that reflected below, but this process should work for just about any project with lots of interrelated configuration.</p>
<p>Once I have completed a set of changes, I export the site’s configuration again making sure to avoid uuids and hashes that will cause trouble on import:  <code>drupal config:export --remove-uuid --remove-config-hash</code></p>
<p>Now git can easily show which configuration files were changed, added, or removed:</p>
<p><figure>
  <a href="/wp-content/uploads/2017/12/PostConfigExport.png" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    
    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2017/12/PostConfigExport.png" alt="Git status report after defaults are added." loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2017/12/PostConfigExport_hu_6721ef1e99a5352a.png 680w, /wp-content/uploads/2017/12/PostConfigExport_hu_d68a8827d85e6658.png 850w, /wp-content/uploads/2017/12/PostConfigExport_hu_bbf7eae15e9c61fc.png 1020w, /wp-content/uploads/2017/12/PostConfigExport.png 1290w"
     data-src="/wp-content/uploads/2017/12/PostConfigExport.png"
     src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAABeCAYAAADrChyUAAAwj0lEQVR4nNy9a3PrSI4mDCQpyXad7umO9/2wH3b//3/biImdqak6lkhmYgPAg0yQkmyfU9U9M8sK17ElXvKCy4Mr52//638udJHCFyp8LlwKE4n&#43;EDEzsf5NRDwRlRMTFf9OViGp&#43;oX/8ImovBViIWpXIVmEZCOihUnemWQ5EbdXYpqIudi/RJWaVGL9Tx8QNyMhkU3/T4VnHRgVfQA1qm2x78s00Wme6XKe6XQqxIXsvLn8QhO/kMhKS/s/1KjRzK/2DD9m2upG27pQrfocpiYrVXknnhbiaaWt3qi2SqUUmqaZylRIWqN1XalW/3yeZ/vX1qYUEhE7x/7VkdZK27ZRw2d&#43;xBjib1/jR8e45h9yiIg0Ednm8y8n4r8Jlb8TTX8tVGYm2pjaTYwQdNN1MEoI0ysTn3zA&#43;r2s4458Jpp&#43;YSMKuQq1Tf8lot8KtX&#43;dSX59oWn7F5r5jabyRnN5odqutLXvdv3EF5rKhZhnW6iG74TYNnXW75RkjKqEpjJRmYlOJ6bTPJHwasRyKn&#43;nE3&#43;jKt&#43;NgPS/l/L/2XdKbPoz0Y3OSsuihHEhoY02&#43;Tei078Tn7/Tsv1G27bS6Xym0/lkBFu3jW7Xd1q3jeb5RJfLhaZpsnVRQmhNbNN1P3XTl2Wh6/vViKZ9sJm2mkciwPn/SBLQPdVxzjoJmpotZjkXKroyunn6UztD&#43;sZWItufohKBbaA21ubntNWY2j7TOUmBdOiTce5wCVBA/c022ddhNk43iVB0sxcS/SFdxAIuFrveJ6EPm2xAej/Re8lKjRbb1EITnls69&#43;k5xMrFM65iJSeVKUQzE0&#43;FTuRcr5usnG7cKGK/633m04lOpxNNpRj3KwGoZGjM9lmTZhOuW7Xnq2ToC/FQDozPHm7WV8&#43;RtN4H6sk0ZlJKhKoSAK1M9Guhtgi1f2tEZyIWJrkyyaY7Kf3uVRfozL75lahtjaS5pFBO4EnG3wSiuVWS70JtbbS2lQr9SreqIn2i1lbfZNsiXdATVIMTRpUbVVntswIVYXdm57p5Irrwic6qv4qP9Ub/CnVBpkb0mk1&#43;112wzXcpsLmaU3Vkz9Nvrqq7iHXTjNJ9FOuymDrYtkqtbuS0ENzOTsTMLv51Hvq7rpUSRGsPObyLfTmQAfPjTZa8iezMdbzWuO6oUp6rGtAKzUUmmutMfCXa3ittbSVhpplnYin9YscDRPK7DKmwbrbhyhmzShJmmzRBZSiz6d9VGjXebEM3Ywlwo36e9CMfWES6eOF0DoEAmM40k9QLyXSiQiVNNHgbkoKqPcvlj3QOcEaVsSTciLexYKrDdQiux9tuMVW09zHxQWfH&#43;sh4VlAUf6TfJSQk9z09yomxj5LWKHO87GjCJSbUOP4NiaZfz6pLz/OZpnmmWje6rn7S5eWF5mm2BxbVt0XBm9BWK8CO4ruFGjd6Ob&#43;auNRzt9WBTwF4NH1YFpJ6pVrXzikUi/NAXO2V372gtP&#43;Lilq91v9VVTA4gxKgpNiNvDT&#43;H8v&#43;2bL/VXSusl/oWMR85kfjfwTy8mf5XsdzbT7kk7r/br&#43;p8fW9BODd54O4/Lmz/rJhorpZrfrm1q0ZEGDjNnIRm0Sb6RDTcf7vVjYnAEO&#43;YqJQD9WHKj5VjErfBPzbRZ7cLciYyOMFdNGbv8Zk&#43;zNavuLpJjwB4Z2Njwv3M8dH1z7a2DhsY9Mgn93ny5/znpj0/nM1MSe0GbAKkUUm4rZtiNwQcxXEwjhfz7jdbvbjm&#43;ffqQRwSeNEpQuqUmaSgUD1vGkq/W87twG2lTJUT2w4CEp3WMHWNCs2KFlnYPwQ2ZJ2mAd&#43;eLhgnKRL34C7k&#43;6w&#43;biXJJHNXV//yPGQyzGQZ5LkqE7udP2BoSSdpz&#43;zLrxuzDxPjngxEUPq4DIV26bL1bZVvU9E57Mi4dkWVT9XAlBJovc4nSYzkWLRBsX5BquUWNbVNvF8Ods99DM1vZZltfPP57PdS&#43;8TNnfrtvhm1xoW0CEW7lujz9DvFbD1iTNjHMVUGYXdLvcA7E6aZ4zCe3Vg18hesVBacCPOL0qOp1xMH4qpTyXTM9UR4zcCIHI9b6YNwJxxp3EYmwgP54miX2XSy&#43;VMLy8vNmHdfN2YImJEoZun93FHymQEpg/Wa/W86/VqRMOG5GcHkfNEt6vA0TIZptD76P1Op7OZZTqOq9riC3cnjCK5vkjgfH2OEgGFpIIu5TLRBKNwmGcfL1pw4GdHB/YS61m6efv5tT&#43;vXn76wDNn5TxeFuNMXTS1cV38Fpqbo/tVuVM5T/U7OEc3MgZuXNkquM&#43;51IEgxDsW0CXISuu62e&#43;kkoNdglQQh6sYMmnQr9ExcrFn2DlbpaKI3QAqd3VBFGrD5&#43;gc6ZimwaJ1MOvc3pSIHoA8lyxDT3Y7QfJG78GbP3/4KEyCFj5IwCQ5DveQJ2L&#43;H3YECNTFrbZZS5cC82m236dlMh0dm2AAEZMMsc/YwNbVxOYWAESNqgXdMNf5A0uoZGji19gY9BnVVURrG72/i43JJIhKJRBS3KPBKHR14xKEzOqY7Pe6zZ1gDV/UZuertFHJZRIJOGGHbVRqwblDRAPwtrg&#43;nlON2PUIaZeJL5tyQQgB6jqeaYNZ6A&#43;4f&#43;8I7AeIYDbuVJTOlcrUfMHLZJJANz&#43;kgU62ifvBTT&#43;rpOBhLytxbFRNXL&#43;&#43;vhpG0Nkut8UIRb8Pvd6dJW08T1XMdCt0u5E7XbDwDHWkC06GPc7wyLkzRlXI69srvby4q1g3VYyoFloUl0Da3JbF4g2/fPtG33755oQLy6Saarna7&#43;fLxWIMBR69mJtKQR2nPksJPOZlY7qczT0cxMpQBUb8tQGvODGU4gBZCe&#43;23JwJluEP&#43;YoMuAN2DzZ&#43;/xk/8Da7JJ&#43;pi0ofoGHY4pxiGEABVhmUav5jlRLzZBPr3IMB6TUzpIgA0Sfo6SqhI&#43;XixAaMIM1VSB67qZxtqJTwArovoFlQSIlCMUMPyJD7IeJeytUu5WY776TEaX4f7nNi3Pdsc5t92Jt05xT3dfFNblB1AvwUWEbH41KumdrpUpPceTXPUwe07Ia&#43;zzGkQN62u13Ljqt7tXF0HO0B7F4qmaRVAlBubIkiDKgta6fWHNyocIXqxJebB0L0fEXuthgKCK83O&#43;d2nWwR9LpYKALH9Mkx0VqcyFwVjAjaceYxl3VxIFqgc6dpc06E&#43;VfDnNz8c8MaNj/ejY9BXKa2zAJxnKGSYoNpXCHmg0j0UEmh6D7UljvEbj1K2LGDSSiXAmEaFjCIXq9jXDeXQLYHH9jymdMfOYuzM0jk/vP4bBCMBDUpxpuJ6kYVNrxAjHZfNoNaENBQtRB63yinyc4tqQtTAK7i4cFRwwQZA1Gw5yK/dj97DDTCriZpiOBdxKQQePFNvRq4HKKROjH4mCcqOk/DJBvxyoYbQmKYPRxc3/U9nNMAbBMsGoLu1iOuKUkSbmCi&#43;NwIzdbPg0WBfwjzsYDT6XRnkYQKVImiQHz4Tp4riaPXUv9fE6HmS7sfIMAYw2Qy2/x0tlBoYAAHfLrxi52jYlLFbrh7ddP930onhErDNeyEJN1/bz6FcGF2yfLeJU5eYAWkCthUbNpilIgC6uIXbBC4Wa85OI6m4tdcXl46mFWOnjH&#43;TgAlYhhhvg3RucECYmAfnXv4Rjz4U/r1Lk2AJ4BXfP02s3z0Hrbh0zS8oZT88&#43;TSwKSsbpyFnmc6Xc6uHsFcas6mXe8Spon0v82bWytdb9d7nweNXI/5ECfceYrK5Ho&#43;c69Rsi1aePtacn7szaTg4sDsNjmdAIIjlVqXElnUdQ8YbPVa792ynTuZutjNotIJz&#43;Pz4UnTMbMHEHzD9HMTq05MwsApbejkmG8BkSmzTGHNmAVQbJ02iPMRfojQE3XJViC1XOUhcsrSTUXHCeG3kE7UJMf4AnW3d0tRQM4ntOcWQV7rOZ9nInxd6fv7u3vqpgmb7J&#43;HFzDQb3B4he4OMaW/u67k7lkk2hOHA5EKD2DtSSchMvW44V4x4NLtakI42LOCzGwN6usxDfcG1tVxinJ95xIyZd7DtQyuIwA9kUwAAyROtxvAr5EL3NunTgC2Fm14SzeEjMOTWpQozQEGIpOcJ&#43;BzL8gxiHWkWO&#43;kArokJCcid3SWQegwcRv25sj9WSLMfPjC9AU8e5lSKF20mOm0gUpl9x1Vnci6j23vhQztQrIJpNAB&#43;4X7uVNt&#43;k4X4aSWxuXsorM7g&#43;C61nl0/4R7BlV0CvEIfD3wBB5NqxzO1a&#43;Cg5kFiSsTNky63o5rYwMJ1xc4wh758OnghNqHkr9&#43;xJ7t1/dAAGkz5kf2oVEaUMMuphHRxSrYGLl3nj/Ydd49eI9KPzvCeSIPEhqm1sBJ&#43;0n2mGMEhSwvoaRMoq&#43;4dvmhd67BrThiQJWoPnbkhBns50pXBZ95Bh85qI&#43;ex&#43;Pnz3wCGRCmBep/z2M3Dg90eJKSVjidt/dy8/FC/CLHj0JsHZ51xLXHv20sWb9SiOD9NZxmJ&#43;HUkCGhOBYfixX4ZnefByg7pJTQ8OTtoNPdFXGv/T0/Cv1&#43;dvxoKHg3CEkwIv6Hz&#43;YKkCOPMs9irQAu45uJyUQHpyvKTpd4pl&#43;V/R317&#43;2wYAX3i3wg0&#43;/4vNEe/yQL1oDYidmSO0/s9yiwg/3ZvuEhtPSLoiYYC/F9liLFw0PVMI/cgiYKWJEki/EieE6rfUe7TJ6f2qh/0OHSc&#43;wh0T6o3fMBUvIIBjx&#43;pHOYh1/fCtNfC9OpDO9h6V6&#43;4bGq&#43;DJA6bsI/V4VIfjC6iKeC9v9zlhUwr309637zgfhNkxhnphO&#43;JkxzsJOHo39pyrYQoBotfsLvRjxiqc6YrwFgxSObDWfp9kGopusY2fLIHologsIbhGmX4XoimDTc0nwn7P5uzHQYOZ8zC2lZh2Y&#43;GF8XBflhZn&#43;Phd6Kz7x4OoqbADREjZwbtzDPq9ENxbLCxQMSDf&#43;L4Xpl8K2qOFb0hFtwnQpbAuuXLYq0CLf8PPkKexTIftpoJ4pEj/mQmvx&#43;ylB3SDOvhUlOmeLGMcJm94cw9q/Ov4Tua6/CVGBPv8rE70Wv&#43;43JYxKtOi1/KPpH//8w6ctWRckDHA8PJJ6QHDOMcYRCnzENXENC0I3GomWJpYTES0PxL9AzG/kXFaN6&#43;N&#43;0FEueY0oFoh3E&#43;JqIjexDKNTv5eLalNPZaLKk91r4i6jabMkDsJmjy3zCMIwB6knf&#43;h8pWMivd8VYv8m4eEQyy8&#43;ruRTfJy&#43;/zGM//nxDBQeIbRvJ4JBH98xX&#43;R2tG7ybwyuPpwaej&#43;LRIY4X2Xo9bhAN/zanDJL8l&#43;EX/t7842v2IgGvDFTo6lNdBayH&#43;paDInlzM7Neh04O/T5BDBXMYZ3qyJAjpxlRIvdg&#43;y5AsL0a75LT2q2zwtUAiUg2sAoQgMfFOO2gVMqGKn&#43;iURwzC94dHQclaOBz07sYcQEEQrAl4rsFx4bGjfeJC&#43;EHzppFedqFpk45ZHsrdypOOClRIY&#43;yjh43MvUiW6KcH&#43;WbVRx8T3zUCkFamAK6QIii7HY8/R&#43;4iC1wSrZsF4X1fN6b70eRG7SInALgmeoi7Fn&#43;zMFhAewC4m3YE5KJC&#43;4Tj9/F6Lf28fY4c885JgWjmN&#43;5pSgAIK0r2gxAlDgNjkGiMmGKggv3onHRuqVyr2L2e7U/fcMca16/tUwgEuYhs0L7rqAGJbmG6bXnCdE16BqQgfPsApmjEe5/0pjg5X752QyTtDzsRG6Sa8gOsQRbY6FEk7CulQrLxvPjHSziuffIAmV4H9RAsA63iCV/pmY4ZkpOlvwo7UnguixM0dF1380N4FM3MnQ56uEhykTgE84dOZIpmRb3GsTIG&#43;/V4jQ/OS16fW&#43;GSqiFTdwEZob0Um6s80wgRJb6fjC0fqS3B0b&#43;caZKx5ANThVRfzWhuWyySBK2RWZ&#43;X2cOPy5hQZxxzqt&#43;PxKgWH8syUxzp91fMTMj861aKBnvjx2OfbgRlLmDfp46XGKpHfwPwblq9hkVZgMcYvghXQgKhYi3WyhGhXhO5vf9D67Ll5xjwosMrVxLlFUsXnCScEYQnw33LtAJYVkC0ILXbyGOgnnCQ9sw0nP171j1AiIyQEpyiftDCOS5gRAIMqWALD8k1TAs8MIgB/4xAP1iuxdXsxCZ2b6lxLmEHfg1rBhFMg7pS&#43;sKDB9J&#43;oOFoZIfoMvYErImCG2Z&#43;j4amZb5Na4GponxwFzt98VJ6hYb6bjlUg2YpM88CiYfn8x1TEcVZQyhd9gmmKYvgZQQea3QCr6GmoFOv077hWinqHnldNvXZ3cJxj/mZv/Ve6XZPobCAzA9/DgkJ28O4952O1Cw&#43;saEy2pzDP73PzB0kW2bWcGjkkFWI6AefvYRH5wsT5XCaAkjnYHlNuu3DZihKkbTLZmkqio7UANhFmB7Evi7K7Hu9fMWXScI1aHOCVZxbGQav4mL2bb&#43;UqxDnwfWvnZ4y4B5IuxFaGRhvbcDMTKZO9RiE0Vd/9WxUw0SeWbLRGAu1zjoW5GvTc4gWR8vgBP3LAZR1lkHATdfxPHCAoC3UnjauCcwuYqb2WrluXUyCXAahLIm1Do82/T5MXkQxfRihneAOZiKUuXhMPj6ZXISKUDBtogzX4PlUHu8VzBOCV54ziZzI8rE752ZJ3/Q5FDScWhT29ODwN7wymcZsIQsBEPCA9gpDmGeRYImhIgEyxieOhLii1kj2AW19a2QIEmboCEo06E0svDBOFfB3aK/E7FXYdIcwFm4A5kawBXuKNJZMexGS63iA5GTCNNzywcMExBps8J0qsBM1xDNX5t2z7d0x89OIpDpU&#43;P9uIqAkB9w3wz1Sz7G/R2AyUHRa84d0ZwpsBDtmDllibdI1i6K7jQL4W6GSjYGOXWU7iCA5FjMc&#43;Wo8fWI8BcwbFLxXPt2IhGzI5/h&#43;TQz95Y6Jt5igvyIP3Cdzz3l4wBIv6RrAD7HNRW4f4OtTGHSUrj&#43;issIN38F6yJYpLfk6/gjxKA9DSwr2MAAtHM&#43;x42&#43;SzqJ&#43;Xl8CQQF&#43;khzjeIQXOPNl/IM&#43;eomYPDuivR3j&#43;qAW5s0M2x4KfufPHrm4ygUfYXUDLJQrKo6bi0Zv8GoItxcriCYeOPaOQoPNkilSvmLSNdrQekeYDarUsI3mGekiRaMEmNANJBAvxo4OijxI9Pr1MpZQTQ2hNEcj&#43;YBsT7v9dmHsEuwrvJ5X9PaWMonDIw5aRrD7fP/72KecWYhhMoslgVSauO182/NmQZqyi3jWs0T2LBHUZgSi9W/Fcr0VqdCGyxzTvool6lUQnxLcOsM&#43;ROg4trWlRJsVTPCOorOXIifQd3RaLZ2ol1qMl0rNm7FKv&#43;g3kCd8krSZgPosglc8kP0FLyIh&#43;2nnNQgUZO&#43;hoDzxQnA&#43;XSwXFEyUyUbBzChNrlLyZ8oJu0VHcDm0&#43;&#43;wR0rZOaemoAXgMAoVld&#43;azxRtXBws7CwBDVNEy1lMoDm4WC&#43;26hrG3GIPsVDXIPbwDvdhyKUcu4PGTzZB59VSVa1d&#43;1dvn5EnmAm0vzd8dw8jkM08P7k3lSAuJtttNNz92InxKNQGtAdgQx7qNFhCLjMORfX9g0ZjiACEMxOGeFCUmbiU6ESqW1B8Ui4lEgNC1gOLCCc7xMf83ACAyeUbNdnVZCHz/sEjHzsiOlPzBXgkcPV5zweOlg8srMlYgFEgwKjFi&#43;yQYZYy4UFnKZ/nPlhkyVQ/kE0ZRfD3VR2MgzXJkklw0G1uxbjLVZIwb1/X24Mcb8ou4mlDOEjY0i/x7HQ7o7LYvbPXCsPP/snJBTwYGrYcjQXFDRaTduBy4&#43;6Kbp&#43;dEAoUcC5L4nKwDGSTCv6ChjRCHWl8jFs2cuXL4GcFGfoNQu8z4U3QjqA3&#43;fZwPFsuqusocPYOjM9IMw&#43;jge7/Ec3/5GafnDS3RroqfM8z/T69uZVLDxEqySxGZOzUqjezoVQ1rX1Ct8Ql3wol1qWlW63K0mLrh3DDKGfsIO/cr6gSlhatY4gTvlDlLfe2fOOodM97pG1V/dOhxqH5zIMJ/UP5Vjg8ieogKcp5kR30uxI6HNhr3k7nU5eUNBGIUGZvda&#43;Aaqe7Ryy2jnv&#43;yOp7p&#43;tiwehhj4aLEbN3rqWvmgl6f47afuFozuhnojTPnNrVNgSmkv3GHAtaYLHd5OxkjsJeDxLZHjnPprSTlr8SRjgWTr47uAjzCeat&#43;pVPBUVOAKQYOZOnajWCbn3ZJsZVSnRCSTq7TauvTijtakXXeQqWv9eOgFYWtcB4O0GnzN0DwtXeg&#43;j6P2zT/G2KqLKXZK56cY9oT3GeqcGUo5&#43;VN7kcwqaR/jzcrDsc27mA9Y4lsMdN/AzlffDRSP7q&#43;3/lhV8bc1atVjPntmbPykmICtP8gIH64YhC&#43;oFRwOoCVW3RgRt64vToqBDvHrIK30vXmVbokEEFhAVyFFm1iRyf12qqISyjYgewdjMArVkDRpQcSvwDUubqKJK2XoUGTAkeyYRJUIenUHmyat8gtujPCuXZDFKwEPFRVl8dAlxtbd1go9rODehQrIlF&#43;4mINEgiOjIEh1OPiOAIyGM5ntPLIJxg&#43;gQsrnve5rpdC50vrx4oyc0iFBxf7stpsuJJ5pO3rwpJqUDfn/3xk&#43;XywUdQqznLF2vN9qaEE8zXc5na&#43;xsYBLZQ6FTddGswfLtZnV21E13b1QRJdfRv5fIy9PO5xO9vb7ZeKjX8lVglWoEdzqd3R29rjaP6HJC0d&#43;oVlOBZ1TuCjDEtm7WlEqJ21vnnBBvaEaIvZ5CyCqQ9RwdZ1yj91O1ae3xAiOhTA3I1HCI9zmavCu5kOGl6/u7E&#43;czT&#43;1&#43;HztHM/ND0zwTS0g&#43;axAxzKygwmIFj/MZrVKm4sWf1VvJePJOofl0MV&#43;8WKeJ1Ths0s/1Oqt59w4hZdq8Np&#43;a/4vq1&#43;6Jsk4kMxXlGgvX6mL4AsnwtHoQ1lLBTyj0HJxsXDkV&#43;AuG&#43;nDimWk6zUZsDDVHKI322r7ijqXJG2JFh4/WfN7BmdFKz1Leauv9jQJISirMpNzJo7fZZfgakrXUojx9Gj6KuB&#43;KR3tn1T9wHDe/f3ZMCrUATG10vS0WP1&#43;mtZcyr&#43;tmYFD/WwwLTL06WMXVujqH3tBxLKqK9Tr9ziZjTaXwMDR4vKEEPUxF70U0xpP93JZadVtMQth90Jf4/f2d1jUaSUW301Ge7sQh/f7BeWTRY8cn3g8IRa1woXpvAC&#43;ckeuVloV7W3hKTZ4EzbBu6DMU7XQ29AroDaRgmh6LUr3EfO6cadaV9TZqO2z06PhRi&#43;LOZ/Hy//&#43;PxWMoXHiaWDnbm0PMvUUMRR8b6C7v/1dQ4r2viM3gJj7vDaSTI9Q8dqn7N6XiyQP53gVLQv/rvp7nYmplKnvO6ufTHv3KXV8debqAx0DZMegiu86pqWz7sB70wPziQzOL45iOz/loM3NX1UfHg&#43;ultdZqrVuSAFFU2Q6ove9DP8/PyX5v2i94&#43;iX0U4gc7g6gtjvxq2JOIj5fGL12YIo&#43;MQjlOMDUgeR430d/f5Rw8YiYuoB7gOqPI&#43;vugU96BD777iMiOp6XCU9Sw4z5blABogCEhtP3c2fVnQcsXRuLM7IP&#43;Onm52c&#43;O&#43;x6lpSq9mOHpCjecezZ9UyPTNNA9Byu6hwMOk6Gjw9Okzz2UPjYxXx368N4dp/nRz66F/7eY4DwjqGvD98NavQMyHl0RJH8cR/xChDXSA7EBPF1OJ9oHz2jREDxt6dhF5rLTCdq5G8L4LsoW9wnSzE5ZPVMyTElKQcgJGI0fG2pdmBCYmjck1KtY/hScsFHSZ7ej7i00Yi5lAMjyJPNpR6M4t18c47ER9VHnQAiYcLAmtU8tciN2l1QUATxgtLs&#43;HZC9k8UU3AO86YoG6VUL0lJnTs1kvLygoBuJFYc6mXhSAzlRmf2fABvZ8&#43;9FqCiIOMUbVAQWdyiftEqhNgqgU4Y8UJE78gfmEEcU0rytFx&#43;ZhSC&#43;Mwjp0DwvJHy5bkPhHPnnjK2J2SCJGkoJBHM74ziGkmbmAkgdqaipqFiMy882r5YtnLz6uVPCaDTmniWHEl5JJVM6l4K098m6qncUV4lSN06s6dxLSjS4OgpAAKpqWyLiVAa7pCw7ghqSIjfqtAV6VoXhjWJlPDXIujbQ71oc0N1zguuiYXU795x7hsqdk7IAPrefHN1XC&#43;ExFOUioullxGtxFbKdom6QxnNHk88Kpl14d&#43;x6q8sdAHhWAOdNO/YqMgR1Eveio/rFXUXV&#43;G&#43;iVNixIl8c78jK0vX/S&#43;Y70qednbjEXX9AgFkWvBefHxImBAEjKqMXMANRSCCKNwpEipTSVbcpaZYehRuUK&#43;xk1Rq7s8r4N6aAJNyYemgMpJTfIBV9i&#43;ZCYkQqWCR&#43;dPH11UUClkSZ3Ei&#43;lBJIZpbImSJdUFBamQgdfXD1EvPBcQZcxMkhm5QitMhMKhqodcYStRboPH1oepaMIebuDRb5MNmYZ8QwAG5Sh&#43;Q0NKYfkO9Ph/1vW5iY3oPcYtKoLLLlx&#43;LKCmbltN3sTjx8CXyAdlLxq0vQBu5dXihSd/w2KwoRpVMBOIh6cXK2KWrmw0SYhPp4j/0aVQ6CRZtSro&#43;ys11wa/FaxCscCS9wWtFHSElBngPwos8RZUSaQ6/I20&#43;CkwkMQRhbDWV25k0CO8sCGN70nPoUwIwhjrY4ILaeoZ4jSxYOuikEOf2/gB8yUmcRxMITi1ids/FvSNUG9S9Qjef0KJmgo4/HSKMhAWdcJ85nsu5JNsdS2c0gohFukpwWvQ4cBXgnOULGgsnHQNIH/NJGGlog7jPHEQDjk6VUbmMPIphA1sFEXxP1cv7DRm/ZmlFRwD9MwRAR9MvRA905mvJGGBsqk7ipZDpvAWUyzQIJigziiQLpR4/4MImo&#43;dPEIdyu4q1U3GMwYDWJ2ACvM8SGx9FpOM7wXNvNBwzv5DQG0BXhRTZMIbADgV1DgLJYxjAKppdkizhrSTX8xdzZ4O4MYaoNiZIkdiRWI9YaR3HN4Dris3PFsVHG/kzpvCnBHA0A7F0vnnI6B3iRrp5N2PiXpfnwz7RWNwQgTWZZbkka4OILomzrw0iuLG1gymgNkE7msg22nB9Q1GpTqJ2/ejVOjGXaq1jvN5A77159RjS04cRVjAvoZzmPn5aTvhonrN4oxgH1EhIslQavnUxzaMLCkDoCmm0xfWJsz8jhj&#43;NAB4fPsFFRi597nWvGOG9ce8IsiIVaqUR&#43;88YgAB0QnRFlnKJjQKRLA3czV4SbkWhudNGFKdYHYA3irYiTkPfngfQANRGbeCwFoS8/jC6kbTcrQTjDH0b3T6aoMs3zDjrFQRxvmJjuzl7wEGUUsQp1VHe0pwQM/RiUx5jWOjPKy3/BATSLmvP2435YFW0vvXWbCFWfYATjxLpOeXJjTZugfS9yicGEWjay6qQ6I2Jf2evKrLWcAXFoSWZhTCZrElr2yxQpKrgUoqda3pWCm2l0I3chaxS6g06ugGUXZFAdDJ8ABMWY7VuYGhS9YKkmV50CqmnJmIF9y7i514gRaJnwkqj21lNDSaCON4ThlFV8wq/QNz31/bntZb5WAU8&#43;Tw4IAYdvXgk2be6QCr&#43;b22ARrxxtqP0kCAzD/PHUT2jtGyYk5W9l/AZlcHZRzXxAI0K5yYLo27o9NUcmFFUB8/da3kGSI1uIqW5qC1JbJcAteKbwOT45gVWzprQ&#43;QmgtLfHZgeYl2T2UTJxKfod9Q4joV5dYhgBwF8xwxRcZO&#43;B/WifvrKfH6uA5GMefgAXP9&#43;RXcPZnu&#43;i3fX0Yl4oVPPAdIqSMkqi0Alg9AasSf9Hw&#43;kbqoMWdAGJ7OzL7FHhGeNYq9C1Ntq2Zhu3wG1rpeWlkMz&#43;7mMFgdY6pg393JtAsHvl1qRsc3VvS6aZta2BCryhwZR0/4f7PdakTsLE49QLqWCME8aRW8jopv/WhlUQXVbKwf7mB67jozs8TNKanEMfVwcf0piHYwM6tfeeG6afpIFu0K2S7NGWCjAaVIAkfdgS90QoStD&#43;LbqMRZVtmKDZ9o9WcwvegdDAWYHTimUnAXiRm2wnzDMskegPZGXf7NXJatKe4dbNnT1qsmZ2cQ0QafRNqgcAPNHgeuF70/iUwSYNCdql7pGlU/xgTZJpPMcPJcZrS8z3oQSgXAIenOCevm8TmwkVnTYi1KO/nyCmN3T14INzp7duQSQvTLiQHoR2bQzJoPr6N3a3ppt93ndfN/KEjhzBPQuwwVy8MsjtajhtVD8XNguGYP69MruITX6E6CoW7uF3azPLw0aHW1fQG&#43;hqL7J207iAMSgFvzh6IWEzC4DdS9yHB9FPqSIq3LlKbN&#43;Kq4IJPQ&#43;WQ3NX65WAv1Q6fcf4L3AphxX2DgmwfIUARA5eBRqmjKQGjg299IIrzqiFjwZSnJxG267vcDSF4l3/3YZruTe5dZFlvgTKbwl9UFaGJtAnS97MwZyw8fC2UUiylvr6cZJYkT88wbkjvO9eFouvBHpJvgyBdcDIruY0NPdpSP8uooQ1WULMuch2eCNPSfIRWt&#43;EU6qkphNy8LBOtJeUx3ZgH3sCe9rzUDbVgJ3QrxvTNV7AmG7JaAl3a24q3oCqAwFH&#43;TftQrI8QCClEvAk4oaDyNPKDbBxoRd0HSko9tyo0MoT1eILNSGVTKwXsL9SPl4uv0SjBsk&#43;ftnFEgSYJLx3V3gg5w5a3edg3VO7OMcmi/Rw7djU0ZVskdF3sNJgjJbwUXhKv0cjKvFg0jV5JX2tuK/plqyIjUY0cOvq8csqIBniiZIzVXO4SxNAkuQEKbhekj2cSapQNHkeujOaPVKKL6wSPX3Gs2a8hqaPCS90qDRTY381zZwaIVnSqf0M/DJFr0C5nx/J0N2S&#43;glF6JuAYza8eST6FPMhtkGZmCiFh8v&#43;3JqcRYFpzqnrWDiO3gFCa4oJHKV0zOU2pjIkRNrSj3sEcUoJgK2vE79MTH&#43;dmH550CjKw8H&#43;oxJgbdz1/0wjGBO6tgBYlQcBolhsXfrfmkuVcxkYgAIDFHcMEXDFjQutSHd6YUE42O1ztc3fsQgndA9/JerovSUni075vYm3eIMYttyDLgHE2szeIJ4vPIAfpVZxIeZv5qL2HIS34hhEWDqgDmKxkDWA2ou5h32eYRFEJLYlpnpmCx5f3Xj8/XMrILVqPxYxtmTX7hwTIAx3qboOMEzA3HvvUkK5hO6dBd&#43;PiCF3/RUJF9QbSIzuXS3CntEtjAu4NDdzwjiZe/Amnj/RCN&#43;2JFoF10cziRwCpiR6uw5mT/vudn40ykpt7mM9tzQvoYMZfQB44RtYJDuRMpE9dwp95iz6EAMcrxZggqUJ/QfawewQAsS2iv8rPHe3NjJ/wmLoLuAwzbqZIrvFleS3DxNwAhK2SqPiWUK1h4N5B6BUWl1lZOn0Dezg0g3Xa0qAkmSqRdwjE/cs3FvgEXG3GEwVyjBbHQNwz3zK97npuBp1Zxcd9H6s0ZTi/U2GSSgAnZlA6gOA95Xjg4QQ/CP5A95xxbTrDDZcwZwo&#43;MTcl2T09EtBkkMSREvoOrOBNOn29gTzaUbj6t6ZM2GQmpD3TMnUktEWdsICnBMOaXA0hQpYu5ube0SzJM9jhXop6c0n2THTOlYYEmpKPY1P5Ik3S4ozBENExtCagFsOGU&#43;9Fa6bfctP&#43;IZ/MBjkG6kD/6XQeMlD9u9bONjDpUtj9P/jHpevFP13R7rYuQydH9Q&#43;M&#43;&#43;igb8jxezMIxw8UsIcAwSQCq6JlLDIrduw&#43;aE2TsVdra9pIWpuea&#43;ciq5elN3fgQEYYWqRHpamo6cP6xbjEhr&#43;hFPaRKsrkGEuT&#43;xjM4sBVoC00Xj6Fc&#43;6Ymy3A7j&#43;4wSQQSC5iRW43AEVmy3aEArOqVjnOI&#43;H2zfMoS0wQCYcBHkK3Mx1l0voT11lZPQsYZw0f1fAnPyeOYGy69qUurbiu&#43;guusiwZCh1&#43;8o&#43;0HBRL8kPUCPSh1qHipawsutMPoJpYZpZ2hteT7MC92xwPbdkATCyiDgFgTa8QGPjkU20HMy6Hz2&#43;BgK742Y0WF6SSddyrABxghUie4G&#43;XVIH7561AyeSR8pazyrOfQf1tykFUyLoFPB3BYo6H9AuH7p5t0QAHBk9AezwlpOYRIjrcPhsTZCSJhbtO6O4dcHbQ&#43;ItKWN9oPaEuiHbEi6ZUlOK0HQtqdLdPiRcEsR3rffq7mejgz8EAillyZ55ND7MDaUrS9eVY0Ij4XG0lkcCaNKtU8TSIQHCHDuTZyLPPWjjD96gJsIEG3GJvV&#43;ec6wAHsW38NyBmha4X0sifALnEzmhTXifwJu/ksjE7neAur3U4E6FInRno&#43;3&#43;Er6z4&#43;83YvzabfsjQH9iBn52fA4Cd/9DYZc44lUUPiFQk4MZbqs7Mr/RyJeztHCohd79i4Zen2AGMja59Ld0jFfVRboYQ2UEmDrDLm&#43;J2PLQW8rPu6Crd5iYNbqZivQ8w5GU6mMOMPlWRjfwJbleW9/67CbbuRTx974vEjMd3sL48fGMTn5y/7&#43;QE3ikNHDnd7R8LbQ37UIl1Mhoha03RyAj2dnROfRGw7HSkrty6Y0aYK/zEPBGHMVfFvHuFduorsEZsvePh16eU/JHodGG/nvzNLcie&#43;vGpFHz65Uwfm/eTLIBHF6FHnZAfVrRe2gPIx/0KPpnHB&#43;CQObsZtxTePTJFWTicPSfw2JfU1RNunSQXe5A&#43;AE2HtJDuh08WsbHK2FKd2fGOwmlv/mDaFzfAzbJ9s&#43;5dQZO8Rzz9OFdRvmFVWHOmfu2RXWSzysco&#43;4Glp7GFsezzc/NGf7sHkE/e3wJBA53IEPEM/0F7wyaIELjmprEvfcHHrKee3fue648EXeQZ&#43;8XEjYpI3D1vkb2bkTOFAPA3PxbcdHMLKaPK4hGcoIlxqfnveH339G0&#43;SbD0UTdterRyOyp43Bfd2Idjh4iOnD2PRH8Z2/2o&#43;NjENj/SFW4SbV1Oze9z08iRAroHYh/6jbvKATMfv9IC&#43;uJkjKkD6cxxXMjGBORxML3wLWkzJnSCc0/q5Ldukw7TZwia5Juefw3zi0PNvbRZh/LwP8rEMTHILAldJnE3K0R/UrN&#43;&#43;qmlOxIIVvFXZ3KVeEKjrj0mmIBXcQzwrw7l&#43;ewArZK5pAZ77qHicWFLrqojeh3op3fvyTV09KzvqPZ9YoE0IiWTcl7N9yqHxtWP7qBd905/ksTQBx7UWAmn/Q3aIxwZmFOAFB6WnMc8Xrq0AgtAWOhfQ2bxfsl9dsrI0Ez27&#43;BF3KqeQ6OhI/&#43;jM9iuTcQwAa39RuPt5xVEMhN8ssn5GETh/8uYv6j45Ok0OGICB2uG3EBBhgveaCuCyPefeFYZF&#43;kkl7mGFbDBulwQkh46hVDYtwZf7/ZC6qy29n7/q3AAH8vnj4dHFthl&#43;eS6QFVUcPXBsb5C3uIloAL1vaJXz11Ur3/alz434EYnoNAPoDAFp9HO5Jh0za81atH8vBWz9ZG7lk4WJLDDAkkowl0SI8tGkpkWz15BxkBcKbhN88WwNEzJlHEgd9XGa&#43;GmWU4qyrtLYqBCYZVUNIXY7Mlder&#43;ryfmPzo&#43;VQFHYCW7Fz0N96/Q3nt2Q&#43;rSDgPwPjM2eu1nn3k7JDEUOFxuMl5K4eac9BdNTpEWTrwLiTKnEivK5ez&#43;BhJK5emEDKY1pYdPuAkfAOjIV5CkdqQTsBD95xr3P3A8twKy7ZPNOI4kTaf53vaVo4&#43;&#43;44Ta9q93idsUGu1eespWKgqRHioNlB9BnQTJDi89kGy20kjtpsTJOWUtvJDxHuEJwLT00LB7CyvmlsvXhfxV9NFh5JyKWq/h/6D/BwigHztftKdHzwgH5&#43;rgAcpcL0dlULxhNMLBLgEQRcQmvGDDV3u1HNzDhbt6CC9DhIgpCk/RqeMbO06ISCGlap9edp1qGKJmwd5LjLv3Cp9kOfQ6hJQjEG8IVezzjb37R0MALFQeR5&#43;hL7zK9a55I45/lhn54cujiY&#43;u7GEfB5KuKYQb2bCzFU2mDckeuRRv36LxAxIjaq8CjhBnagpheQioFYz7y4jx9yYNSXVEZDH8&#43;HPCAA3makxwS5IkClfWFN8QjnLw4ctvGO&#43;KusEVmcnxgqlje7rdwiaEkoNpQTj8iTex3&#43;kPEsFc5plku395WQaBIpQaEHv7kV/V9k4vewxLoKA/zqlI9&#43;kTHDYB&#43;hrEf7xLOOrvJFKsOD8vOE5SqNQ9gfrZubmfIERZO4A/QZ1&#43;SfAsTNDSy6557/CRfJ5LvZ0bmz2k&#43;45zq0Si6wiMPed8NhC770N4ODfa83ywcX&#43;Y&#43;/H8eTqdxETttlEycDDUx9EnT1CQu1Bl/M/crm3vRcvDPbaA5YSmLbFS&#43;kvZdrh6oHJ/feupxT0cCD7shiR77&#43;UO1Ap9OE/J71SMPAQWFHAwuFc&#43;7cPTh33g3BwbOGIGfnLdozF&#43;KMWfXIbB08ylRLpcGgYQMiJsedWOVsHdfcVzAiipjMHLlO4xGizuqAQPkMNo94dPeMKbxLbcUPnRYh1v8MXF6lxKo7YhXnfzSG8fH3Qk/t1GH/viPRjyw&#43;vSHI7taJ/d63gdoVVsE2mztFbBRHzsy0vyqPX4FxZPfuTcxI6Snf8fTCRMwibeCKJW&#43;uG46mfgjIY8pEOnNPpEPA/vGe6Vx3V87gfj2JmTH5x3jGF8erjqtWbB/zcAAP//Snsq3oAw0ocAAAAASUVORK5CYII="
     data-sizes="auto"
     width="1290" alt="Git status report after defaults are added."
     loading="lazy" />


</a>

  
  
</figure></p>
<p>Next I use git, xargs, and cp to copy those files into your module (hat tip on this detail to <a href="http://gregorowicz.blogspot.com/2010/04/using-xargs-with-git.html">Andy Gregorowicz</a>):
<code>git ls-files -om --exclude-standard --exclude=core.extensions.yml |  xargs -I{} cp &quot;{}&quot; pub/modules/custom/fancy_workflow/config/install/</code></p>
<p>Notice that I skip the core.extensions.yml file. If your module had dependencies you&rsquo;ll still need to update your module&rsquo;s info.yml file to list them.</p>
<p>Now a quick commit and push of the changes to the module&rsquo;s repo, and I’m ready to pull the module into other projects. I also commit the builder repo to ensure it’s easy to track any future changes.</p>
<p>This isn’t a replacement for tools like <a href="https://www.drupal.org/project/config_installer">Configuration Installer</a>, which are designed to handle an entire site, this is intended just for module development.</p>
<p>If you think you have a better solution, or that I’m missing something important please let me know.</p>
]]></content:encoded> </item> <item>
      <title>Preparing for your next crisis</title>
      <link>https://spinningcode.org/2017/11/preparing-for-your-next-crisis/</link>
      <pubDate>
        Mon, 20 Nov 2017 01:05:24 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=523</guid>  <description>Eventually every organization will face a crisis that requires a public response. In my experience most of the time the crisis that actually emerges isn’t what you expected and includes strange details that easily distract everyone from the main issue.</description> <content:encoded><![CDATA[<p><em>Can your plan handle the bizarre?</em></p>
<p>Last winter Dries, the Drupal Association, and the whole Drupal community, stumbled when concerns about a leading contributor’s potentially exploitive relationship got caught up in discussions of <a href="https://en.wikipedia.org/wiki/Gor">Gorean</a> subculture and related sexual behaviors (warning researching this topic will quickly lead you to NSFW information). The intriguing details drew in an ever-expanding audience but were actually irrelevant the main concerns and the secondary ones that followed. The DA lost control of the message and the story and the entire community suffered as a consequence. Last spring and summer I was asked to step in to help them regain control of the message and start to resolve the crisis. It wasn’t the first time I was part of a crisis response with unusual details, and likely won’t be the last.</p>
<p>The first time I saw an organization respond to a threat to their reputation was my senior year at Hamilton College when I was intern in the Communications and Development Department. The morning of February 5th, 2001 the administrative assistant who spent every Monday morning scanning major publications for references to the college and its professors (this is before you could use Google Alerts and other tools for a similar purpose) suddenly jumped up from her desk and ran into her boss’s office. A few moments later they both sprinted down the hall to the Vice President’s office. She had found an article in the New York Times Magazine titled <a href="http://www.nytimes.com/2001/02/04/magazine/the-cloning-mission-a-desire-to-duplicate.html?pagewanted=print">The Cloning Mission; A Desire to Duplicate</a> featuring then-chemistry professor <a href="https://en.wikipedia.org/wiki/Brigitte_Boisselier">Brigitte Boisselier</a> who – unbeknownst to the college – was moonlighting as the research director for <a href="https://en.wikipedia.org/wiki/Clonaid">Clonaid</a> trying to develop human cloning technology as part of her leadership of <a href="https://en.wikipedia.org/wiki/Ra%C3%ABlism">Raëlianism</a>.</p>
<p>Yup, the first time I had a front row seat to an organization&rsquo;s crisis was a college learning from the New York Times that they had a professor doing secret human cloning research for a group that believes aliens created humanity.</p>
<p>Within a hour they had a preliminary message prepared for any alumni who called – and they were calling – and got it to all alumni class presidents to share with any concerned classmates. By noon they had held meetings with all the needed decision makers including the college president, the chemistry department chair, the deans, and the VP of Communications to form a plan of action. By early afternoon that turned into a more formal statement that was recirculated to the class presidents and anyone else expressing concern to the school. Over the course of the semester, and the two years that followed (she continued to <a href="http://www.cbc.ca/archives/entry/clonaid-claims-first-cloned-human-baby">make world news after she left the college</a>), they responded to repeated media inquires – I was one of several interns in a mock audience for b-roll footage of a CBC piece on the topic – and even got her to engage in a public debate with an ethicist from the Philosophy department (which went poorly for her). In the end the concerned alumni were pleased with the college’s handling of the matter and the school’s reputation remained intact.</p>
<p>Eventually every organization will face a crisis that requires a public response. Depending on the nature of your organization you may already have a plan that handles the obvious situations: like schools preparing for threats to their students or political campaigns preparing for sexual harassment claims (at least they all should be prepared regardless of what their candidate tells them). But in my experience most of the time the crisis that actually emerges isn’t what you expected and includes strange details that easily distract everyone from the main issue.</p>
<p>Hamilton did not have a plan titled: “What happens if one of our professors is caught leading human cloning research for an alien cult.”  What they had was a general plan for “What happens when it appears someone is going to make us look bad” that was quickly escalated to “what happens when it really is bad.” They knew who they needed to get into a meeting, and that allowed timely decision making. The communications team then had a basis to work quickly so they could get back in control of the story. The plan they had allowed them to brush aside the unimportant details – the involvement of Raëlianism was fun to talk about but didn’t change anything about the response – so they could focus on important details.</p>
<p>Often when faced with these kinds of strange details surrounding a crisis the people who should be leading the response get distracted and start talking about those details. When it gets really weird they really want to say “is this not my <em>fault</em> and not my problem” and ignore it. It doesn’t matter <em>why</em> just that it <em>is</em> your problem. Everyone will want to focus on the salacious details, but you have to focus on the important details and lead your audience to supporting your response.</p>
<p>These are my tips for how to plan for a crisis and building a response that allows you to stay focused:</p>
<ol>
<li><strong>Know when to initiate your response.</strong> Develop a list of people and metrics to use to initiate a crisis response. It should include both some clear markers – e.g. a threat of violence against staff or constituents – and some fuzzier signs – e.g. anytime the ED/CEO or board chair says there is a crisis.</li>
<li><strong>Know who needs to be involved and how to find them.</strong> Part of what allowed Hamilton to move quickly was they knew exactly who needed to be involved in the process. Likewise you should determine which staff, board members, volunteers, consultants, etc, need to be in the loop and how you reach them quickly. And know who gets cut out when – if your board chair is on a cruise and can’t be reached until next Tuesday who do you call instead? If your director of communications is the problem you’re probably better off not having them planning the response.</li>
<li><strong>Prepare different types of response.</strong> You may want to monitor the situation while saying nothing; you may want to target different messages to specific audiences (your board may get a different message than your donors); you may want to try to use press contacts or avoid them. You should think about how and when to use all your communications channels as part of your response.</li>
<li><strong>Have metrics for testing your plan before following it.</strong> In a time of stress it can be easy to overlook important details in your response. While planning write up a checklist to run through to make sure you remembered everything that’s important. It should at least include a reminder to think about everyone’s physical safety and your legal risk ( <em>in that order</em>). It should also probably include contacts with important constituent groups (like Hamilton’s alumni class presidents) and any internal audiences so staff and volunteers aren’t surprised by public statements.</li>
<li><strong>Be prepared to share aggressively.</strong> Often organizations appear to be hiding information when they share it slowly, or when they say “this is all we can release” and then are pressured into releasing more. With any given statement release everything you can – sometimes with supporting materials if you need to – and then stop.</li>
<li><strong>Be prepared to shut up.</strong> This correlates with the previous tip. Sometimes part of a good response will be to be quiet. Usually this will be right before and after a major statement. It gives people a chance to process your response and avoids the sense that you are leaking information in dribs and drabs.</li>
<li><strong>Don’t over plan.</strong> Your next crisis will not look like what you planned for, so be prepared to change course from your very first move. If you lock in to many details you will likely make your situation worse by sounding tone-def.</li>
</ol>
<p>When you have created your draft plan you should practice using it. Some of that practice should be very practical: what do you do when a man in leadership is accused of sexual harassment or abuse? Some of it should be like the <a href="https://www.cdc.gov/phpr/zombie/index.htm">CDC and FEMA zombie drills</a>; even if you don’t use zombies use a crisis that you think couldn’t possibly happen – if you hear someone in the office say “good thing that can’t happen here” use it as your scenario. The first makes sure you are prepared for the kinds of things that are most likely to actually happen. The second makes sure you are prepared to think outside the box and handle a messy situation to which you thought you were immune. Your organization might not do any medical research at all, but what would happen if you discovered a board member was marrying the next director of Clonaid (including aliens is almost as fun as including zombies)? What would you tell your major donors?</p>
<p>A good crisis response comes from being prepared for the unexpected. If your plan is flexible enough to handle the utterly expected and adapt to a staff member cloning alien zombies, you can probably handle whatever actually comes your way.</p>
]]></content:encoded> </item> <item>
      <title>Drupal 8: Remote Database Services</title>
      <link>https://spinningcode.org/2017/10/drupal-8-remote-database-services/</link>
      <pubDate>
        Sun, 29 Oct 2017 17:33:41 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=513</guid>  <description>I recently completed a project that included pulling data from a remote database. I figured I might save a few people time by writing it up.</description> <content:encoded><![CDATA[<p>I recently completed a Drupal 8 project that required pulling data from a remote database.  The actual data is not terribly complicated, so Drupal&rsquo;s role in this case is mostly to provide an abstraction layer that converts the database into <a href="/2017/05/cached-json-responses-in-drupal-8/">a (cacheable) JSON response.</a> Pulling all the pieces together took a little more research and guessing than I expected so I figured I might save a few people time by writing it up. This is more of an intermediate than a beginner project and so I&rsquo;m going to skip over lots of detail that important to making it all really work. To really understand what&rsquo;s happening here you&rsquo;ll want a basic understanding of Drupal 8&rsquo;s controllers and database services.</p>
<p>What we&rsquo;re doing here is creating a database service and a controller to provide a JSON endpoint. We&rsquo;ll define the database connection, the Drupal service, and then the controller.</p>
<p>Drupal allows us to define database connections in the main settings file. This allows easy access to Drupal&rsquo;s database services and query classes.</p>
<h2 id="connection-definition">Connection Definition</h2>
<p>The first step is to define the database connection in settings.php:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>$databases[<span style="color:#e6db74">&#39;remote&#39;</span>][<span style="color:#e6db74">&#39;default&#39;</span>] <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span>  <span style="color:#e6db74">&#39;database&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;extra_data&#39;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#e6db74">&#39;username&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;accessingUser&#39;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#e6db74">&#39;password&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;UseGoodPasswordsIn2017&amp;amp;Beyond&#39;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#e6db74">&#39;prefix&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;&#39;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#e6db74">&#39;host&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;10.10.1.1&#39;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#e6db74">&#39;port&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;&#39;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#e6db74">&#39;namespace&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;Drupal\\Core\\Database\\Driver\\mysql&#39;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#e6db74">&#39;driver&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;mysql&#39;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">// I&#39;ll explain this detail later.
</span></span></span><span style="display:flex;"><span>  <span style="color:#e6db74">&#39;pdo&#39;</span> <span style="color:#f92672">=&gt;</span> [
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">PDO</span><span style="color:#f92672">::</span><span style="color:#a6e22e">ATTR_TIMEOUT</span> <span style="color:#f92672">=&gt;</span> <span style="color:#ae81ff">5</span>,
</span></span><span style="display:flex;"><span>  ],
</span></span><span style="display:flex;"><span>];
</span></span></code></pre></div><h2 id="services">Services</h2>
<p>Next we need to create a new database service using the new connection information. Drupal core&rsquo;s database service can be leveraged to connect to additional databases by just defining your new connection as a service in your module&rsquo;s services.yml file.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yml" data-lang="yml"><span style="display:flex;"><span><span style="color:#f92672">services</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">mydataservice.database</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">class</span>: <span style="color:#ae81ff">Drupal\Core\Database\Connection</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">factory</span>: <span style="color:#e6db74">&#39;Drupal\Core\Database\Database::getConnection&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">arguments</span>: [<span style="color:#e6db74">&#39;default&#39;</span>, <span style="color:#e6db74">&#39;remote&#39;</span>]
</span></span></code></pre></div><p>Notice the arguments from the database service are the array keys (in reverse order) from the settings.php definition of the connection.</p>
<p>That&rsquo;s all it takes to create a new service that wraps around your database.</p>
<h2 id="the-controller">The Controller</h2>
<p>That service is all well and good as far as it goes, but if we want to actually to send the data to the browser we need a controller to leverage our new service and send the response.</p>
<p>Using dependency injection I attached the service to the controller and it looked like it worked great.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span><span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">* Constructs a new DataSearchController object.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">*/</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">__construct</span>(<span style="color:#a6e22e">ConfigFactory</span> $config_factory, <span style="color:#a6e22e">Connection</span> $dataservice) {
</span></span><span style="display:flex;"><span>  $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">config</span> <span style="color:#f92672">=</span> $config_factory<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">get</span>(<span style="color:#e6db74">&#39;mydataservice.datasettings&#39;</span>);
</span></span><span style="display:flex;"><span>  $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">database</span> <span style="color:#f92672">=</span> $dataservice;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">* {@inheritdoc}
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">*/</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">create</span>(<span style="color:#a6e22e">ContainerInterface</span> $container) {
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">new</span> <span style="color:#66d9ef">static</span>(
</span></span><span style="display:flex;"><span>    $container<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">get</span>(<span style="color:#e6db74">&#39;mydataservice.database&#39;</span>)
</span></span><span style="display:flex;"><span>  );
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">getData</span>(<span style="color:#a6e22e">Request</span> $request) {
</span></span><span style="display:flex;"><span>  $query <span style="color:#f92672">=</span> $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">database</span><span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">select</span>(<span style="color:#e6db74">&#39;mytable&#39;</span>, <span style="color:#e6db74">&#39;mt&#39;</span>);
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">// From here you gather your data and send your response...
</span></span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>In fact it did work flawlessly all the way through initial testing. Using the database service to get the data and the <a href="/2017/05/cached-json-responses-in-drupal-8/">cacheable JSON response technique</a> I&rsquo;d worked out previously everything came together quickly. You could make a request of the controller with your search terms and the browser gets back a list of objects for display.</p>
<p>Then just before launch the client physically relocated the database server and didn&rsquo;t tell us it would be offline. Turns out we hadn&rsquo;t tested what happens to an injected database service when there is no response from the remote database server. The request would wait for the database connection to time out and then throw an exception that didn&rsquo;t get handled in my code at all. There was no place to add a nice error message and it was incredibly slow since the timeout was 30 seconds.</p>
<p>So at the last minute I had two more problems to solve: trap the error and shorten the timeout on PDO connections.</p>
<p>Drupal 8 database services attempt their connection when the service itself created. It you use dependency injection that means exceptions need to be caught in <code>create()</code>. But <code>create()</code> cannot send a response to the browser, that has to happen later when the function that corresponds to the active route is called by the kernel.</p>
<p>My solution was to make the database service an optional parameter on the controller, and adjust the static returned by create based on the exception thrown:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span><span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">* Constructs a new DataSearchController object.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">*/</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">__construct</span>(<span style="color:#a6e22e">ConfigFactory</span> $config_factory, <span style="color:#a6e22e">Connection</span> $dataservice <span style="color:#f92672">=</span> <span style="color:#66d9ef">null</span>) {
</span></span><span style="display:flex;"><span>  $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">config</span> <span style="color:#f92672">=</span> $config_factory<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">get</span>(<span style="color:#e6db74">&#39;mydataservice.datasettings&#39;</span>);
</span></span><span style="display:flex;"><span>  $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">database</span> <span style="color:#f92672">=</span> $dataservice;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">* {@inheritdoc}
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">*/</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">create</span>(<span style="color:#a6e22e">ContainerInterface</span> $container) {
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">try</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">new</span> <span style="color:#66d9ef">static</span>(
</span></span><span style="display:flex;"><span>      $container<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">get</span>(<span style="color:#e6db74">&#39;config.factory&#39;</span>),
</span></span><span style="display:flex;"><span>      $container<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">get</span>(<span style="color:#e6db74">&#39;mydataservice.database&#39;</span>)
</span></span><span style="display:flex;"><span>    );
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">catch</span> (<span style="color:#a6e22e">Exception</span> $e) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">new</span> <span style="color:#66d9ef">static</span>(
</span></span><span style="display:flex;"><span>      $container<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">get</span>(<span style="color:#e6db74">&#39;config.factory&#39;</span>)
</span></span><span style="display:flex;"><span>    );
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">getData</span>(<span style="color:#a6e22e">Request</span> $request) {
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">if</span> (<span style="color:#f92672">!</span>$this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">database</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">throw</span> <span style="color:#66d9ef">new</span> <span style="color:#a6e22e">HttpException</span>(<span style="color:#ae81ff">404</span>, $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">config</span><span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">get</span>(<span style="color:#e6db74">&#39;database_offline_message&#39;</span>));
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>  $query <span style="color:#f92672">=</span> $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">database</span><span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">select</span>(<span style="color:#e6db74">&#39;mytable&#39;</span>, <span style="color:#e6db74">&#39;mt&#39;</span>);
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">// From here you gather your data and send your response...
</span></span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>The other way to handle the exception would be to load the connection from Drupal&rsquo;s service container when you need it in place of using dependency injection for that service.</p>
<p>Also, notice we&rsquo;re throwing a 404 error. Ideally it would return a 5xx type error, but those trigger other behaviors that prevented me from providing nice errors for the JavaScript application to process easily. Our controller also had a page display (to send the JavaScript libraries and base markup for the actual interface on application startup), which meant that we needed to create a reasonably well themed response in that function as well:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// If the database is offline, then send error message.
</span></span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> (<span style="color:#f92672">!</span>$this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">database</span>) {
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">Drupal</span><span style="color:#f92672">::</span><span style="color:#a6e22e">service</span>(<span style="color:#e6db74">&#39;page_cache_kill_switch&#39;</span>)<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">trigger</span>();
</span></span><span style="display:flex;"><span>  $message <span style="color:#f92672">=</span> $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">config</span><span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">get</span>(<span style="color:#e6db74">&#39;database_offline_message&#39;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  $error <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#39;#theme&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;dataservice_error_page&#39;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#39;#attributes&#39;</span> <span style="color:#f92672">=&gt;</span> [
</span></span><span style="display:flex;"><span>      <span style="color:#e6db74">&#39;class&#39;</span> <span style="color:#f92672">=&gt;</span> [<span style="color:#e6db74">&#39;dataservice&#39;</span>, <span style="color:#e6db74">&#39;database-offline&#39;</span>],
</span></span><span style="display:flex;"><span>      <span style="color:#e6db74">&#39;id&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;dataservice-error&#39;</span>,
</span></span><span style="display:flex;"><span>    ],
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#39;#message&#39;</span> <span style="color:#f92672">=&gt;</span> [
</span></span><span style="display:flex;"><span>      <span style="color:#e6db74">&#39;#type&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;processed_text&#39;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#e6db74">&#39;#text&#39;</span> <span style="color:#f92672">=&gt;</span> $message[<span style="color:#e6db74">&#39;value&#39;</span>],
</span></span><span style="display:flex;"><span>      <span style="color:#e6db74">&#39;#format&#39;</span> <span style="color:#f92672">=&gt;</span> $message[<span style="color:#e6db74">&#39;format&#39;</span>],
</span></span><span style="display:flex;"><span>      <span style="color:#e6db74">&#39;#filter_types_to_skip&#39;</span> <span style="color:#f92672">=&gt;</span> [],
</span></span><span style="display:flex;"><span>    ],
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#39;#title&#39;</span> <span style="color:#f92672">=&gt;</span> $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">t</span>(<span style="color:#e6db74">&#39;Database Offline&#39;</span>),
</span></span><span style="display:flex;"><span>  ];
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">return</span> $error;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h2 id="settings-revisited">Settings revisited</h2>
<p>So that fixed the errors, but still meant we had a really long wait for the database connection to time out before the connection error is even thrown in the first place. And now we come back to that PDO section of the database connection definition.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$databases[<span style="color:#e6db74">&#39;remote&#39;</span>][<span style="color:#e6db74">&#39;default&#39;</span>] <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span>  <span style="color:#e6db74">&#39;database&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;extra_data&#39;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#e6db74">&#39;username&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;accessingUser&#39;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#e6db74">&#39;password&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;UseGoodPasswordsIn2017&amp;amp;Beyond&#39;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#e6db74">&#39;prefix&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;&#39;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#e6db74">&#39;host&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;255.255.255.255&#39;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#e6db74">&#39;port&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;&#39;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#e6db74">&#39;namespace&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;Drupal\Core\Database\Driver\mysql&#39;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#e6db74">&#39;driver&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;mysql&#39;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">// Now is when I explain this
</span></span></span><span style="display:flex;"><span>  <span style="color:#e6db74">&#39;pdo&#39;</span> <span style="color:#f92672">=&gt;</span> [
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">PDO</span><span style="color:#f92672">::</span><span style="color:#a6e22e">ATTR_TIMEOUT</span> <span style="color:#f92672">=&gt;</span> <span style="color:#ae81ff">5</span>,
</span></span><span style="display:flex;"><span>  ],
</span></span><span style="display:flex;"><span>];
</span></span></code></pre></div><p>PDO expects you to override settings at connection time not in a settings file. So I couldn&rsquo;t just update my PHP.ini and call it a day but I also couldn&rsquo;t find any documentation on how to change any PDO settings. Leveraging the power of open source I started to follow the code paths, actually reading through how Drupal establishes MySQL connections and, <a href="https://github.com/drupal/drupal/blob/8.4.x/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php#L127">found I it</a>.</p>
<p>If you add a subarray in your connection definition keyed to &lsquo;pdo&rsquo; Drupal will load and apply those settings instead of the defaults. There are a couple settings that Drupal insists on being right about for performance, stability, and security reasons, but timeout and many others are fair game.</p>
]]></content:encoded> </item> <item>
      <title>We can do better</title>
      <link>https://spinningcode.org/2017/10/we-can-do-better/</link>
      <pubDate>
        Sun, 22 Oct 2017 20:45:49 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=509</guid>  <description>It&amp;#39;s time to make sure our colleagues get the respect and support they deserve.</description> <content:encoded><![CDATA[<p>This week, for the second time in a year, the <a href="https://code.likeagirl.io/there-are-weinsteins-lurking-in-every-profession-including-tech-d833d7d92758">unacceptable behavior of a high profile man in the Drupal community</a> has been the topic of public discussion and debate. This time the <a href="https://docs.google.com/document/d/1oJabbjROc0BSNNvxQf1PA0epcIlc0n53A9Tb_Xez5sk/edit">organizations involved</a> <a href="https://drupalsouth2017.drupal.org.nz/news/schedule-announcement-keynote-withdrawn">acted more clearly</a> <a href="https://www.drupal.org/association/blog/status-of-speaker-agreement-violation">and rapidly</a>, if imperfectly. The issue came to the forefront during #metoo campaign, and again showed that the Drupal community reflects the world around us. I listened to friends and colleagues respond in various ways to the events and to the recognition of several men that they had been allowing this behavior to go on right in front of them for years without intervention. It is clear that in Drupal, like in all parts of our society we can – and must – do better.</p>
<p>As I reflected on these discussions this weekend I read back through some posts from <a href="http://www.danah.org/">Danah Boyd</a> I’d read a while ago and stashed with my list of ideas of topics for blog posts. In particular I read her comments from last March on how <a href="http://www.zephoria.org/thoughts/archives/2017/03/03/failing-to-see-fueling-hatred.html">failures to understand people’s hate fuels it</a> and then a piece I had initially missed from July on <a href="http://www.zephoria.org/thoughts/archives/2017/07/05/tech-culture.html">change in the tech community</a>. Her experiences and perspective are worthy of a few minutes read in their own right, but this week her views seem particularly timely.</p>
<p>One of the things that struck me about Boyd’s piece from July was her clear simple ask:</p>
<blockquote>
<p>&hellip;what I want from men in tech boils down to four Rs: Recognition. Repentance. Respect. Reparation.</p>
</blockquote>
<p>To me the first two are painfully obvious and most men who care about these issues have been working through those for a while now (too many men still need to learn to care at all). I count myself among the group of men who care, and the this post is mostly directed at that group of peers.</p>
<p>More and more you will hear men acknowledge they believe women are telling the truth, recognizing there are more stories we don’t hear than we hear, and apologizing for their own actions or inactions in the past. But of course just believing people and saying sorry doesn’t get us very far. The next two on Boyd&rsquo;s list are the places where real forward looking change comes from.</p>
<p>Respect should be easy, but too often it is the first place we get into trouble. It is the part her call to action that will always be true no matter what future progress we make on these issues. Respect is an ongoing act requiring constant care, attention, and effort. Meaning to be respectful is not the same as actually being respectful. It requires actively listening to the ideas of women and people of color and considering them as fully as you do anyone else’s. It means tracking in yourself when you fail to do listen and making the personal change required to do better going forward. It includes monitoring our own behavior in meetings, hallway interactions, and one-on-one discussions to make sure you understand how you are being perceived differently by different people – your friendly or silly gesture to one colleague could be insulting or threatening to another. Respect is not something special that women and people of color are suddenly asking for, it’s something that we all already knew we should be extending to all our colleagues but too often fail to show. And when we fail to show true respect for coworkers – regardless of why we failed or which demographic categories they fall into – it’s our responsibility to recognize it and repent.</p>
<p>Finally Boyd also calls for Reparations. Reparations is a word that lots of us fear for no particularly defendable reason since it&rsquo;s just about attempt to undo some of the harm we&rsquo;ve benefited from. And in this case her ask is so direct, plain, and frankly easy that I’m giving her the last words:</p>
<blockquote>
<p>Every guy out there who wants to see tech thrive owes it to the field to actively seek out and mentor, support, fund, open doors for, and otherwise empower women and people of color. No excuses, no self-justifications, no sexualized bullshit. Just behavior change. Plain and simple. If our sector is about placing bets, let’s bet on a better world. And let’s solve for social equity.</p>
</blockquote>
]]></content:encoded> </item> <item>
      <title>Make sure you have the pictures your site requires</title>
      <link>https://spinningcode.org/2017/09/make-sure-you-have-the-pictures-your-site-requires/</link>
      <pubDate>
        Sun, 17 Sep 2017 23:33:14 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=388</guid>  <description>Frequently organizations fall in love with a site design that includes excellent pictures on every page. Those designs and images may be great, but only if you provide new images as fast as you create new pages (often faster).</description> <content:encoded><![CDATA[<p>One of the challenges that organizations of all shapes and sizes frequently face is getting good pictures to go with their web site design. Good images can draw in your audience but a missing or poorly displayed image risks damaging your credibility.</p>
<p>Frequently organizations fall in love with a site design that includes excellent pictures on every page. Each story in the design has a wonderful supporting image to highlight a person, place, or topic. Landing pages may have main images with carefully placed text and overlays to help draw the eye and keep people&rsquo;s attention. Those designs and images may be great, but only if you provide new images as fast as you create new pages (often faster).</p>
<p>Much of the time I worked for <a href="https://www.afsc.org">AFSC</a> we were lucky to have an in-house photographer. Terry Foss traveled around the world to visit, get to know, and photograph AFSC’s programs and he provided us with excellent pictures for nearly every area of our work. But even then we still had challenges getting the exact picture we wanted for the story we needed to tell the moment we wanted to tell it. In addition to his wonderful images we would dig in the <a href="https://www.afsc.org/project/archives">archives</a>, beg local program staff to send us more images, and sometimes we end up taking a picture of an intern’s hand or other acts of desperation.</p>
<p>Web designers have to make many assumptions when they design a site and one of the most important practical issues is the quality and quantity of art the client can provide. The more prominent and plentiful the image use, the more specific questions have to get; sometimes down to the level of aspect ratios and staff image editing skill level. Good designers use this information to help make sure the images in their designs are the kinds of images you can routinely provide. You should know what those assumptions are and make sure you can follow through over time.</p>
<p>When you first launch a site this isn’t usually a problem. A lot of time will go into the stories and images that are included during the build and migration so the initially launched site should be at least as wonderful as the designs.</p>
<p>But as time passes the constant need to specific kinds of images may become a burden. You will soon realize there are places that images are required for technical or stylistic reasons. Some images will have text overlays that mean the subject needs to be on the right or the left. Some spaces will be very large or very small, which impacts what subjects work well. Some will be surrounded by a background color or pattern that may clash with an otherwise ideal photograph. The more you understand this while working with your designer the more you&rsquo;ll love your new site.</p>






<figure class="figure-figure-left">
  
  <a href="https://web.archive.org/web/20100917040003im_/http://afsc.org/sites/afsc.civicactions.net/files/imagecache/normal/images/HandWriting.jpg" target="_blank" rel="noopener noreferrer">
    
    

    <img class="rcf-image external-image"
             src="https://web.archive.org/web/20100917040003im_/http://afsc.org/sites/afsc.civicactions.net/files/imagecache/normal/images/HandWriting.jpg" alt="Hand holding a pen"
             loading="lazy" />
  </a><figcaption>Here&rsquo;s that image from the Wayback Machine. The image is owned by AFSC and was published under a <a href="https://creativecommons.org/licenses/by-nc-nd/2.0/">creative commons license.</a></figcaption></figure>

<p>We had to photograph an intern’s hand because at the time our home page would break if every story didn’t have an image – it was a design and technical requirement. A few months after we launched we needed to post a statement that required home page placement, but the statement had no image to go with it. I had no budget to buy a stock image and the program had no appropriate picture we could use, so one of our team members grabbed his camera and an intern and quickly shot a few pictures of the young man’s hand holding a pen. We ended up using that hand image for several statements after that as well.</p>
<p>So here are a few quick guidelines for making sure your web site isn’t held back by a need for art you can&rsquo;t consistently provide:</p>
<ol>
<li>Make sure you have a plan for getting new pictures. There are many ways to do this so having a plan is more important that its details. It can be a staff photographer, freelance photographers, volunteer photographers, an organization owned camera that staff use, or a budget for stock photographs. The best plans are usually some combination of all these pieces.</li>
<li>Talk with the site designer and make sure they know what you are able to provide before they start the design. Will you be able to ensure pictures for every story, blog post, and event? Do you have editorial standards about the use of images of program participants, volunteers, and staff? Does your stock image budget allow you to fill any gaps, or can you create a picture of an intern writing a statement from thin air? Can you edit those pictures to work in a variety of spaces and sizes, or do you need to assume the pictures get uploaded more or less they way they come off your camera?</li>
<li>When you start to see designs ask your web development partners lots of questions and document their answers. Ask about every image you see in the designs. For <strong><em>every single image</em></strong> you should know what size it needs to be, how it gets loaded and changed, if is required or optional (and how things look if it&rsquo;s not present), and if it requires some kind of preprocessing for an overlay or other visual effect. Make sure you understand the purpose and details for every image they show you.</li>
<li>Try lots of variations when the site is still under development. Upload great images, terrible images, images that seem too big and too small, a sunset over a field, an ocean scene, a portrait of a baby, a team group shot, fluffy animals, flowers, and anything else you have around your computer. For each spot you can put a picture try each image and see what works and what doesn’t. No design can handle any image of any size and description equally well so make sure you understand, and can live with, the limits imposed by the design of your site.</li>
</ol>
<p>Finally, make sure you actually follow the plan or fix it. Having a camera is only useful if someone is comfortable using it. Volunteers may not provide what you need in time to be useful or may forget to sign the releases your board requires. Budgets get cut or adjusted over time and may no longer really meet your needs. When the rubber meets the road your plan may not always work, don’t panic, just fix it. The reason you took all those notes about what you need is so that when you adjust your plan you will already know what it needs to provide to make your site successful.</p>
]]></content:encoded> </item> <item>
      <title>Code Without Community is Dead</title>
      <link>https://spinningcode.org/2017/07/code-without-community-is-dead/</link>
      <pubDate>
        Sat, 29 Jul 2017 18:40:52 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=341</guid>  <description>We like to say developers have a right be judged by code alone. The problem is that it’s not actually true nor just.</description> <content:encoded><![CDATA[<p>With the turmoil in the Drupal community this spring and summer I have seen a wave of calls for open source projects to judge their community members, and other contributors, by the code contributions alone. It’s an idea that sounds great and has been popular among developers for at least forty years. <a href="http://esr.ibiblio.org/?p=7516">Eric Raymond, while writing about Drupal, described it this spring as a right developers deserve</a>. In some circles it gets treated almost as religious doctrine: “Thou shalt judge by code alone.”</p>
<p>The problem is that it’s not actually true nor just.</p>
<p>There may have been a time it was an ethic that held communities together but now it’s a line we pull out when we want to justify someone’s otherwise unacceptable behavior. Too often it’s a thinly veiled attempt to protect someone from consequences of their own choices and actions. And too often its used at the expense of other community members and other would be contributors.</p>
<p>For obvious reasons open source communities are dominated by developers. And as developers we have faith in our code. We like to believe our code doesn’t care who we are or what we believe. It will do exactly as asked every time. It forgives us all our sins as long as we faithfully fix any bugs and update to new versions of our platforms.</p>
<p>We like to claim that by focusing only on the code, and not the person behind it, we are creating a meritocracy and therefore better results. I don&rsquo;t need to convince you I’m smart if I can show you my wonderful and plentiful code. We will be faithful to the best code and nothing more.</p>
<p>But none of this is proven to be true.</p>
<blockquote>
<p>What does it profit, my brethren, if someone says he has faith but does not have works? Can faith save him? If a brother or sister is naked and destitute of daily food,  and one of you says to them, “Depart in peace, be warmed and filled,” but you do not give them the things which are needed for the body, what does it profit? Thus also faith by itself, if it does not have works, is dead. <a href="https://www.biblegateway.com/passage/?search=Jas.2.14-17&amp;version=NKJV">James 2:14-17 NKJV</a></p>
</blockquote>
<p>Any project worth doing could be done many different ways. One solution might solve the problem more quickly, another might be easier to maintain in the future, and yet another might be easier to extend to solve even more complex problems later. Which of the solutions is right will depend on the problem, the users, the developers, the timeline, and everyone’s guesses about future needs. There isn&rsquo;t some objective measure of <em>best</em>. We figure out which solution we&rsquo;re going to use by working together to sort through the competing ideas. Sometimes the best solution wins, sometimes the loudest voice wins, sometimes the most famous person wins.</p>
<p>When you say that code is the only valid way to judge a developer it tells people how you expect developers to work together. If I see that out of a project lead it tells me expect they me to put up with jerks and bullies as long as those people write good code. It says that women contributing code should expect to be belittled and degraded by colleagues, friends, and strangers as long as those people can solve a problem as well or better than she can (and often even if they can’t do that).</p>
<p>It says these things because for decades that&rsquo;s been the behavior of large numbers of developers who are still welcomed on projects and praised for their amazing code.</p>
<p>It’s a simplistic way to view people that encourages the bad behavior developers, particularly many famous developers, are known for. Instead of creating a true meritocracy it drives away smart and talented people who don’t want to deal with being called names, threatened, and abused in their work place or while volunteering their time and talents.</p>
<h2 id="people-who-damage-a-community-because-they-mistreat-others-in-it-hold-everyone-back">People who damage a community because they mistreat others in it hold everyone back.</h2>
<p>If you join a project and write a module that brilliantly solves a new problem, but drive three people off the project because you are unbearable to work with, your work now has to offset all of their potential contributions. You also have to offset the loss of productively when people get distracted dealing with you. And you have to offset the reputation loss caused by your bad behavior. That better be an amazing block of code you wrote to do all those things, and you better be ready to do it again, and again, and again just to keep from slowing the project down.</p>
<p>Terrible developers can move a project forward. If someone comes into a project and writes a terrible module that stimulates someone else to solve that same problem better, they are making the project better even if none of their code is ever accepted. Or if someone takes time to make new participants feel welcome and excited to contribute, they may cause more code to be written than anyone else, even if they never write a line of code themselves.</p>
<p>And just because I can solve a problem faster and better than someone else doesn&rsquo;t prove anything. If I start a project, or contribute for several years, I’m going to have more code credited to me than a new person. I’m going to know the project’s strengths and weaknesses better, and I’ll be able to solve problems more easily. Which means I should produce better code than another equally talented developer, or even someone a smarter than me. I just have a head start on them – anyone can beat Usain Bolt in the 100 meter dash if you give them a big enough head start. If we judge just by code contributions, I can use my head start to make sure no one catches me. That&rsquo;s not merit, that&rsquo;s just gaming a system.</p>
<p>Developers are people. People are flawed, complicated, biased, and wonderful creatures. Our value to a project is the sum of all those parts we choose to pour into a community. It matters how we handle discussions in issue queues; debates with community members on Twitter, Slack, or IRC; the content of our blogs; how we act at conferences; and anything else that is going to affect how others experience our contributions.</p>
<p>If you don’t care for how your community functions and if you don’t make sure people are treated well, even when their code is terrible, your project will suffer, and eventually may die. Sure there are examples (big examples like the Linux kernel and OpenBSD) of projects that are doing just fine with communities that allow developers treat each other terribly. The men leading those projects (if anyone has an example of a female lead projects where vile behavior is tolerated let me know and I’ll edit this sentence) are happy with the communities they have built. But can you imagine what those project could have achieved if they hadn’t driven highly talented developers away? Can you show any compelling evidence that those projects succeed because of the bad behavior not despite it?</p>
<p>Communities will be flawed, complicated, biased, and wonderful, just like the people that make them up. But if you only focus on part of someone’s contributions to the community you may miss their value and the damage one person can cause.</p>
<p>Faith in your code, if it isn’t matched with works in your community, is dead.</p>
]]></content:encoded> </item> <item>
      <title>Controlling Block Visibility with a Custom Field in Drupal 8 (updated for 9)</title>
      <link>https://spinningcode.org/2017/06/controlling-block-visibility-with-a-custom-field-in-drupal-8/</link>
      <pubDate>
        Mon, 26 Jun 2017 01:20:13 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=321</guid>  <description>This week I was working on a site where one of those blocks needs to be enabled or disabled on specific nodes at the discretion of the content author.</description> <content:encoded><![CDATA[<p>Awhile back I wrote up <a href="/2017/01/a-pattern-for-drupal-8-blocks/">a pattern for creating static blocks on Drupal 8</a> sites. This week I was working on a site where one of those blocks needs to be enabled or disabled on specific nodes at the discretion of the content author. To make this happen, I&rsquo;m adding a new feature to my pattern.</p>
<p>In older versions of Drupal there were a number of ways to go, like the PHP Filter, or custom handling in the block&rsquo;s view hook, but I figured there were probably more appropriate tools for this in Drupal 8.  And <a href="https://drupal.stackexchange.com/q/203308/210">I found what I needed</a> in the <a href="https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Condition%21ConditionPluginBase.php/8.2.x">Condition Plugin</a> (more evidence that <a href="/2017/01/drupal-8-plugins-are-addictive/">plugins are addictive</a>). According to <a href="https://www.drupal.org/node/1961370">the change record</a> they were designed to centralize a lot of the common logic used for controlling blocks, and I found it works quite nicely in this case as well (although a more generalized version might be useful).</p>
<p>I have the complete condition plugin at the end so you don&rsquo;t have to get all the details exactly right as we go.</p>
<p>I started by adding a boolean field to the content type named <code>field_enable_sidebar</code>. Then I using drupal console generated the stub condition plugin: <code>drupal generate:plugin:condition</code>. In doing this the first time I also looked at the one defined in the core Node module to handle <a href="https://api.drupal.org/api/drupal/core%21modules%21node%21src%21Plugin%21Condition%21NodeType.php/class/NodeType/8.3.x">block visibility by content type</a>.</p>
<p>The console will ask you a couple questions, obviously you can attach it to any module you&rsquo;d like and call it whatever you&rsquo;d like. For this example I have it in a fake module called my_blocks and the condition is named SidebarCondition. But the next couple questions are less obvious and more important.</p>
<p><figure>
  <a href="/wp-content/uploads/2017/06/condition_contextType.png" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    
    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2017/06/condition_contextType.png" alt="Context Type should be entity" loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2017/06/condition_contextType.png 290w"
     data-src="/wp-content/uploads/2017/06/condition_contextType.png"
     src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAABeCAYAAADrChyUAAAeVElEQVR4nOx9eVccO7LnT0tutRdg8HW/6T49b/6dDzhfdc6ZNz3Tr699DdSae6akdyKUVRQFBWWMudgQ55QxZKZSUoQifrFIpYPphyUARR9BPwUkACEA4X90dPO/2&#43;QO/vJEOvCiQ&#43;//FrrTvefo7&#43;sn5wfqPw7WAQbdRz766D3/ffBv300HGnVPfJ/7jmffAOlDF9x9i&#43;7BSXzOGd60dc&#43;yf7bXvEGJuGfIBwXg9lMP6d8fOZEPCMJ3t/lOeEwAblh/SAheajJ33/OtwvB2GX7MyB/VALeF4Hle/H3r&#43;fkZ&#43;nZFBNC7a/ul1vlbnvA/m9ze/&#43;96Ae/ceVN0RwDe&#43;f/r0n28lYcuvNOvRW6PyZtf7w0EOfcuFL8SHealIy/gsJ//LgS/Pm01wDuzf2E6oP6xHwe4pQv2FcO7hPwStM9GvX/Z3yA879&#43;Z/suQ2/l3d2U/mAx6p1&#43;fjkgG7ZEAhBRcKcBCYp13Md4l5qck/Viub5eEEpChgEokVCjgrIMpLEzhYM0TfUcuOxEQqvNVjbvjsz6pTRLSDuI6atMe&#43;Sg9I70JpPEd&#43;9zPSO5bNABNKDE&#43;&#43;qARn2vogYSrLMqvLcovDZrsZrLERiE8lsRzXbs9iYDaaxya1MDWOxP/rcmJjvm6LxEMJTO/WVsW1MeYScyXsUTQ95LTZhamfPy5o/q5f/2VaEwWgEe1AE1qJBB&#43;0Oj/e4TkXLEJMJllZjULA1M5f5/qcoe0elrw5NHE8t&#43;lLzKjv7nWr3QVScTnAZJPGrYwyP8TqBcGtvG9Is0gtLj9nO2uya7eyWG72lmoQoHoXGPwtxCutsj&#43;UaO8Akz1ADOJ&#43;aFEOFXofQognEPxpUU1Q9eXbpKsHxt1SMjbz2&#43;1jvNax7Y&#43;qkZj95&#43;9a9anY6Skj4BzFtZY2O9WgY/T5g1HaQC/ohSSTwGS3zTQWJ6cZm3Qrq1XJUMFPZS88ohZtnJoVl4wZOJXuAz8BPFKXxm0hYOidv8twPDvIUxmOq0AXrVQAsFYQfckpPKMaNcGTep4MlUst&#43;qdTBORrSyv4uQvIQb/HgK19fc4MDPvXdEkm1pw/2mMg7&#43;HHCChNkUguC/0Phl5rUeagfpGY2WBcGCNqBLB5owY2&#43;YWzdIwo1nDjaTvo/MLp14amMxBiRC9fh9xFKKpK2RZhqqq4V5ACHC0ACg/wOg8gI4F8t9bpP&#43;nQpNazzBaxX8J0PukoeJutTqgvmpRzQ2CiUbvN&#43;2Zb/2qqL62yH9vICPFqy6YKqgYiFaK1TXZYT3S6P23oFPJntHNrEXxewMnBKIzDakBazwDTWFQXRkIWskTiWCigEYiOjU84dRfU4l79S&#43;tUNWn5zTCEw0pHNpSe80m4QX1XMPkBuUfLUSkEJ0p2E6gkr8EzGRb&#43;n7awqL83KAtHcJzjfi0G79zfC3/Z4PiXwaBS3D64QInkyHy9RK/f/6MpmlhjPkR/L5DjwuA8KBIxoKFgH7nVbj0KxhaIJ5IXsXxB4VmbkB9p8nhlRu10GPNvxvSGJVjgaDJIFXfZJZXGK0qmxnUc/83WnnxJ43&#43;3wJejaZxrEGCvuBVXqcOeqRYIxHzqU/ZPwg/WKCFZzYJEt1L71l5c3UIYZKWMLRqV4Y1m4RDPTMswARy1UAgOPHjIE0gEoVwJFF/bWEtGBcRMC6yhucr/qihE8ECEP8WIOhJ1greTPppNWtAZhJaawRBAK0VpBDPWgD3GH0TCBSyA3h2Y3sdd5iEg1Q1qel63qItATVUCPveJBDjGIzNWzSd2qdJJGrTjkFrA7PyK7hZWp7sYKj4g5armT0W0L4fJAS0Osn0kHkh/EBtsekQzgtoauFIK1y3LFiMAQ5UNxO24L6QAC68AFSXDarLljUMaTliYPJRIwm8Oid8wRpAblS7Yc2GDkuEZwqqBsITBaUFbId7GGwGZHccmqbCajGHbUpURYaqrl8EA2zoOAEgtdU4mNJBkxsYS7ZrjIW04MEQ873x33O7upCia8ArzJRgl7GbMz8pjYM7oPGIMfQcqXC6hya5Xlu2rVs3bTcO4byA2qYTVLHzeXiIHpxt&#43;qJ2rhmPPaprw14QmR4Bh&#43;L/t6wxZF95xnZtCLvrijqeE8Ie1AZpTRpTddXyfBLoa5oGdSX5p7X2RV2EowSAJpKBy3WLIAm8N0DoP/VqlYAPqUmdSIRnGroBq2oaKIFBegsxmhhPk8vegfSIeoOKiUgzRB&#43;UR9kSXYzB8sqln/QuNhW19x7ofTazqLqVHY4V6oFBkzvPTAvoRDHDqK88juKwFvDC48PhxNToIoBpCDx615QwTbMOkFAfC8tMJNMSxIpNFgFlUvcEEGkttGROCucXieyEIHOsNbxJArQOMRyNMR0PkKcrFGXJIPClhEDJpPe/vKx64IubHUFikxLY5gWEYJBHE80qjjABqb7cqzay&#43;eFIsf8tOqBHkwTnl3szIzXsfW1Sn3SdJkIEhJK9Kid7DuMni95MmoYYTSqX1S5potyxCdE9wZNMappXreiEpvSTTuZBsQfhhZGE2Dw0t2TOoq4vY/&#43;s6Nok4EaPebMkGYxm/1GjWlgGq/2/hYgIyHb9pHcV/2xQXho4R&#43;0KdjO3ngBpg5WDFjHGkxOMRwNY0yBN16jKH2oGOl3lRf54DUCo9ksNIRzMJ4/MaXXTym8WLdtHYg4BQTIHpBoJrZPLplcOTQy2ray6UfPEkq33cYQW2T9o0hSrVmJgmxIKb7ib8bmCioS/d&#43;Ujj&#43;zeMVMNM1WPfHSSg0itY1yR/keFdq3Z3Jhyx1wcIutxQP6vhu&#43;l9thtNG67LGiM7dKg&#43;sN7OAwsrTdjtuhwxKxF&#43;aXldggEkvZpU81CReNjoEkglQCrq5GulhCuQZmnqOvmRTGAUNOzZRemUYBT2IZrbjSAv7NzlRIfYdOdD04DZr9Y3ET0RKe&#43;6RoxXIQeIzBzXOdfw69ynsAuysh&#43;tEQnWH7FqU0MIRQdUndbN5Ea4TYJU9A7dKchqk6Nx4LbJA1gO/990weme&#43;aZw92x9/G37ZWdV/IxQP&#43;vIVQAZP&#43;3Rvb/algj0Pt7iOn/jNl1pL8Vf7QMQtnsGD9e1kaJNw229BFPU9BkK4RhhEArGNOiqiq0rXnuOIC7CZmR4RXG7w90Zk8AoG7MwJ4AbCZIdlGt7gqr3s5u&#43;mvdjV3EzLmNOIkbF0yIrV&#43;/CUMKsRODd3ttboxTB/Bg3baNbSRw5x1uJ&#43;u5zQe4ncQVDgsAdvMB4ibKSGaBXF1S84a0xD9rlDPD74wvNPp/DdhbIf&#43;eMINp3BbbbMe2E63cBKd4koX/OO67&#43;xFBoIMCcNgEHELNHfK&#43;F0eZ&#43;9G8u5MYuFuissv0Y9rcb&#43;PuO26Dum&#43;hjZBtn5PCm0Ba2RwX8PECMjU0T/XMwNU&#43;RN2u7Z2Q86GxoavAeKmo33307engN0g&#43;6&#43;m8udrkA7ZZS8fRQTIxW4H7iTKIhwXgQIbo4cTRRp1ttLHzgOYBAd&#43;ovx&#43;lAp&#43;rJbdJAn3jtddOd0rCPD0cNSG1dQcekAslJcIw5A&#43;j3brmyJaxdisUGxu/4bHSGlEUQasNCKrRtu2jQiB2zq44fO/PyZSXpCebALcnLFIIBGGE8fQEJ9MRhDVYLuaYLxao2wZhIJDEPiBSVw5FZWGsRJQkODk5xaCfoC5zXF1dI00zGHOYecR8pRTH0J2zLDDG7Ovdb7f9b5EeFoCjyoVuYHwQRZienuLj&#43;RnaMkVdZMgChTC2&#43;HCmcX6qECpgtTL4/LXBYi2YiUl/gJOzKdoyR5HnyPOCGeruqahgsC8l4l4Pw0EfbVNjvV7D2pvgiTcpkoUSnYZwG1MkupLXzU&#43;4zlvpvI49k4QHNcxu97rnbr3vbpu3&#43;tN16OZa1xc8Q1XUkfRMINDxwJXS7NNqJZDlBfKigNQWH84D/I&#43;/h7g4UQi1QJEb9GOB//2PBllVIU1TDAZ9hFKySbi/JNlt30Smptfv4fTDGeoyQ12XqJuGy8m8dtAIo5AzbCQEZFrIHDWtYcEIwhCBUtyOsxZ1XfHzHM0MyIQFUHTNOU7Ltm3Dnif9jW5qjWEh9M8bvqZ1gCDQfI&#43;1ht/n2xTQQcBmUatNmy3H/cnfpza4P6zNHJqm5mAQvfclvIPHBeBbigY7n7dtGmRpirLIEQ0cPv0W4OOZRiCAMBSYjAJ2i67nBunnGul6jXQwwKgXblp54AV&#43;RdGkkRAoGDYHYvt&#43;iTiJMT05xXA44Emn/qyWS6xWKaQOMT2ZsslRQsK0DVarBeaLFawTGI0nGI&#43;GzEyiqiqwWq7QthZJEsOZBmlecjtxHKKpCrTGojcYYTgYcEDH2hZ5usZisURrgMFojPF4hJDbdKirEsvlAllWIowTTMZjJEnE5ixPU8znc6zT7EcEhO7QkdnA7ucRgsDqzVovwaBJEziZKCShQJYZCK0QRhKTscKoJ6Fli9a0NxJ/lLr1QrAppdrgQY63SMFaaDQaYTIZIwhCDhr2kgTAV8ggwae//BtGg4SxgzWGJ99CwokAFx8/YjzsQSrFq7apSnz5/BlVbTCdjmDrApezJVQ8wHjYR76eIy8qjCYTZnJEKz3QqIoUUfQFVQucfbjgWD8BY9Jw1tT4&#43;iXAYpVjOJ7g7GTKwuFYOApEgYJpW6RZAfMqBGBDjxV57hHdsgF/USTQND650rRelSu9jegeD9gfvO/mLBNjDatqHYBX2XBksFymgIpYQ5DvlmU5lA4QJT30B0PIMMF4PIRra2Rlt8p7PSS9HqQ2LFSmkljnFXSvh8FwANcWKDl&#43;vxF6gSjpo5dErF2qxmI6GULYFussR9wfYpD0MBwNARVjenqGMQljXQFSoZ/EaKsC8/kCeVHiDrZ9Zno6BvgGYVBKoJf4&#43;rmstMhyi7q5B&#43;jsx&#43;gPaZ5bz20i1h2wkwqBDrv4esAgk1akJbtOqw/Cr646w2y2QJQM0O&#43;F0OS&#43;xjF7KetsxavTyQCTUd9rGwKVStFgIJXceiGKbX/E7wu71U&#43;fQCrESQKhDZQEsvUKs&#43;slBgaIQ824IOkHLFxaSzS1gzU&#43;c&#43;pD20cUMTwDPQ8IPLAxhAZC2KyqHatmLYG2dlwk0RrHmsDarjbgsfY3tHOeDTGFGBF0IMtYhzCKMRgN2R7TxBOoCtvwlrCR2meQVlWQQQRrg70X3j4jswvY8v&#43;k9kCXMAgJFLm&#43;w5HGZDpBqCXHPKh9kiTvFTx8whoBxqpqGAiXZc2/p6sFyvplCkOfNxS8zfV4&#43;wxIFKXBfGGQnlnehRJoAS2AdW6RFxatFYwLZDdh&#43;20dJsEMGAxHOPvQIO4N0NQtM67f6yEKAwZjNxU2myhjV3pNH7v5GAaKFiWsHWAwGEFHPYwmY0SB9JlLwikOSOI&#43;JlMBHfcRhQo5YYVIM0BUrkVJfWDh9/EJTu/2&#43;ugNxziTIZLBCFEUIk8tyqJCFBZcQmZaw16DaRpUZcW//3wCgG5lKs3qj1ZlWRT4/EeD05HC&#43;VQyJiA38OvXBsu1ZeBFAI0nUO0eV3Wofbd1pYxx6A8HuPgYYlo3KPOMg0hcwmaBOEp8mloARVWzNjBWoihy1GXJrpisKhTSocgyWFFh0OtzIGswImb1YeqSBaksC6Rpgfh0guFoxN4GuZ9lXqAxQL/fwyCJEEUKwlmUecWe0DqroHSM6WSE07MBojjm3D/ZfFrpxOPTkwn6gwGboCrPGUC&#43;VGHoswkAqUhiCvnUrelxUCiOYxSrCl8&#43;N7zql&#43;eahB2LeYt//t5gkTpIFbA7FwUaxmxy4Y/UbViLPMtwdXnJjCTzQmqX/l/kORqbMSgbDQYMMpsuWLRerdnVg6OVViHPS1RNiyrXLBQOGoukhyQKGT/YtuVa/aossV4u0bSOfycbToCvKDLMZ3M0xvvvBCAVxx0MyjLHYj5HWRMw9FhkNOyzh0RtUD/XiwUj/bapOahFXkKeZxwIa2geXiCW&#43;XwC4ByaqsJiNgMX0pkGVd2iaSzKigTD4uulF4SisFhnBAQFRwnrknztObtcNHivtg8TMZsE4PO/fsd1GHS7ahwsqdGuqna9TnEdhV1couW/V2xXgbLI4JxhYRNFiVwKtt1BmHT3VaiqAM62yNZzFpw0XbNvTqtWqy7Y0/gCDnofrfbry4j74oNHPtijdIikX/F9ZaC47KtIV1guV2z3W5siz3PEUeQ9JBaOAlXd/FwmgAWgrrCYXyPPVlwTWHM0rGVw1q4M0tT4ihhLH8dRMleVWMxnSNdLZixP6CMC4LpEE6H5fC8ptJm0siyREq7ATYbRdhk7Wq3Yhngbjz0It6iANVhe5BDOwLY1922&#43;WLIWoHFUZXHnfa4ba56l2yIS11WphJHgMRGTQZjENFjOZ7ieLVFWNbdJz/q&#43;euzg5&#43;ZA8eoz08MlYcf4IeL2L/JWzNtuY&#43;wHH9/G0MW2OOK7JP&#43;Jj3IIWQeMXXq9BEEXQSTTUBQVxxS&#43;tV&#43;32kwSdvdIaEn9F2X5IpG&#43;jo4tCTtCAF5y28r30BPmlQWxi/Fvkjqkjb5HKPfbJB6Y72zzCfSEkrB9OorxOwUhGxX5SGZrmwnb1vM908Q84Xwjfrcx7CJuax6/sy83bb7MXr9vpeME4EjmK&#43;UzW2EQ8KxvMmJk04Rwt9Kl3hzfZO60Ul1Q5PiCkP3YwSYPccfs7O8HvbX/7q6ACiluUsn29nbt4wpRfh56NhBIkxaEESZTv8nBtTWWiwXWaQpjW4ShRBwJdsvICygqxy5ZGEUYTyYY9Htomwqz2Qxpmj&#43;4O5Z88DAMkZCtDoKtUJE7VRbFVujuEwIvOIo3YhLqIDu8Ucnoag247ThmbVkWJQdzXHdNK7/PwCew7E8vBMftDj6COEUbxSwA52dTlOslB2aqUCKMNc7PFE4ninP2X77U&#43;HxpkNfePoZxgtFkCmFqVEXZFYQc7pBSCv3BCBcfz9HvxT5H3/oU7Oz6Gja1aMVNcQi62kTezCoVkiRhv1s6izTLOJvXdi&#43;ktnv9Pk5PpoBpcX193QFAwUGcQX8ArcD7&#43;DlZs9tRtwkZ31f88Trp&#43;TRAp85pkkKtkJI/XVWQyuH0VOO//zXExamCaSxcYzFfGhS180g7L9CMDZJui/TWVBx4l5Qavf4Ap6dnSCLFq74sPfO4wCIIEenAJ2akgnWG3ThySYMgwsnpKS4&#43;nHItwdXVNa7nCy5g4VxCGGEwGGI4HMLUBZZLzeNSQdgJ9xkXtcznM8zmC5Rl1fVJ8FiatuWElK&#43;LBLuVTfO4Sfuz6IeUhbMtL0uOaVtlYFqBsjAoC4k4FIhCASX9mS9tS65WyRMZqQg7uxHvpc0GEKUCX3zRNsjSFbKsYF&#43;7aS3nBU7OTjHs91mgTNtgsZhhsUwRxAnOLy7w6eMFlDCMPwRX8Vxz1C7pDzGZTjEaDpCvfbGJDgL0hyNcXFzgt98&#43;ItK&#43;IonM13K54jRuHAWo8gyrdQYVkFkbcwp4PpthbfKthnlt9EMEYOM&#43;kY2sG4vLqxamdigrh0/nGt0RP943cT4jtnG3jkHsoos3SKUQCMcrPggaTtNKpbk6h5g17CfboEoQKM5AOql95TIBT2G5IjkIA35WSOdrFHs9DMcjSBB20ZBld4hDGPL9JABx5NO/9O4w6eF0OkFTptDBghNFH85OUBdrZOn6dmLxldGP2RjisHX/2tZhvSYt4NDvK5xN984VfKpm3II5iTiOeIWRB6FUy/V5SkrebJnmJcK4xyFZMg9k8xfzOQZJDI0WV5dXmM&#43;8Kjet5TK2PMvhzqY&#43;5duVqxMjaTX3khhxIHF5&#43;RWXl1coygoDoSGCEOPeGaSOWcv0kwBX2cJXHb1S9Y&#43;X2BlEY7eGQBq4umV3e&#43;Aj2v6Rdj3qb4oCV1dXWKc5m5K6cehzwqVEmS4wX&#43;XoT07Rj0PWNMTg1XKF9XAAjYaFYbla&#43;4OZAA71ZnnGyH9DtjUo2hzLxZLxQRMKTgLN53NO2lgo9lwGFx/w4aLH7nCRrjiHUJb1q9408lgpxtNW6E7pNTqApAOBIAC0pp&#43;Cfyq1sznyGyWBBYDwA9ndlU&#43;uEJDzMQTr8&#43;uVT8LwyRtdWJrMkt9HcDcMK3b9fAHWGB5Yip39B8Z7FN3cWOOFit7fWsf1CUmkUWRrTkj5yuDXKwDHF4V&#43;gztIqpn880Br6LZFGAGnU4XTqcagLwGjuFA0Kx2ySvoDkgLti0geMZhuu6HSH0AYkQs5GkPqyG&#43;tbsxNAYfx2IKYRAKxwQNcL2gtkjjCYDRCXvrVb51gF7Df7/tiUgvO0/f7KadtqS1C&#43;VJFGAyHKKuKV3nDJiJlIHo6HaOtSqwWS&#43;/OWvuqN6gcbwKOEYLO5/WoeYDBoIfGtohji&#43;FQMfrnWkAhkPQUktjBipgLJMkv18LssPhwP5y1qDh1nCOJ6V1jBFHic&#43;zrNZqmxHotUOT&#43;uBWVZXxoEGf0WsPeyWqdQqsRB6&#43;SXsIFI4Z9/YRXPbmWwhl2AQnwka1vmopL2ONQs4CQoNSEHYoSbV2jyHKOReRL8jhWL1bW9T30tKrg&#43;zaNdsEYn&#43;lKIHXAiFlJhaoyuL5uUZWWK4IIE2SZRV76Grs4jqGlQEOTXDeP2ExS4w3WqwX&#43;9Z&#43;GS79YZLrNGEVRMM7IspSrbhoutTJItWTGMygrclx&#43;/YMLNSUcp47pvRZgsOdsi&#43;Xsuqvh96lcMiPGNpjPrngLG9l5LhZpGh5rksQItOTKouvrOVZc1/8yKd3voaeBwP1BCZ/6rasC15df0ZQ&#43;n07AqG5a9s1ZCGZie64DqWPrJIKwwmo&#43;R1vkXBBCz3A9wD3v2BBdJ7tLQE8IudngtXU/t9qq22ZFfdjdsmVtjXTV8iYMX5/gtjUIHFHM0p1tZb5&#43;0HTX88ygKvKbrWNCcg3hZDrlqGRZZFgsVih&#43;7Dk/z0bPVhVME01qcLVcsBqk6WtN2&#43;W8bRfa3Z8QC2tLzNsrrDgY422svU8DuNu/WLbvBntpnQOg9W4QhvDBvfkGa/nu3VDurTfvZPYY7yg/hda0XNSSLhdYkRk6IqH1Guj53EA&#43;K8nCNQ2HRLd/fnAS3BaoHXf/3Xf&#43;qLq5Y/rhs4&#43;&#43;NvDrH194TyThDDJD9wrxK6RnjwM8Rep/hpVyiEh466rkmARulXT9HGN6PyLmGWizv&#43;BnJC24qEJ2lYw/BrVu6/42pVZcZPH6EfJbIK3DEEEY&#43;90x5Cfz/rTne4EvjNSIophdJSnACL4g39mYdyH4k0mHcYJkOOKaftttl74PWN06xcIdZ7c3VbF&#43;&#43;9YZTqYTCNfi6o/P&#43;OPrlT&#43;F810C/lTyJkB2X8hw4CxVLoXSgT/ggE/I2IRZHyni7A5yGE0mnJ49Oz2Ba0vU&#43;Rqz2fynKTD&#43;lUlzYIR84qaFM/fZZcEVOHGvj8l4hEAJrnIpy4rDsXXtq2DcAzFvLhApCk6zhny0vD/YwacEf8A3VT8asn7m9/3EpLE90Gj/UKaOut0BHBPv9TAa9Lmah7ACZ8EWCz4KpSirbbTshvwXIiznM971WtctTk9Gd33kl1YFD5438LZo6wYeTr74YEdV5nzODjH/5OQEZ5NzKOFw9fWPbk&#43;e/7IDd&#43;tR57dvZf7YtyQZYDTqvb4ZP2JT8q9Kxx0X3yV6qu7LDIx1fJpWHOouCaIY3R961jp7IxzdEW7e/XzewXw3PVSJ&#43;ovSVgAO8qLz38mN4xO0xmPOwPFe/GXJJVVpUXAxxP2PC66lj&#43;OEs35RGMLEMf8/KCpY&#43;7Ln4z9Kb0wINLZbs&#43;TBqhwhFJ&#43;hE8cRn4m/Xs5xVRbI0gzrdM2HLR0qfBB8Vk4P09MTnJ5OuZBCK4dpmjFu4GQR74V/RfSGhEBvMloqCCCUhDB3T2pzzvAe/vnsGuul9GcAVxXqpmYGWnvIn/elXqqrDSDkX9XV1oRorW&#43;2ob6RCX9tpNl9s5v0pryHG75suyx9/h17CY/Hsn10b1UWmF1dosjX3eEKPp&#43;f5X7P/WuyAG&#43;NNK1sZ7vafPLnDxz3xRHCgyv9MBGzyYNoyR1cyFt/55z&#43;z3S4/i9Iuq1rDgJtkkH3HtH7XVul3bbi5lfbWfsrkDcB3WHP33Qm7BPonemvj7Y6&#43;Z01b4d2ef34xpD9J94CvaHxHicAeEOT8lbG2dEPPS38p6I3wvj9Yeq9i923/N5Kj9zP6ocm7KWF440w74nkdn64/dnSOzftXHBuZ&#43;/uE8p8n9DN9xz&#43;j6R9xm9/1zfnxwn&#43;dF97KMVDW3N&#43;VBdfFb26Dn0PbY7esDffHO5PadA70rC5QXZfg7g9KFJsz/N4W/QLjHj3GI7N18bbXZ7vCADvt&#43;7u56O1tgKwOdPhTxrEOz2N9lS&#43;2Fnk2&#43;JPFgB7&#43;5mt7d9l&#43;Dvzf066x&#43;77r8befPYEAJ25OPKg6Hf6icjtmfobAXD8/W5glu8y/10Afi1yuwessAAIuP8KAAD//&#43;S5b05lBpvzAAAAAElFTkSuQmCC"
     data-sizes="auto"
     width="290" alt="Context Type should be entity"
     loading="lazy" />


</a>

  
  
</figure></p>
<p>The context type should be set to entity since we are looking to work based on the node being displayed.</p>
<p><figure>
  <a href="/wp-content/uploads/2017/06/condition_contextentity.png" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    
    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2017/06/condition_contextentity.png" alt="Context Entity Type should be Content" loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2017/06/condition_contextentity.png 390w"
     data-src="/wp-content/uploads/2017/06/condition_contextentity.png"
     src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAABICAYAAAA&#43;hf0SAAAZbElEQVR4nOx9d18bS5b2U1WdlAHje&#43;ed37t/7Pf/WLszcwMYkNS5wv7OOdVCCZGMjW1qhguSuiuc8JzYcmLOL5cAjAIS&#43;g0oDUABm/&#43;&#43;2aDpw1tM/CaTfoOh9v9U8f9q53P1GGP2P97QI4QAeAS4AFggOP219v6S8aPy6WcapwXgR&#43;TQj7jn7zgeR4AfiaA/0l7fyUiedFV4e3/gwXU/xpuOpwkAXsGM5wjOB8O/&#43;Xi6ALx0fDD1XY/vGgV8jO8/PgTgFx8fAvArDHXwx2Z8CMAvPj4E4BcfT48CXpMH&#43;IgE3u14XAC&#43;RgJomONDEN7d&#43;LYm4HtkEz/GyfEkE6CUFIzpdyAt9gHBP2MVhft78Uwk2KqEhufe&#43;9ie9ueM&#43;xw2G/bXesna22d/hwh4WgBo81pB5wrJWEOlCqH3sKWH78POgQZiCQHjYWMNge7TiUJwAb4H/95cC7nuGG34cy33Kg14GxBseJiY6nBOdQx1jszJtxsFUyj&#43;7VoP30l3hEqiQFgg&#43;COCgeP74Xv3zn5MsNTwH3U4n1JqcwY&#43;z0DTeHE4upmnj5MCQAvrQiH/lCC7MHwQu3YALFwTmFC0DzpcIIEgwqZCWEIIJqwC0oVBMtXwtUd/52AbORhdS0aI7iXC7p5UCKgzhXRuoFPArj36pWfmBPcAsTPFc7OgeNkjMVDFfXonc2Y0Z3Y/p3cBptB8TpMqdDeOBd2MNZKZBmxAv/Z8bh5RELh9JpAgiXBsGEd7zzWyM8P3D2d3vdq7PzZ9GNzv0wZRMAiNNAsg4DsSQgWtDJIkYSJba&#43;G9Py6UrxUAgv1kapD/liCdarja80ZMrpFMFR9Mk7Y0ggpE7HQmhKUD2JWH98DoHymK3xLYW4vqXz302kMXWhibAK70sJXn9ej1QERish5pjP6RIBkptH9bVOgRbgP8liYysZl5CfJzw8R0lYetPTOVmMja3gTY0jFjRv9M7&#43;dUPVwdkMwMis8J78GTkAWN4vcUxT8SoPdo/rDo1p4ZFSJykDCRAPcrEY4wVE6Zdhqj/59h9LuBvXOo/92jrwILKgZhTO6Rh/bJstF4no8mYuUpNK/V3Tq4OyBTY0wnE3jXY7Vao23bFyPBwwIQNZCgn5hKGtBdW96YGWkU/0yRLYxouxUCEGFI4pnYRJQbi74MfAjSLBUCklsHpEoIS8Q2QL90aP6yfH96ZlioiFHdF8fE4vujAIqG7/WTGblm8t8Zxv8v4fXt0qO7c7zXZCBs59FeKQRszdl4mFwxPBPakRCYBGhzB915mIlGdm4QWsVnJN4l8&#43;HcYA3tlxauDXDtFvmi6SMlIcGk7RIDgxF60H1EN0YAYsRM9kmMDB0EaY1GfmlY4UInAtiEgMIXWJwtYPuWmd913YsdjEd8ALWBJpJKVwX4NiBZiFDQZ0QEIjIxjeDcZIDrou9QaGBtmXH0Q0xlJo4NssuEmc2a0AcxB6lG/lk0s/nfgPZPC9cF0WZiainzkOaEbcdNi7aRQJEAsnY6IPEBJtPMDIJ4VWjW/j7OY42YAEvn6uRsZCZULucm/4DXLj1CK79dH5CSAF&#43;KoNF9rnQM6dhycskEEuK48v7stBYhos4IWQybqoE2hFQsVD0YCUjwSDAJgWlupyOSpR6B5rUO3rm39QHYYXFiO1maJ6Q9GiYTAmGw80GYz3aKYdYDg&#43;PTyWuCeCayDTCDGY2mg21jE2BM2CAPf04M6MAMY1jm&#43;2XdXUG9t6U0D2kPmR8SHt6U9XBWCEuCwOtWntFH7Kownv0WL8Ex213ydqIAEAISgpCp4L2Sb0Am5K&#43;er6G1tnnBZ49CQ6bIM0KQAEGUoEiREPLUjhWANd/LmVUGGCNnor3xHCvHSEmOafAezjk45&#43;W&#43;V8jAwwIQxAYzAdYe2Vwj/y2FWTnmNxGOIMsQo4NcByduKmmUGgSAtEp5hkgSIkILet8uHZTXTCS2t15OQQf1lRCCnc4m2tYZWEuI6K4GlNsK4UhDyMm6dSARZbSq433c/xo2qMFaST91QJhg4yNAx/Pk5HjJeyTowxkI2QiKbSUoxk4a7WUt9CEk3EdhWnPYBysQCeCdCB&#43;tTzJro2OZEYpNNHTq&#43;ez9HUGF5/fIx6B9e9qzUzAmQTEqYHv62xyPdF4tAIiEXTu0ZJ9VwkQgh4Xsa&#43;stwoXYMoLJ7sayBJP2sgmICEGes2oC2lwxQYlIBIv1f3r4C7H3JBwkUOzhV13MMQR5vw08tzayH/bqWdvDjrNIKFL/q4fvxK9gwSVHahUdLh&#43;g15r3SnsKsII0XgQtpKL5tCZtYIhgiIHtjUM6VRKcaDkXMaQPjj&#43;jtQYB3lEg9o0cO5okWJxLiXQhGhCUU7RBZsHHqIadvWuH7srxeuQ/kIPIpqYVc2m1Y9vv&#43;o6R4FEECAd/PE0AiBEkne1VL85SpjYwSIchxgz&#43;ga2FIWzHHO5NQufZl6AD8P29oIFeKtZYIr4czkv4FpNM4l8EhjzH/ocXm1uHCJnb&#43;wzMBBIqIjjP2caQLQxJGNnzEGLx58OcrZgBNjml39h2stvkHPq2h71V91GHEcGwt56ZRec5xgRCDxLq4HpBEzI1W/f3tQgQCTU5zL4UmrbXYsLAjqNnAWChIeSoyOKu4foewTs0TfcqP0CdfDBkuEhjE/MPDs5ACDkptjQgpr1UvNjH2fRuJpEdTH3vze9mCcPWB/H94X6/G2/fb1Js5s6cG19hKysUbaZSu3Pez7F9JmzOMsw75AoImsn5a68GBHiIwkK7IXLZ3D/S7KtQZDBEOgRqZOd5PjvQXm0iBdmPJIG0ihFD/Nlfc2eceDDkSQLw4DiWTj1xLY5d92aPB73BUBL2kS&#43;gogPJSSn/xDPs3x8hHTHhxfrSx8xkwO6TQTtPDX29J4Ne3hSqSAoVtI4xNmej/H1ac5MelmsY3kOI14Ujm4tHU5IlHLb72jDnq46BQc5tkO5ZNZFj99PxHDbp6EGZDpj8Rq35LxYArQ2KosBkMmZbVFcletshTYCEbLAL6KwskY/GyNMUtu9QVTU6sl97jOXUsDFIkxRJYjjU6fse1lnxC56wJ6U0tFYPQ&#43;PJe9Xm5&#43;T9MTp6MWw9cH/4Ts9evEwAlIQis8UZfvv8Cbatcc1eq8fZQmM6Vuj7gJtbj6rNMJnNsZjP0NYVQrhipjoXtqZTMEmC8WSK&#43;WyGPEvR9x3WqyXKsobzg5qJN48thmFTEFHIsox/QhAvue/FkCpCoD1EGZBruJ&#43;EJy9y5FnGgto0reTZ3xMCvXScMLPJ4ZVPmY8cE4M8H2E8GqHsG6RpwGKR4L/&#43;meBsruFswL/&#43;bfE/f4jDlaQZFDwXMdRe4ErEL4oRLj5d4uJ8ARU8qrKE7TrJnBkpfjhn0TathEd5jpTgxgd0fceCMSVBWyzgbYfb2xus1tWGsYkxjChd17FA5FnOSENzynsJzi8ucLaYoS5X&#43;HJ9jeWqRNfb92WGXjUOJSHZ/RAPvjyYSol3SnafNCZJSPsNPp0bTMYaCcXUfcD1jcO669BbCx2Ol2dJG4vRGPP5DKnRuLtdYrlcobMOk&#43;kM88UceU6a2WO9WsOFgPl8gaLI4J1FXZYomxaz&#43;RkuLy/h&#43;0ZwVhk2P4vFHFmaoG0arNclC&#43;9sNmUBor2vVitYF3Bx8QmfL89RLnP0XYu6oX2/Pt366PiOjTLHTcBjG1Lbjh7HdUiSgPFYYzTSyDJF4QSKTCFLAbCnvOcqq&#43;2yr0KapcjSFH3X4O72Fst1iTQvcDGbMQNJSGgtgmjngel8BkPxunPMXH97Jy0IW47maDzG5W&#43;/4&#43;Jswb5B17UYjVYc6IxHBcizcC7nrazKml/z/c5xrv1gz996fAPBSPCUsOIJgxCBnL88Mr9rA6yNNnd/erX3e5AphZ3WGYJ9gnp6n2x6kqQo8oIRgBjatjU7iGQiaJ2mrlGWJVzfoGk7JGSiJhM2AaTpNLeRJLskUTpJWZJJcNairmpUoxxlVbKzSqj106D/AyN5LvTvD7bnSrNWdj0xHaxJTetRNQHshynNRJYU3&#43;EcdD0Rm&#43;A2z3PM5nMy/Ow3GA4hNUcd7KFDNJzsOTE8sPOXwHmHrvMcYZCp0TF5Qmajqko0VYW6btB1PTuKcIqzaCpJWeNt9AVoH7SeMXHPcK&#43;h79cbb4QGj0YBp9BB0poGaZqhrDS&#43;3DhcTS3GuUJTe9zceTSdhklSpEkCL9JxMIihTVNjvV4jXcwxmy/4HmIIwTbZerLXdB1pZ9c7fl3XFe&#43;wtynatkPbOzRNg1GeclRBzuFyeQdvR6zhNF8bvfvOKEYJlSQAMb/t4INC3bQw5OAWI6RVw5HEz&#43;MEPqMW8JhZIAjt25YdK4LkrlP486&#43;etWk20mhbj6svHmWTYjzV7G33bQd7xKkiW0vafH11xQUOcvjICauqCmVVM/zTe/QZOXGEFOTBE6wTAphEs3Zb6xnm2wj5xGDS&#43;Ho6kSiAHLuqiWFf4Hm4chQcmrqBalomUpYatBSBPCvL88LxLRzAE/K7KwAnniHbT&#43;WSRq2Xt4Dv2BMvq5ZhtKqALFUc5xM9KWx3YcnEt13L8fV&#43;5YzLyezhL9G1DWs3CQUnjHxgZCCGk3DRe1zZowiEnL2YL6fP6H2G/FJ8Aucc2/KqXLPtp2tEo4WxngVBbRw/cjb6vmP49yTgXX/ch/mJhjLnn5cKMFBDLWAokQxXPHBjTPGyU4UA68RrVkMb9FC8UFKzluKFNDL4/dLp1lp03WDrw17SZz87t58fDJGhKhaiwk5n7ZB6fTirGDbO6PdPRW/n/79fLeDEOoMzNhDID3ltYsLetcx0&#43;MiUEwSl3R2B3VP3HBOCAxPzDCaGr9Bq/SONF9cCVEwHczYuBPbKnZcih45lX2l7liweefMEq6famCW5pLnIdJ&#43;PP93yrKC2hECxadgtUN2jCJi5L2&#43;hfmyorYcSDtDnPRa3Xi4ACtrE3P18Cm97rJZL9LblxE&#43;akk0XHwA6xWQyxWhUwHYNtzE3bXuguQT9SZpygYkjBu/YwRRnbKv7Z6tHYIB67lFTklHM84Lbpcj&#43;UFxPgkkRQZqmEglw2tjvwNtTmLJbd9hi9tAvoMQckuwN/XqIWU4KO0kBaC/0M/ge&#43;2vvp8i/2thkgE&#43;mgp83IQnAZDbH5edP6Ko1bFdjrCwuP2nMxhrLpcMfVw6dNZyROz8/Q99WEor1PVHpfjqlkGQZp3fPzhac2SNncHl3h7AGF4O2nbUQhLCi6WKKiKhZXuDs/Bznizk7ndfhChQoFuMx1yzapoJfOVhGCrOpHB6UqOMY3pO&#43;u3sEkbK1/Az3Uig8mUyQckRSs/NJ&#43;06zHNPZBFmSsDPLZ6E5dexWpr17EYhN2dx7vm5wct9y3AvAsXLkAyXKoRiUZhnyNEMX08Hjscbvn1N8WmhcZcBy5dH2chiC9iyVUu/&#43;lEMt4OLTJyzmU2Ze17bMpPF4jDTPWShIg4mw5BuORiNkBDcxh9B2FsVkhs&#43;ff8diNsbq7gbLNEUeFBaLM0zGBZa3Hm3TISsMM4v2QwxtGon3uU3b2c2eSFuhNCNYnqX3hSOlOUPJWt21jFJZMcbny0vOQdzd3uDq&#43;hpN26MYT3B2dsa1EYowOuuQZTmX0Q1nM1sOVZM0Q1Hk/B6dnYSFQtsHHeavNHYRIDI8cHS9&#43;5jW/lBREDgr1/XoOgttHMrK4GymkSYKkvyTcIpsv9k/y1AL4GpgwUyBd1je3mK5XLPbOJstcH5xjiLPYG2P9XLFWcfF&#43;RnnBry1KNdL3C5XyIopZrMZ8jzBOmYoiVHT2Qyz6YjrDMSU0XSGTxcXbJZIAMr1mrOC2ii0nF0E1ybWqzWUSfD5828o8pSLTlVVwaRZXCfndPTd7R10kuL8/ByTkVQ9q7qCh8aIi1xzGCXruKBxdn6B8/MFM7uOGcpiNMF0Omb/p6kr/PXnH0yztuvftBzxoAnY4fsD6LBdfLG9x9p5fLmzWMwkNQwVYte2j00dxzuB2AQYwxpluxbVumQC5qMJRpMJRoUwKk1zLOaaYxgWluDgYDjfX1YNaychhG3B1USCYmKg5fSuYT&#43;A/ANi3qjIeV2aU03Jb&#43;kZnSqjEZSSopOTiiKhjXcdz2edRz7OkBcFxuMJz0fr1k0n9QrlWUjqukXfdaz1hIBZZtjHGemUBSLPcqbLaDyRGkcxQpoYNmVksshspnfLNy9Hn/AB9ri&#43;1fN58F70hYjJQ&#43;8GaX9iJCI46drEOfymWVPDJAaJEcct3cB0y3aWiMRt2c6irku&#43;J0k0E5O0eLVeI1WefxNDTOqZQfQ52XIyG&#43;xkBgfb9sxsxG4kYhAhBlgwJHJxUIw85WrJVcqE/IxMUtOaMyaGz0g&#43;S1WWUD5jAWhiQ0oXHb9RFh/o1Ip/k1Ba6zjpROtINrRF7zybPNoPN4S&#43;cT3ydFt4FAK1x7DtDUkrlzwaZlKN6URjOtWcZphNNG7X4FQtF2fCntBEeSIEYeewazEpMobIJMuliIQQvfs8Vu16JhKhC0UJga9IOQQlgpLG0WfOOvE7soLNC90f7Ai99fIoWULCpdmP6dqaow6ojDWP1iMBE3RzXI9o6pptvckKZiD5JySYnp/SIQS0rK3jcS6RCDFRG0YvXr8oGEka6ZOLc2hBz/iIl&#43;tb9GTztYmRytuP5PFuw2NiEOLhHX9KWpplCWtblipGAXKWicBFrqGzVNKrnRdzEO7NQYgCQLaQbGny6YwhkASrrCpUZSVlYQrjuE1shdZa1sC2qXlnaZtwLl8qhBV6FTZVPWIwab7UIASqurbDeDQWR8xodPWaC0vOB&#43;4TIIghuCfn0LrAdpnhPxaUaE8ZoVRi2GEjzadrydzkecoREjl07INkGZ/FkuApzT4LXa8nE&#43;6/pv2WhBz0met4D2knpWne89sLAHbh/gF52LbfrLXOyebXOROGNLFpPP7zZ4/VSp7DWpcBTZehSALatkHfHG8IJWEiZ&#43;rLlyt0XcMOF2kUEZ0UoizXDN0SBVSsMaQ94rFL&#43;ESMofdt3/MzKYQEpEN1VeLvv/7E3c0XtukEy1kxYqgn5mgV2Dm7u7mBD7fI8owxhfa7XpfMEF6zl8KSC2t20MrVXVxXPHauRnYdOhKEiE7kL9D&#43;KVKQiEGuMWaJZVFIT0NTc9EKsSgWGPESNjvfoh2NnwtQ8jzAphbwlA4RzSXTgj1pUnnSINq00oG9W7Bmg6el&#43;JzsLsE3ebzSaHHYFUyQzc6gEXh1UQNoLdLUsAWX&#43;2PIsu0nWIZ8wfA&#43;ha8U1l1&#43;vsR8OmHGXl9f4ebmlquDw3VSs3DRL1E785u4R0T04mu5JV6zOVQbZmIT3&#43;/vUfobRJHcAdyrTdqcr3/DWkAUAH7G51kCsJt2Hb6w4ZjdeuS5gP2r1b6p2X3vxRqhVCz0SGhI8E9mhYSWIbztdu3uiaLRfsbu&#43;XvaKbcdKsN9Fej&#43;9VsVg3YO86xzCNP3nZVDBkpZ9smznsjIvWpEhpKQksdOmr8jlM/Iur1&#43;P6cf6d7Jw7zxSLjdymipxMWne14yBljjwo&#43;J3q218enV91QAOS64v&#43;pIDMXaeS59cW3LT/TsOHxPqmZJHD0aTbi1u8gzONdjtVzFDp6fqa3q5xpJkmXIxmPYtuNHjneKNFpLiMfJmMD2kkKTfTsubd05zi4u8Pvvv2EyHvEj0Vd//SWVMfKmPwTgXY6ENJfiVqW6vW4Z&#43;TqyvBjhbDFn75yzXRSbx5bpAUYJIYZuXkKAUTGSnn3b4/b2dlMZ&#43;xjvbyQ7D3jsfwNjbNEqijELAVmC9fIOV3//jbvliquAQ1gj&#43;eycM2BpmnBBJI9p1zerc3&#43;MV49kOwF0ANLRQybtJV9hMir4iwSq9RplWUlX7VAe3nQIpdCQDiHJZH1A/3se8mSQuo&#43;Th6HiB5yEiU/OlOWaO3frpomQHtO5QZpC&#43;z56/QiS22&#43;lB//DAXy/IxlahXR8EkZ5tdt5GyQt&#43;uW6Zx&#43;gLEtO0bJnv3UNd/As73A3KVBkKadEV1xnb6UFCuoIFnwIxvceiXM2fuHQ9qO7w3fSeM5V39zwF&#43;GKhlNsvxcFiAC0uLm&#43;4oaOcZFz8wU5gDU/B&#43;C3Zt0eL/cNPkzL1xkJxf5NzITxwxE7NX4vDQ22j82YksE6ID75CmQiVisufKTxIY627d7sAcvNt2V/CMKrRkLa750d2nsO0pBclNn7zpqdVuyhMTfmCQhRmu2HON6YP7tt4T/xeKxq/8KRSHlgw6gQTfWLljqWKXxiXemJCzx0&#43;y8iBE8d4fBRvq1XO&#43;8kRy7an&#43;Loh8dfvNPx3vf4bHV7go4&#43;0ePWxy4IR24IW/87PvtxKn8LzfxptX&#43;fI0dfPXWmSKVw/xoRAcLhz1Z/&#43;EMovtPbd3pL&#43;58f/Q68F5zp5G0/kkwcabjd9sWECfdPQOFIh9ap2ffaMAfPjLU5ic/UBjV8qWtkuWwAgyAcXeMwGnhgCwf8DgcfPoaC4bFFfiSGPzT2BCEg/htBEN4zI8IhpQ6OrvY&#43;2o7Yhc/Dl&#43;CSAPC3/u8&#43;ChJfhM3Sj0DA0V3sffaIR/Eq/v0MzN8eG3odtoaELWI&#43;zUnbMSTDNyD7EPi7b3xy/88v8GJ0sVc73wN2OOOxBR/lwf73LHyNkCYc/fMHlohjjI1YvPMVey9Smg3sCwqIICT89Z73E9NFOjoL6iFJeymxT0cPp1vTf42xxdgQNV9tvf86Mgx3D0UcFoD/CwAA///08/&#43;JbMokbQAAAABJRU5ErkJggg=="
     data-sizes="auto"
     width="390" alt="Context Entity Type should be Content"
     loading="lazy" />


</a>

  
  
</figure></p>
<p>Next it&rsquo;s trying to filter between entity types, and since we&rsquo;re doing this based on the node content entity type, select &ldquo;Content&rdquo; to get a list of content entities on your site.</p>
<p><figure>
  <a href="/wp-content/uploads/2017/06/condition_contextdefinition.png" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    
    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2017/06/condition_contextdefinition.png" alt="Context Definition ID should be Content" loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2017/06/condition_contextdefinition.png 412w"
     data-src="/wp-content/uploads/2017/06/condition_contextdefinition.png"
     src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACKCAYAAABipUKtAABDq0lEQVR4nOz9h34cN7I&#43;DBfQeRJJSd50znf/N/b99&#43;x6LYZJHQG8v3oKQIeZISlZlu214dWSnOkIFCo&#43;VZUmD58OipQmopSIEiLSpEjRn&#43;O7jDjVav777LvbJ3/ZcOQcOUuOjCMaiJzVX/HMf47/ovEnAfzBx58E8AcffxLAH3yk7z4yKBzuF3uWnz/eesal0uTeed70/Pcc855rvXdMn9l9heL3xrgkgMUN2D5QCdsJirwOSc5AnXx7sGbrr4fjv2RSlNybz3nzXBWe0R9v5DmXx&#43;hUkUrlgVzPxzgi7c&#43;zRJZ142v3wbPIcXh/62Sals/H90gUPndGjvtaQuD74Xk9j47vozwdusk6/AxiS18jKTxEqSjbJZRWGjccDoaGkyVr/EFOHiIsNH7x1MGLonN5Cds7st3kWH/ckpDCdzpTpAs5xrYO518s6oRAk7WmpNJkW4vnYyMnPB&#43;OyzRlO413YSOoezI01JaSks9TuAefx&#43;8oD&#43;Hi4vI88DFJocg0/B4EQuJ3I&#43;vItA7n8XOka41nN2dLQ&#43;1AWFHQhuuF9/efLReQ34nvl9&#43;nuB4P28ic85xgPhtH/cGQqR25YXr2OzenHzdFgFLygsWHlKr/ySjbaDJHS42avEhCZAdZXKajJCw2U//gSJea8vuEkoyoezHU7y12BogiJTw4zr2yoOlWzuUJ7J4GnM&#43;LNCUCEGihKN1oKj6llN0l1D8P1P5kZCF5J/ayU5J1Qqv/zaj6SwoiDvfNHhIQBZ8nO0qID5PeCeHx3/ws6UpT92xo0Bbn8Ny4zlL72VB/sniv/ENCaaGo/ezfTQvh8PxgAxgmRs&#43;NcA&#43;S9zJ&#43;HjxxMDGX/0ip&#43;ntGygnB8rzyOzLtDEdD7b8VNT8aco2mRKdgE30/kLWW3Dup4LYOwFRYysTyizIFDmeLhU93Mmk8&#43;aa2NBwsdkR256m/kc&#43;YAMq/Z5QWRMmPAyk14AV50pmj8HFCFDLJ/GaBjWf3CV6ed1idy2T2g38xJ4TC988/plT9NaXirymu2WSee&#43;QaRIadeLRCAP/IqHhIqGbiTBUlK035Q0rZVmMhbU8gJnAJcjS8GGqfDFGiKH9IKCnkmXlyyr9mICjXWFKqkw3BBHCXYCP0fM9KU7pNcK5OCByGz8fnfmcPe0vtfwbqT0RkRo4AYuTNkilSnmvwemQbBaLha/DauFaTTgtalWuyw0CHw4Gapv1KAlDjL&#43;AApaZ0k5AiR93jQM2PAyi6/FtK1d9STKIsosGE5x&#43;TyP6a/wzYrbxr0lJRWlnsaiYeXgieACao5l89Xog/54mz/nqYpI0mZR11hRbZqkY9jHc/X6P8S4p/vDN0oakwTnbhWstOOVhq/j2IWCk0Tra82IOw7HCf4agpc0Tl3zIqPqZgceAKjsj4CWcC4/e0g/WLockmni0nslgsitJc4XunFFV/y2ReUiLLm&#43;XkcC1m8fwOw96AM5hmiGKVF49FDT87Ey9zABDUWpHpHPUvwkmZs2TrhDKqaLfZkek6apqa2rZ91&#43;LPCUAt6MArYVGxYhnMO2clRMETgZ3LO3&#43;bgP0lmcLi8ETzZPR4AUM0KCw2Ew8fC6LyCiIWNifsEt6J3Y89dZ9FHvM/ZeR3lrOyQ7yDVCsvv&#43;U5DB8LXUAIiSec5aPsKJHTPJmuZZFi5TuIMBd1FT1oED2fhB230lhc1hXAztckogvPZGg4JpEz8vcqFZkPQigVqUyBsKFAM&#43;djrplaTK7rmM3JPfhYwjETpdGJEimKpNcl/E88i&#43;c4oiQ6cEoHDfXda3&#43;FA0yHX3SmTrUVtsg7gdkhT&#43;5E15PDeRF4ogaKEwvxwA8JxSCwNsJi8S7sA4XnOloMPFl4j9qROTvSWuT&#43;UlVV058uaOeEiYBewkrSs4HM7p5FgUoqQzYj3JMnMWE5rEShw44dLBREcxrlsfJiCfpGJscpbWWH1qxsutE807KQvDDM&#43;Xi&#43;mPVDrDt/Qc&#43;BQNyFX/yl5cUfZcpzCg0OkFQ2Kp68iXh&#43;eUPy&#43;mBuRbP8YjPxJgEw5fFL8gRma2HdBYups3xuVw5sz/QEbZQHcwOwsUTJrq0ttO&#43;0lEmmswPLg1xT8gJYtMFR/2SEMBrR8jBJR0vpRiZdrAkVTSs&#43;j5UnfhbmHHxN7MajUAv&#43;HkRDdl6ZY5bqmBW3VkSc51TkNX0e/AyGrRNvxbBpiOPA5kWh09m4iOA2hYJ&#43;kHhRgEXk6/Lz1Y7URrgWc8OeldledBOVO3KdFu7m5kogOFIp11NOuAl2/0DROmLC7o/MSGSTaSa&#43;L6SAVzkAy3dWUJh6WU663itte4MXSLwSyBo6PxBPEN5DC/s1YI2D7BIrEwB22TlQfjS9HGFiwgTw7uVJsaYXOdvahakjO53P5efjC/Cz8HX5&#43;fBirD8krI8Y4USwIAbSmiCHeWGZw0G75ntFJVeUL/IWCRMYvw9zExAcEykfPziqqRdl9ix/UyMWAYjIK5/90WDH8rVAAGyiWuGuvCl6LyrxflP2zwT7YqnW8gVbYLy5wDF54/G8syg7MKHWtNcvZM1AXd9fNwNviAaVPPxwUBICjuFgFYxULTKa5WIyscmh8WbiqLBgQ3buCyDvCDGjfIXJ4xdRF8JOnV8EZyemZXC2TM4F22zthS8A3xdio/NzBl9DuAcIchAu4bysBxce5B2wy3LZZZC3w&#43;RZgqvCeosjm1yv83Z/KnMQxA4UwcCpjJuYx9qbgWJpyAS5aPWAS0GU&#43;AnUFMUN7hvmzs3fAWbloEjrhLI0BfH2fX/dDHThrvNw8OsEoMadMHPphdlRoyNIXmhyPzfGs9XUsTK9nqOZIjElosgR3/AkxmsF82B64uSza7siiM04P9cOciNbnj7okuDnF6WbLzG9hZqaNUtsgL&#43;nUhPfspto6F5MQXwFjdpP0sVruPGBwIsnBJBevKhcQh7Gfya7buGwiXJTDnDeXTlTDpmytNi72NX&#43;C2Gx13nSBeG&#43;odVee7bFW98&#43;d6rEvna8u36968/2/mfBPLs5CGR6bTEKXrlepCt3e6JuvpZ8kV58do0IFoMpLs0yKooCylzXtjSYAb9r4YjMXEgnKeVFAU9o23ZgT9ccFEprEIry1CMszL7LpakmuwTy&#43;wv8oOFcF92&#43;3zfSdVVh&#43;wWxWBdv596IBkYiWAxesGq1ooeHe2zBw8sTWVvTaq2oyIi6ztHxxGfntNndUZok9PLyTOYwkGG57x8FOqvWIJJVVVGapfBmtU1DbdeNHIOJguWfXzD&#43;L3zHhJhnGZ626zoaBiPP7Y&#43;zTEjWjSbdhEWnaUYZn&#43;sszu0HcaPO3pW160STjkRmyVoX50FNPoNlETje1c&#43;EQJdEG9g4jlPz47QKHNRiDr41kaZvxRiXLIgnlc2Noihpu92RHVoy/YFWVUZ//2tC27Wi&#43;mzp///PgZ4OivIspbKs4KE6nc7kjJleDAu43d3Rwz0TipbjtHCYJE1xL&#43;Yc/I&#43;VnTzPMVFmGGgwhspqRXe7HS817fd73IPlkBynqO96arxnjJ85TROyxpCxllbrDe22W2hYz8/P9LI/zAiPF7jIC1qtVpTnGT4bhp7apoWXD/dQirquxX2Y4zFXZC7Y8me9fFYWJT7j4/iZmfD4XJ71QHj8WcnnagVu2oXrZXJfPrepGxz7LYng/XgAP8SfobArkiSBtlsURB8/pp4ANHWNpb51dKp5Fwx&#43;911iT/izPC9os9lQVRZ0Pp&#43;oPtdkSYEotrsNtFt&#43;ef48STMsBi8iix1e7GK1oh8&#43;/UDKGRAQL1qa5bTZbjF5TVvT/mUPbZHvkyUJNfWZmq6n7d09/fDpE3y9zhmqm8abUbIpEp3QerOlv/7tb7TdrLCITKD7/QHXW6/XlGhF59OJDscjJWlO2&#43;2GlGNifKFz3QqB3u3w2eGwp7ppqVptaLfb4nn53HPdUFFUtNmsKcsSEMW5rinNClpXFYj7eDjQTz/9RIfjCVzuW41LAngTdBDYN0UXHBPpZq1ps9JUFhoyvyoUpdqC4p29TrFBl&#43;DdYK2h0/GIiSzKilbrNa0qXuyUVqs1rVetEEyWwr1WlKW3KBJhqRATlnSSULla0W63wwLxjuWd75yissiobWrsfuufS3QAz2IX7J85TlWt6P7hnna82Immru9w/TTNqSpL6D28iBnv6CSj7XZNpu9AtMYp2ux2dHd/T3ZgHaiFfrRar2h3f0&#43;rqqSuOdN&#43;fwRxZ1lORZHTVhNtuh6cs/RzU5YFiK&#43;uGzLm/dG&#43;t8YXc4Crg23dhGWqaAws5&#43;1Mc77lhZj87s01/ohZf5ImZIaejDFUrdZUliUWre87TKzOMpzSdx01dU3OdGCRPC&#43;84Hw8s2MmrsHLdmcG2a2HA/W9oSQrwEWUabH7hwl7jbiEJIEc5vPB9bKCVmuCaGCC6Ls2vovyRJPkOdh52w1eZGoQCN6BCbGscD7/nSUK92XJKCIjoc2mAhfja4iYMJHzfs3aTI2G5Ur8fAJQLI&#43;JmtZR6x0kde3o3DgajIKfX914cES9WJYPA5V5SevNBtfjl9fetsUOdZaMNTT0HXbw4CRyx6yQZWXb9ZRqh8nLE5bbIl9hdbDRawwWkLmEWBwJWddD3rOszvhcLeIjPps8IM7j6zTkKDMZuI/IYQLwoT6f6Xg80PFwpJQXtapoXRXYsYfTWfSDvqe8KqHoMgFkWYr3YVbvrIGyyKTPz8/ijd&#43;ZOVfTyPyw&#43;EOYt248l/oWu1/I4esIIJpqBLdV2yr6z2dDZUZU5UTHo6HHZ0O9yahKM7&#43;IV&#43;xo6zBBx&#43;OR8jShvCjxORMEy3itS&#43;wynmQsfN&#43;DCAwpSlm5q88AQDDHqIocC8gE2DQNXL6iLBpMHt&#43;fOQJ2VlmK8sV6xPFEFT&#43;4Gk3RoJmzSOH77l&#43;eYcmwOOLjur6F/pPg&#43;j0WqG1b4rXhZ2WlsmlaPC/b8vw9fwnrhhVSlYjXrm1w/ulUg3g26zV0ISYslvnMSVXgck3twR5fhviZrPVVHvBVBMDmCC/c6XSCV6euDZ3OHZ2OCkTA3GB/cGQpR3yeX5pZt1tguhwQLB0dXp7JDj12RmDzpE5YMCYAaN48wX4nh93Cu4PlOX&#43;X53Iuy8fz&#43;SxathJiYoIQ0VBg0Zi4mACMa8l&#43;NrjvwATRTzVsh&#43;sdj3vcXyuxfngSefeCrWcZsBI9OElHOmmhI8g9GmraDsTJ3/NnLC76wVCWH2C6MrEZM4ArsEXF1gITTVOf6PGnz1AY&#43;Tx&#43;prYV4rHXcHE/Y6ivSQ0T7T2nChqqA3UOpqcEu45ApcbwImXYbfyifAxPur1QCGVikyTFYsN&#43;NuJSDDvSQkEznvJHLXWU1xO7Gr5shR2KReRnAUZN4fphh/PEOzdxBkWu5i6eLdj7YTh/z8R/zucxIap4X8LzBj/A&#43;JlcX3vHV3DnsiV09/CBPjzcU5ZoOh5e6KfPj1TXrX8KwvWDKJs83vvHtViAQyzg63IDIUuVoG6C5&#43;7iGKX9BAtRLLXs&#43;bGv3/JLPXzXzp1&#43;/i206OX15vcNrFpNdDcXiS5eg8QS4s1UVSUmnpVaUUrN1feYnPz&#43;cYMAvloJXMZHbh6n3g&#43;U/1qX7nLcOvdbe9GW17t&#43;/UuZvTyO2f6JFcr6HDmKdV8PKf&#43;S8VUEoIP7drXCA7Pi0w9tFAFmcDRYBbu2WokD5RwVpQUX8KyUdwErWuRDmgOzaPtqiMafrr1sdl5B&#43;gJOoYOL98vP/ZYD4scE0Td5vm8eGLh8v68mgNV6Qz/88AMpO9Djo4W2vd0Q5ami/cHQ/kiUFjnd399DyVKfP8dY9fJaZbWi7W4HDZi1YtaAWZGDw2PKEeAbn3IUBUWMlTvmbExgnVfkRj/9Df&#43;7UpTD8VJAkWWtvbvyfN9rLCOw32t8FQGIEphBZpmuoTRRtKoS&#43;v/9I6F1oej//bOjphUNnSebFyn15uD8OsIltrs7&#43;vTpQ3TTmr4XBQxKm1gBIRbAxyfReSL&#43;/IeHBxDi8/MT7Y8neP2YQ6VJOHeA1ZDhGQJoguCle7i/hyv48fGRnp73s1jAf9/4RmZgLGbgnF&#43;IwWu8rNEqKnIlAZG&#43;h8lVsm177TJKU5YXcPtmaeK9dEfYv5vtDr7xNE1gFjZ1A6titSqhVcNffj7Dr/7p0yfSzoPqdUJ5UdF2t8U12fau68Z71nJwihpKVkubu3twMTe08C8cz&#43;dJLOAPMNTP9AQCXmIt9YODffv0rChLyJt67oZpNbm/UnCuZGlKph/A&#43;pkAirKiar0Ch2HzkAlksxauwATBRgsfQ16Oy30MFCcWJx8&#43;/UB3uy0CMCwWmL0naUaJkmgec4PBQ67xfNYgZnFpov73j68ggEsBxRM5GHEFM2sVu164wFuWgpvApEJMnEUG/3PW0uAGqvIVZVrDDuadOpCiJMshNcVL1oCNM7dRqfexY/f3cNsG3cEM4gDi83jh&#43;TxWTsm0IBTzjUOtXzpu4S9&#43;yZF&#43;qWN5&#43;ngBsACrING0XmvabhJk82xXlgYjIWN9JRRMfvFZhDCLX1dburu7ExyAThGK5d&#43;DM4htYj6uaxsEgzKnY9yc2XaRJmDzFq7TntpEUdM23n/uyOUO&#43;gqLJRYTEF12AEEUqRAdP6tSX0AEX&#43;OS/Y2NV7ODl0NNEJQBnRICGLzrM59UmaSKikJT0WcRmHHNgQ1XMFzKR4RGy6rCgvPO5N3MooE5CSuGp&#43;NRYgFDD7xA2g34nBefF15tVniWtm7o5fmJzLAG92H9pG07uFKHroGoYgLge7CucTydSK1L74lMfotr9IuONIBMaQLkpPjrNcyauE0FkHECEMPA3&#43;/o//7V0/7F0DA4Oh4dona8&#43;8ZYgLsIDPGCHvZ7KGcVQr7iuyfSCBKxJg9AiI&#43;EwUxDBlEq4WLWQbqeTocCegDvaNYjDvsKhMlEA/YODIAoq/wOsAS87nA65HgOKIBfMnvfmFoCSlgtL/4t7hOwp06RU84DThWp9MMPe&#43;8CTiWnx4OSVQAgX8EEsvk2jQXUNfVD5yNwgUNILKAoS/iWa8QCrtnZ4m9nZZDZviNxiPBCCEtWEcJ1iXX3GTzRGSRKafC/Mzdx3k8/ehfF0A66B5&#43;noyK5AIW48OOX0QsuSsQtf9I3JzJ&#43;FYvUF96f5GwkAMnYx1rpQARKEV3km00UNqkasogFqPHllNcPiGgEZ16ZzvlLuwkzUpPnnt9//kBLd7Oaw/PpEsN9heFdXn4Jy74BD//yMYkFqPF5A75f&#43;S9eX/svRBS78P&#43;OGZ9B0pzEAuJWj6wnJiUsJpKmExep1cWHn&#43;YnODf&#43;DS3cKnLaf758bhUCR/4efre6yZvFIhsXLzkhE6euYtrUlcm5ntOhYsKK87kOyqfKKzWik28lmixvMJ0/tzxnMd8R8Rw9lpdz/&#43;rTvyMvNERTnYfA83&#43;pmu1Y/9hqQpFXtr/yiNiyKnHVtq1Z9wYknJW2vnfUdcxPMtjrzAVaKHbdRTxb2HVKWZ4J4MJayOLBy&#43;jlpC3tCSYcCSN7f/q0mM7suS8pecZrgk8iCylWHTyN4qzKI1aBlcm&#43;H/y95xNLs&#43;CXiKEkTSEmxWFm5mLM73KZb5/ceUEIr423CX32ypEAxthHGh46PghYv7&#43;5WoY85Se/2Gq9oQ8fPyA9&#43;LD/DNl/tyOqCk195&#43;jzs6W2L5AXUOQ5YNc8AbQAtPLiV&#43;s14Nl5nsHOZ42/hl7hoVeTTLWI2rE2xtJZFwE8q6kBD6PJccERFSY5ToDXKwJtaJ3ACuHnUM7CMjk3DTmSHIjtZg1MIb&#43;HtXWcB5rE/mmitwjgVYJhTAD1&#43;QRrZBnTD8cGXQQhdj0ngHf7Biab&#43;WLxY2peiI3IvKSR4USW70lgJo&#43;m8W6Hh82LHNHAoT1j18P0yxU93CeIDbA9/Z9HB9g0H8uLyy&#43;4fPm8KGi3u6P7&#43;x08crWzAEyK7T949E&#43;KMl5YJI8SYm7SDQOt11v68OEBruCnpyfaH4&#43;kVALulGgtpqMxfhcLgoctGASc6kaIIASlyooePn6iMksAynh6fsExAb2cFpknTOujoRW05sa7mxVvjNVKMH9sbipNq80W81GWBZ1P50gIdoJRgC8l/NOBE4xYijeZ&#43;4W&#43;eO14NwbWWFFmEnCW0qhxBCEy3f0LqlqyTMSujQVq1baCy99tE1qVivJMAWuPRbRRms6f26NleQenWtP&#43;eKDj8YSX36y3wMM7ZsFVhYfm3bXdbjDpbDoeTzWtt0wAH0iTKKIqSSF2Nps1jmcCkCSQlaCTyOHcf/3zn5IJ1PYxkwh5B&#43;s13W3XtFpXWOQff/wPtR6Lp1PBBfKuvn/4QPd3Oyzu&#43;XSkl5c96TQH3h&#43;&#43;i3NN3WBpvd7Qel3SsNvS/vmJPlsj0DMkyMzFLYpQeE4whqpf0wWWhHCbVwRFGNwPF7ST1LCpHnCNhtzIQpY0JfAqgisYHNURta2lc21pGBSlM/PNjT&#43;mMOpEsnVYT2jqBgvIk5&#43;nrDgmVKw3sOF5QtarlYRv61AVq8OO0k7sfRYpPOmQ2c5RuVrDoVRV4h7WMCstFWXhIWKLJFEvHjSSQja0Ph5pOJzw0EIkCVVpgWAVE2&#43;iiXZ3dzieVIL71vUJiB7Skht5f39Ppm&#43;pPR3HuZgmYHsi0Gq0nIQgdBTNP5cAaBpWt1Kux1k1xgIWYCZRt5c1ayIRuJFgoDwpKoqEPj7I7j8fDZ1OlgaTxJUOWnCEZ7mRHUEspGlUwtJUlKcsT4hYQUwz6s0AtsqKGYuToihJqT2I5nw&#43;k3aCxEVNOi3iYxh4ITNMLHOHrjVYdGPHxNNpYijg50AkNzEXcUokkoePGm8xxYx1zjxLJbmFxGfBRMz/0qKSAKUSB4laxEa85jUVvROdQL9TEQxrf/24KQYi6ETT&#43;1wEg0LKslOLHT/RmoM/RRaf5XJC63VKHz8kVBVEx4Ovj5hoLGpMcFxAvfhhOh/MKfMtbTZb7OAApkx5h6WC7g35gVmWC07A7w5g9tuWylyIZrAOnsGyEKuCOUfdDNETyaKGlUVJBJ2YREExRHJpjhdk8dF1gifIfVAJiSZW8Pop3NyEa2PHq0RyIauKjBWOWNdnenpOIKKEQ&#43;SUJM0YeVRT9X0u86MS&#43;A4ieIsApn&#43;rSc5FOllfYXPXFn9&#43;UETVipIWQrKsDFnUDGo6580gyfDBzoIJNIoDHMEE0DaQyaw/lGUOgmKFCrtaK8pyScxgy8CAMDQNQyfxgfNZsm90QmZdgTuwGHhxRGazBsSMF4cJApq1V/ZaWBqnqJ/APebh5fvDHvKR9Y/z8Qi3ctu0UCxZlIQsZOcU2fUK&#43;sj5LDgGjdSwDaWpxr3PXUMvT490Ph6gDIeU99GvMNIAqStOoTcW/9p3rxGCm2VYy0jnq6vmRQviNwsvmrVw/748P8tEnXv8O50IMrHrHZ3ZUlLCDvtWEhuC2TW93jD0wN6boYe14Lw/ny3&#43;AyZOwsD4TCnEH4C7R3ygRhyCd/P5lEU8odZHOh72krqFANIwm1jhPG3MAwgEwET1&#43;T//oeP&#43;BTMBLEFd02DEnRzyA5j4Fd9jn&#43;N6bdvg&#43;ZhI&#43;D1DDIK5hwv6TghJm&#43;APoKvu/pmI&#43;AYcYHHUhQ9U5Z/&#43;elAKlWcSVMsRp9urVxudJj75ouuAvVfeK&#43;ikbB1pnXrTi8S5cyPePpV5tMT7e6Kc5fj7vH/rCSrYzeO5KlbMuig0oShm/ZCbk3YwyULFsAgYoUWuvo/bq2nNAOdivQOxlt0lwMTf240y1CecJCBWOI4Qw0hiDsPXLP61c7wTiIc1xv/PWpN&#43;TawhxPGDTe9uoH6sffsYiiLFXBDAu5/nCpLna7CdeA5nRIG59d1r5/OimlduPHUCTu2tiQ5wzez7uYog0bx0j5q4jb8SFKo8yFJOZ4XIOhMvbGPFL7Gblc/3c0tX6OR60&#43;BSsA7eRwZzf/tvfQRup31aOlF0v3gklZ455ZbnxnD6Fe71nnsv5&#43;irUcFlKRVCoAOcDuRcS2XhdYDOUQ2lOIfLmGX28XhAkqRZPEAQJ2zWZbnAwIJMtfayTpCaOuD9ZIY0MNbg7QQGHo5zF5P0ejBHXcsg8orTdALVxMR937yNWUBsyppeqo2wcovM5qJAUYuQakY0DxKlaYbznR2g2JobbO4VEUBjRVE55gsIYHQLsxlWVWt6&#43;PCByPakXEdaG/r4oGhdKaprSz/&#43;ZKnpU1TlKPhlzUBt0/lU6HFSJRawATy7LAvEAg4vL3SAQjfMuYCXmWMsQMGhs6rEOXSGVTDGAmiRFxBD0z7XcJ4MEnIUk4vaP0RjtDLU6gmxhelnl5PuLlzfvIjb3R1Aq31zps&#43;fH5FEyp&#43;v12tkOTeokdRPdCO/6VZrWm/WNHQtnY4Hatt5TcD3iIC5d9cTgBrX&#43;HLBaamtijKUeufH0A4&#43;PkBUFIo&#43;PCRE96IF//goiFudVFjoUDQ5rKr2wBLmJLu7HTx7bA0wlSPO0Av8S2IBPgaRF77ejhSEWm/EFazcQE&#43;PT8jJ591UhFpCPvjC14TI8rV6Toejr7YhxRdCLGCz3aBKhwr1gJDOrWM9oL7roNAmqRSnQnZw33nCUxPljnAu/P5BDwooaSJYPKlyuEY/WABnUCqnyHxiS0pFVcKvoHwYOisqBNfs0OJZ0uQMH8gQgmZvDU8FauKBvMoBXmtmSBOvFapwo0iDwUvUrcjxKldUorKoEQxf8D4FZ3O4pM8LYJbIe/NwOKAGDh&#43;7Xm9IK4doXMY7HISkkUMf/PnH4xki5u7&#43;nrQdcC&#43;VZqgoUpWFuH0966tWVSwcweLoX//3fzg&#43;mKaozLHb0d//8XfasH2vFRbvdJLyLcxl2MqpzycgiZOsQJ6BBJcaOp0bcCTmGiKWFD0/PtHQTxRhxE4MiMgYK9xMSxWy3OdHVHlKXTdQVmh6&#43;PBARZ76/IuerErAJbRegTBenjQ42UWY&#43;Qo3cH7h3eLzdLno8wWaLxjRCHLw&#43;voYW0axB7bJCTUCJKI1lmufujvjtTzLRSzAGrA&#43;/leUFXajxAJSKtcbMkOHc3iSeHcZVNCQmgG8A5TtwRHY7FxvNpRqKVVT5SW8giE6yM/FZCWxgISU8iLDF6wCGy5L6CV5aSkvC0QnUUOg7z3UPSGdZqE4uOzSJAOxMsdL0oTSRHImg0npV2GeKxFEcTBLUTVNTGfi965KviIOYP3IOAVOwe&#43;TKaL6dLwMsL3hCJp8MCeAayeoGSpovnOjO1FLLECoXxTAoVDYQfw5a7US3VLx31izRkUZnWgpscZyH6HbPAP188Ty360Z3bKrqsQuzw5HgYa3LWky0DNI58AWEpnIebQHjPAuQsEFSxNFaGTbyqe6970QhcNOTnG&#43;VAKR3c/PkJKmAcWnVQx1k0ooyVNv&#43;Rivc6jZ5IcAGt4Z8Y6ckrYP9CFVztKUnEqgW3S9iKCQXRV1Gq/8Kh346q3atYt1pbm3KZ1/OYJAYlBCzTCiI5VFzTRBICjPErrbKMpShZpBQF&#43;rFMpNAElo70xxNCqC8Ji1Ha1XJd3d3fuKYQ4Tn5dSLInv1cCdPAhLLVx0HCF40w9U5Ql2cD&#43;Ij4LZc5JkvoBFI4vqQ8pNKAg18R8E3wZ/Z/uBhqxHJLLvW&#43;raDNZND&#43;9eB&#43;UrNaH6uBS1YLadpAV2aJ6n1LdGsn1nUVQhfpTA6QYq8gribzBWdALA4AUdxacirxEeUOFczAEsHalBFZoenzO30El3VQl9z7jgAFNWPY1IqZHpy05Bls4QK14AFOLhYMeDpacXR73VlGuhZGdt5BggVu9ulho5RyqKDHKbXwjRtKaRiJt3755PJ5hLvACnk0PtHqSc9wPpw4HcWgIwrHi5lxeyiAVoHC9uWu1jAQrJIafTWRBKLkAlLWL4LLdTv7tYXvIOTBMJJ0P5bFuqzw0R1VKWThMWru8N6vwwexnyBNyibiZBnzB/iH&#43;00GG0T0tPvF&#43;gR76jAodhcTb0LT5j7or3graaQMxIFCt4IL9&#43;XO0bGDT9qKRMWKVzws7apkH5V6mU1dP5zDKcAJBoO0fnmi9kKckaH7NvRRcI9rQaJ54n69FZaN8OOP8OQJDT&#43;TSPBZAUXOJF5L9DzTxWRJvzCXoEAj9KYgGhyigT6hR/Fyp0oays3zlM0OfzEYGmwK0cSt4JK2fOhHpF0cfvohyHsglbPoV5lmi/mHXtucCoRgFv2HWYu7atKVHi1k7bDp9L6dpgulKsGQBO46/kJj6CCG27MtQtDLMbi0urIsQC/D&#43;tNA8V6tiMXMBvFhtkkChwzstM50IsQIgF7dcSUWi0UjNQ5BLiHb1jesTsgQz16HxxMQfAI5EmypSa1A82vpaQin53G6833tbF95hN2DRUOlkwihhDikrv9aFifsKribFBHCbj/KYeD5H6fIZpbOSqY2dBVJe3uHRmIRBgnbXWmMH4WMCVd4g/VfzndQPcVbxooaIFgjIxs9ZNziGEVXvqvePmivdtYmAgb8C4eT0dM77sPEnDzZC4CNqQT/6wUjHUOXcTyXRrLPEK0/HewhHvOoyJg5zvcOpEyTRG5sIRJcmYtHLNfRsv43&#43;&#43;FQyac4JxA0ZU8MW4lp40PVmRN99Sj7Rh&#43;SQh1yQZ49pi30rIlLmEWToswnGwhZNYriXsnuBti9E2DwGnGIxyS&#43;q4fNXfanggPLJaPuAUPvfl0v2qGXiJe4t/XyeAYL7HnWYhtN2EPeeoFr4F4mb//AzFJM0I9YJ5jepGkVPeJk8S5PmdIXNDRE1FIimqCvZ3nqbQ9ENJuSBChl5q&#43;KWo3F36wssnX//PTdDLX1FE8Xc&#43;3hspXA4fHb5eLNopN7JTPWX93n5NEtjs292WhrYB4iXNFD3cK/qfv2aUkKP/929Lx4bg6iyrEu5XFNGcAEQVaSzyZntHf/nLJyoyKRHz8qzopDSIjM9tTkc6uTPueX//gLKwQTFUWkqvMhdBgmfbkRuG3&#43;zGX46fo8F/i3EbEwilyxJZcfLQFECpBSDJ5pGBvHdUVZo&#43;fUzof/&#43;eku3ZDLS0Pw/SSYQCK3ej7e0FHuoN&#43;YYRmizV3u&#43;dpCmg3FVZ0tDWUoRikNLzLFYyVphQIErKweRZCs7x8vwMd7Idlm3Gfi/j&#43;5LEdQ5AvkOlX1yaEgCYgZ15tNKUaL3R9MPHlDYrRc1JQQwgM3cwURueKVmwaUfNXvuegKgCMkiAJs1yuGwlXct6R0yPxA0mnKIo6eHjB/r06SMIgM1JFkUIsb43QPKbGurG79/&#43;PteDQW6ilDia4ANHNyYPbcem&#43;cwfykLRw11Cd1sNT&#43;CQMusnShMXlbolLFwu6HzI1YqZOHQIjUodX/G8kV57T6KUSw3RNCiYhfjuS9&#43;lg5XS1HcZecUK/h2ML&#43;8A&#43;v5LT5N/pxwgpAIs7MqL9GhFk&#43;xYFVOZJA5gqcsl5i5xABVNmfECFB0o5EXC4D19p&#43;OBnp6eUdolRQ0gCdJIWldOdhD3qlLi9nVK2DwqiBvBA4z1iH&#43;viy/jPev/pQqg8o01pinoCxEwNi&#43;8BQ2HfhBdwgJo7DpF//5xoKZW9PFOU6aJDmgaxVp8MZZemXIAT0whI2j/4nw4&#43;AhiyosqVspGXCDPqO0N4t9t18s1&#43;wGo3TQRL1Xf9TH8&#43;vtj/7/smPoTpgGhV1vHXv9Y8HpD58ESxorr92xov3f0/KwQxj2eiQxp3GjwTSGWDg0Bg/Z0Oh1o6OoYtNEqwU/UzB96oI5b7yo9vOwlT9CDQk6nM5Q/qQrmO3&#43;Yb9dT579uTFLS1Ff3C7AWyRA//UcyCeqad6VEvroulIxXiFKpF/HJM3u&#43;8KZ5QAkSKbWK6B3mPvwZK3KJj7ZJgGQgaqUfj/b4fgLA4wgHEXOTzqdg/x4Aor/GWAqNryIABIMARepxwbhwbu4KVYMEXHCMNVdLykvWkCSY0qR6Rd93uH7U5SYxBCRmTFiaRPvUpaXx53hzvE0AV/SM4EUKka4RlDg/yk186O6VsirXFuythZwpqu9YcBXdzG8e&#43;jPG78/yeJ0AFN2sEhZax/IL922LXam1D2Fa3vGC&#43;M1956vQSPEiiSNmxwhqKGbjvLN17FtjxDaEDiL21ZyDEbZ2xWy9fZdZZ5GLamO/4XGbAK6VLPNDJ4kUSbi/h1PoeHgiooY2KxIsXGNRLp50jtz5NNH08vxCR2PIeCcSBYRxIj0A174hJCt8p/NpzKtbBHWm2UOzFLIrWUXhc7RsK0pfUl4g19dCtRpwrAy4PPKOJ2Ps9fvOStcTgKPopUwu5h2&#43;Vif5tzJuYwKn8LCFYwIBnLJEjX&#43;0jjUH2q5T&#43;t&#43;/aYAxf/xJSrk3g9Tzr8oSKJ/zWRJEAxoIfvy8oLv7B/r48QNlqUZcQSDg7QSPNyABNODqAY8aBg8SkQVOE8lCDlFCgVdJaLIoSpSh1STdOw/HE8Ak8z6BwtW22x2g4c6IFVI3bYReBag4Pwva2MbGTwa1izfbHSXaUX2S66NVLBPCb5gIboaDKcDDJmVMKHhwVUhk1PD7a&#43;VovdKoD6Sdo&#43;NRU5pYcq3BQpFPJVN6jgoOvYDXmy1KujgzUKM1dlJRrdAxNMskxZuJh7lqCax8JhVB93s8z/buDpHErm3hJwiZSwCimAFdPu/u7ylPBVzJBPP4&#43;DTCwjwBZL6P8adPH0HYArTUsaVbClOzptO5hqMqVCvhZ3MqQbmaqszw&#43;WH/Aq4nhbF&#43;ZwQwq1ih55hANWW5vkjkwLsdZWEUrUsNYtisFJpHSrcvNwGZau9unmfXOieuXLDqnUIWzHa7xc4ehg67sesHKsoVMP5A&#43;CYKxRpQI8hZeuF7kQJ0vCxyRBaH8&#43;BxBAny9pHSBjO29unl43sH4BATKxl5Z2TsbKQpxWpVUtfU9Pj0gnpA280K7mtYLZ44Hx7uyLQN2V4I9Lc&#43;3kAEjYtGk6QePUvHJpSFe3wyYH9/&#43;ZRSVWrabRJ6OVIoOzpLvY4iwJt0cAOXJdKldnf3tB56ynzrV&#43;cVQnQAQbvVCr17mbOcjkIUzIkauJKPKBEjVcYplo8pSTCEbhDzkrT22UZz2NSA1vWt4Ax6aSEjlb/WIILVqoCYOp5qOLnQ9zjV1Fct1e2A8jFVWZHRhNwA&#43;h14pC9h4bSEheuIPQ&#43;wsCVsHIEaw8qf9AyoChVRwjNkcQBbRqKQDnUC5mxpGFZUrEpfb9hRhxy5Mb0KFoXy2cgT8xIAzNMJ/5Kigu8hTzPfgzjFPeQclt&#43;9YO6veCXxHL3kHiQUUE&#43;&#43;3rHWsXGl8cd1XUnrKgdiuDcN7sHEo9BQO5N8gVrHANZvYUw98TQjgIncD5p/YP86lnH1laY9xAiJW4B9JZRlmrZrRaxA17Wj09mRdSkWIpSLn5U&#43;8cUUeIHyXODgRD4zuG0AKkUDaQ/8EJ&#43;DECIrmD0ygxpYC3xtUbp6UlaqiOTpDhlG1kkHE5bd6ODNOolOPJB1QQS&#43;cghzjrJIYQ3wbdEZtG1o6BWuA2&#43;jFQdUimzoXhS&#43;/Qug3OhVZOwYmVxCsn7V4Wags7kIUKP5pyYVLGPuPo14fmlxWgN4MRjZQafaoVR82zp6fiHqjaLcOkxYrPo5yTImP&#43;noCdTUUv59COXiFdKyQrFH6aydxv4DPPmsF/B10UMIvf8HxCaeHx/Rwj3LUtnRXU8nX9fI&#43;PwEZvVLW50JhZ/j6ekRWbqsZwwgNkPno3AmlMk/1wJwsYZOWklfIrYWfD6BdBR1SF37rZiBcyyGi/9eTQyZZgCNpqBcCAv22QgAAzt2QI0glIwZCDUCle7I0h4TIj0DzRgG9ABOnuTz8YhGytqbVKGmT5Imsbqo8YUVAQr1BSembeiYQ4jGbaALMBcBbN1XH3EeexDm4JqNDjOSCcvsqU60dxw5VPg8pB6TYKS/EBPA&#43;XzCecZ3MKOJv0D5WMW37PX/LUaA14efrzqCaATuzl3CXu6GIg6CvrHU0NQbygTQ&#43;4LLy1o9EzyAYQ3aYpfTjFJZuxxtz6kzKOD6A/w7QsD9DaQQ03DVOTSdiGtDCKOnOaKsR8g73t2/X9&#43;9fq23vvs1RnDju1dh4eHICPwZ48iRe8QDQyIIeYSQiqdPpsyfN6nkHa6hBHUUUCoj2CQs7Nx/H5HJk5Lnbv5A00SIr5ukNwhGTcq7Lu8VM59uXGeWHT2Vhb/gmD1jmE//aFcJICRvBrYZoMHjedLwkW1q50PDPXrqOyiBFnAu6RhSVSvIbLa5O4gBN3KAiTs4IHudZ5sqsGTWvN2CjU4Wf8yO8Jf1YutrW8KGsu03I4s&#43;rpDlOXCIALTAgjExWRaFKQYRFUvCQY8lL5rgI3n3k33LMc7dVVSw5Ow5slqQoUrNU49DafUPHz/CZapIWO7djlAqtmksPb2wTp/T3d0Oi/v4GAos2ngPFUrErFYosBj6&#43;LO&#43;IKleBtp903ajjJ2WcPMcRat5GhXs8zyP7WRF458XWbq&#43;OzUyc/nckMTZT0xO8nTGlst6s6Hddg1lU6qK10hLX61WyJTmv13dRtBreDYpiDH2RoJr/PvwgaufXoBCwy8CCddABoNNz9LDxXwrioJMZ1EaZrVK6H/&#43;qqlICU6h&#43;mzo1IofXFLE5VZx58bFyuHK/fBwD6dRcz4Dbg7/vgeSwHePUqwK9&#43;Qdhn6BbYup489CFU9&#43;0mq1RtVuMj3q&#43;7/sD&#43;AEcCb58rFsGTgacweVL1q92e5ot9uRGzq0ouVzQzLoOAEEImMi4A3A3K3tepiz290W&#43;Q2iADpBNudZ9F8keRHPS1F0YvBVVH5pXjANVY&#43;W2AUodPxFiEC5ywohOhRZxEv2lGUWdYL/8lGjc/jhYBAaNr54A7J&#43;Jyx1bJCofJJJKfWGusYXhlLoALpZV7TZbWl1PNH&#43;cADhreGTH3MAHGm6f3iA67f3Gb/VZksPD/dEqCrifBWulDbbLWWJ9pVIWi9yRIPXqB&#43;kaXcngSnbN3g35kChomicKmMj7FwCVsL2mWglw0lL4Is03d090Ha7pkT55lrGws2dJOKybuszHfYHMRl/ITagJmVio0v3OiZQFl8AoWomK6Jyp0a5GpQKlvvrlaJVxTa7pe02oe3awi/AbHxWiIHmnSustwDMYHxwKKNhsLHrF7PM3b1UCeHboRO5l8GhUtj9/T0ifXuWxaEUqx0rkWNhNjv47tncZGslD9083IBK5KyvtJO072B6Ln0F&#43;M4Xq0AUMJ0Hy3UiYiTLMrJKiA69CzRJ04i6paJao4eAHXp6/MmhYNX30gVU8PMEDnz1qGW3rMhcpzFxGmHekMlSHoZN8bJQtNtoet4vypYsfOMB&#43;nU6nVDAiSdqt7vDZ6HNiiWNSiHw6lmDHsOWCSQVp5DxKu35fIQDp2nFMVUWBeoGtY0UVpAqX4RK4WdE8wovZlJKmWBUAl2D2Tk/j&#43;tbnLtU5PyDx02AekE&#43;sTWUlUu0VFEzHjnN72N95fQ0Ew8hiyPny8N&#43;12SgSV4AvYkIWr73wrgLJuDQEx1Pls4rKRQZYP9ahzr5r79h2FUAZKAQovF&#43;hlaQxYk0XlK&#43;U6n2uevGF1RkMXM&#43;HuEAanuLCl5t21GZy/V618N/T0o4SZ53MYediSsnaX7tfMMqlvmZVljERF9pKuH9BUF0sOKHsjG4do6cRv6M6l4KXzaNVE3PU3CNtm1IHZwks3hCbtruF9UDoiI6yQu4zQFeHe5iB3SdKH5l7mhTaWpqSy9HR71Nqcput46loFD6srNSLeSMFiw9CkJ1ZJVGCTq&#43;L5pVrSqYUSgRczpJJe/BUH06wxVsBgv94Hg6kVbSTtaaBuXhU1&#43;OrSwHIJl5t&#43;d5is8DwTVtD7N2XRUjqGSZYR8CUOczRBbrAazn6DSTDeG7jUlTzZOvMiJJrB30CRVLyyShS4hS10oU/yLjfXkBN09W0OxRbNG3jq0bS6ezobYxVJWKutbSy4HIUEa5sZPWsVdg4X0PBM0TER3TvY8L&#43;AKOXsYn6cETQArfAwigbXB/JsRjKn2F&#43;8HEwM/j5//Q&#43;SjtZFHvX5&#43;AD0BhRtyjRb&#43;BGmVopNH08XASv4MxdC6klOvVoJEXXS/PT3A5AxeJTGUpkDktFx8qmSivH4SuqORcbKjBVsnwWpHpbzkWeQFjiRgpFc8/L8vFL3CBkpItfQMB&#43;ERN/R54ANZuLdrJiyNIGjVRjNwtlSqlxv562tfECWVeaFEkAdHDSTs4VsSCfT/19U9Lzkxt/thO1gn7RqnaUG3MmFjHX8dydqGd7HWPnpqUn53iBN8LUVehTIyvxZR4UzSgrdQb5eKvfffa8c6FcvHjeBMVTHQFHOokGngy4jAPSFuEcNSkOLPtI&#43;RqWhwxXIO8XhEm/zqqOjaqQYcRM3&#43;hWy86XnMypsQXzKJr18NpbyQXTa2F6XhvTlIou4PrsDL4lYUefu54UwTEsuWLsrFq0ogxyhQ1jRuNkUSavDCGWyCPaN6mbowFxEMk3kALNMMXjmus/NcazldP/a4WwJXxJix8HhoePwv9/ng12uZMxrSoDxSsAAkH5zDf&#43;PgalbwnhZNprOCNpoy&#43;mCR2r&#43;/4Jcf6QFIwQ6cOK5r4/68EbPyHI0d67bgvTBqJVbx8QYtpMGh5j&#43;Xz0LVN8SuNV4pELVqZ6bHZkE7EF/7h40dSdqD9s0XDiFUlsQB&#43;x/2eqDMFbXYPUIoeHxUNLyYuSEAcsT282WxpvV4hwROp4mwJnGsQQUjmmPUbmogPRWNJdWvH4lLLz4K8J6ILXSF8FmT91Ft5TZYnobY/MIvGK7kiDrXPhJ4mh4wFsEbRM0NIO3c1Aed7jNc5wAwVpKMDIfHFGZgDmFYKN6Za0Xar6IcPCfEU/JMM/fQsTpqQ388LYFUoOhQSMSQY9OHDB6rKHKZdxP97pU38/r4g1GSijG/wWHrkEHB6fS84vsKXd/dWhcJxAhXvfLXuoiykihlJNVKAVjwHQpkancQil0FBZGWN3/3jp09wN9u&#43;Q8vaw/EsPoGqkmqkHpDK87Zar2OAia2S0PgBgJi&#43;83UN&#43;l&#43;FG9ysFDrf&#43;QtgqNIx3AokbScRs6LUwO6niUMghBcj7Trf5HHSD5dGXKC0nu0wMVpJ4gUvTrXeIJLIi9Z1De1fXnBtLJhPDOGF5cXebNa&#43;XKtUEM&#43;LkqpKUtLYXD0eT7BIVqtK6vg3Le6x2e1ovZbP2KQ8Ho7iXMIzSH&#43;C4/6FniLix0Xxh/yBH34g0zUw41SS0mq9o/uHO2yG42FPn3/6CfGFD58&#43;oeJ4h&#43;AVwT1cMrt0Dj6PH//9LwSthuH7p5PdRgVf6WY5WpB&#43;hLyA3lHnsYD8rzGODicLTICdQqIW3cjJQ6w6NFZoEUXjxemGgYqVsFlg/FclCGQYHO2Q4JHScf8s8WzPWcgHkFjnyNIU1ohB4GUDODlzCuUzhwSjoJEBBO6RKF/HwEjVjNRX6m4bqk&#43;H&#43;Yx5DsHPzP&#43;GVszbLCvo/sMDoO18H0VSAtfCDZ35nV4j76EovadQJpuqwwv6Dhrz/bmAni4GTU2&#43;aVPj2UM5WkYKIsQ4ERl3OFo61RZROLql6Ex6DoQWcNa3XkEQKMtiahcibjrxi5NHv34YqBuM2LqLtn9bn8Fagc7NpBL3MGHzUpRK6hKH4syd7zQuWUkrAXss6g2IF1D0lNNJ7lGjzby4dce&#43;B21UZLumwQ5/enyCh5KviYIXvTiKSL3tLv&#43;lxiuoYKKZ&#43;8eNoZ9ZWNfXCEJNoFShaeTxLFVDpMx5MlF2rj9EKAEnyZi&#43;qzYWyGDnEI19/gAZNwK7DnY46ySpR&#43;l2ZkBkqqtr6oxFl41Qg9d5NE9oWRsUQ97xWLS6hq6w3uxQi5D/blpp6hSf1d8zYCK1o7HhRV0T2QHZQ8fjEdfk&#43;9WJZCHxtXIfcEKtZdZbblRP&#43;V7jKio4GuQjeHfc&#43;Q7VHiJUO2i1ghS2/P60P1rqDbM&#43;7RMqrFeslghZFVlqfa6RG4gK4JaAxE2VtG0x1sBdzDsKk&#43;wVQKkm2qPMPKDhXeujfw74/ME6&#43;PbhuUwzADPgtu3PNPQGwR7tldrOWx9ZXlBbN9S5AfDvrrtcHOuRRrzIRZZiZniXPz1&#43;pnVV&#43;fK5nQBJSNrSCEfoEadgbsBEwBuHCYffdQhK5nemg1ccQZOCUZPqXmHns13/8pwKxfcD9Z2lp2fyihfLX0Umtb45gyRxWBOqhExsbyua&#43;mG/pzPyAAfvRxiQKRxg4X3fRYh1sAb489B4KmQMx3awFuWjfV0A2aWhcnngNCGfHwvhRLndJpkkfzTnmDx6LYGECfHxs0PyavBbMBEfC3kWJJM0LYilaVrfa1nwk/x7ko6ckf&#43;2xiwrbHyXcbtSaPxrdLhEBK6Rrtgo4eLIl3Ox5Du2RYdK7zN4ERP32n2AlsZ7KIF4N34CwmR3rDSddIQiWzdHCbvxoS6wfrfQuNH9etW3L4WtM48lbM4nz42ulbWRfAZzNh4HMNYM4HkRR4Cb9DAcIoYCc4XqqTTJvArtY5Ofs5ZfNW6igv0v8eesz77H5YeOGwFXZ93ozldImDDU2jZO&#43;tQaGKuOemfylTiAmXjWl4S4dAr93KGUBec67F/o7BtNLKFgszlCToO5COFeM&#43;RmcDJ&#43;5NAm1wmglRIJHf8a4yoo1E32v/JVwmcTrkYnDvksHZZlySQNTppHCzKGYuvY6zDryPgmsYKxMvnt5/uWcxYCSBZpaW/XKPoW9xN969eLR9CyUmjYmXHRr0y28zBsNDrcboEwOZ8OZK20juX17gdpHUt60joWjRrr2cQqHwZFl62wI7Ro87HDCF0u9LR/UfzslSyg945fetF/i2PGAeLi36gSGne/0nC6fPjwEa1jNXWUZYZ&#43;&#43;KiQGh5ax567FF66PMvFc8cmnJ3X&#43;8kyqfeb&#43;HKzwPn1AjYJCaXRr64kJyHUCLQeNzD1tQcw5x9tIb923ASF3hxe6QKwMc/IdAPlBdGH&#43;4T&#43;8VcNAmgaB8Tr//0kOAEsEIIkanbt4FZdb7Yo98prVlUrckMLjd35Y9q2AYRLJ5J4kaVpRCTxMXwO2s0ZMSfZnOt/Rdv69zS&#43;HBOoYqjfy80Bqk&#43;O5BBNZc4arQUyWLkBmT62KG9cS7TfNM8oR3NHKbOinaBmpTADwZLY74&#43;Ulyv68PEB9vz5dKTPP31G&#43;Z0PHz&#43;i63Z9OtEjPUquvvk9lov//uMrQKHTWICLhR/QOFOTb6c6uo/tW7Aor1NIWzRvDgmbkfauWkkTaUsIEG3WK0HyDIXkJiqNqKTtO/jeBU/4Z7Ho9453QcKufzS2jmXzVRwxRDXbv4MDMCRhtq5fwbVN8g/YWgBCmK/Tiw9e6RQRvJIX2LqIF4DvH166nhL0FOrpvH9BWPZ4qq9j&#43;f8cV8ergJDw&#43;/yrCTrIZ7sSaWmH2jvKEvLRQXg6pEaPnkcAZ3jAQTT&#43;NFlL1g&#43;6cbdxcY3JcTxMNB9OlSISvXAGlIeRoAzqF5vhO&#43;TZ/feMm3iAi580jRj6Nuh9D9ue1&#43;Xzo0H&#43;G5TA2tLnZ0vdIBXD0F/Q&#43;np8NFoZElmTpA50&#43;LY5ys4ejwcRB97P0LUN8ueUThDCTb3LGC7dTqJ1zfk86wT657g&#43;lrMzKxKlxnDgAgdwGdJtm5ZeXl7QOvZ86uhwHOh0JMoyhbJxp9qnbyeNhD9DvRxFY8Kpd6ke9i&#43;ot5emCcAYLdq/arhidRL86h18Bqz5A3fPx/kQMO9&#43;&#43;OOD21a98sZ/9OGiEx3/LsLBAQMQy8PNwCDjfPLO3b9IcKf3YM/z2UVPoHO&#43;RIw9gIB4wQIQdP48wgUOQz/D96NjeFPHHIDgv0dalT9uBsme&#43;ONnmFH17b2Gv8vh5iHtm40jIxJIq5iwMOMCPqgBEAcvvAstZBcoWJLuYr3t43kBZ3AtDTo4euQJKeIOwt/RM2nd/JggVmjhVl4Gtm45t/4gw9E0qXf8Ow3u2AgCmbJ/dA6f4wHDTrOhKFPwDpKOYsT5/MHZaqgJyGS5EEuCuGp9LPICFoCV6dIvM5vJdz3/Q1NAHG5W9ynVqKaZxYIPilzkAsE&#43;jwQQWKpzaB1nlY3HJZMafgKz6n1ve3VZDGkKM3oTBOcix1DjL8sLzc/gd0HxqRDAUuN1/qSBcYugekuew8OGBMWmkd70aszZA4jC59MFzB7AFoFTQFQkAG/e39/BVj&#43;8PNPLyx7JmkTzfPTZGnxpSYxF2FBdfOli3oVzNClH8KcecGukvPuzoqC&#43;XchwpZDvvt5sqSgyVARFs4W286idkMs3ZvcwEVRFTqZrkY49hEzYKaJYXdvAl0x78iQzpW56nlp&#43;4C/uJjgG9cbV/&#43;gjVZPS72MBOVEGpBrYiu7vtvDssa293&#43;9Rr8fEdGYHzF7XNDDbch/ajdcMY2lGxHFjed5YsylBzT53NHIDFYhA/UkE0zFrHKmmytNoIDpfBwd5/aRotdkg64WclZp/XTdCsKxF3l9TN3IMhRW6km93hRBuLs61jz0Hccrr/k4tgCQTINsSQPLnmC0&#43;RTPwim0egZW&#43;r&#43;8Ar98Q6&#43;ZNC0U5v8ukKYP0/BeQhy8KEY0FN5H7k2V51/pExMrCurgGXRvBq98SNvZ7HmHRL0vEBHSOd/qEyvbOJ3FaYxBla&#43;uTVMo&#43;HlEZO1bw8AjdUOQBVkGaxGxfADoXQNNxfCERqIAjlOKVLrzQFCE0aVIdq53&#43;DongPfbRF41loaPAAeBCZTYfvGqyi5y1VvUoyb5HnZtQzg1QLe&#43;ZiwWglUCbmVCYhAZ02xhm1TVus&#43;H3M2g16Wss7uSQVTu5h1sQwi8AIP3lxoyVvUkBY&#43;2/1z&#43;bXBFj&#43;m06dC3qhhBkfkRtKmutYwIwvlvXrEjzlQlu2xaVNZlgpAdAL6lRV7qF3nzv6Vja7DMksYpE4JRbvKW7/HnrHr&#43;BMdO7gv4SPaH&#43;oBvhdLXEQIZC1beRzBMXkNwuHfreWYO2VsjYUE5&#43;IgSrzNxFu3jyWdFHK&#43;ig0RNIMxTx6zPwjs8n13HBs3vNvXtl0X&#43;LSmCYp/DTTVPunCXL5nU4&#43;NaCqoU/xLnLz8JX8r2zqBJkra8X5FL8aawaW8KACFSgTPWKD91NBPirLPZbzf/sfso/3/idu3bD3yDnV0GMLQpQQKwqSza0X/W1DF&#43;7jvxy6RG5NsS4s7z&#43;xvqRIjlXxRosDsV3w&#43;FxkW&#43;wgJt//TJDXdxRLTbH93&#43;mrxluEpvSNCacYhdG94rfze8hAHofEYDnW2x/awzTgLOpI7LjJnfuus/t7an8bUz274MARL0ZhYDs/BDeBtxGiOQLdz/dXvxR1XBCAsIIrP3/AgAA//&#43;QTavsA4yq/wAAAABJRU5ErkJggg=="
     data-sizes="auto"
     width="412" alt="Context Definition ID should be Content"
     loading="lazy" />


</a>

  
  
</figure></p>
<p>Finally select &ldquo;Content&rdquo; again since that&rsquo;s the label for node entities in Drupal 8. If you have your field on another content entity type (like a taxonomy term, or a file), pick that entity here instead and rest of this should still work with minor editing.</p>
<p>Once you run through the wizard you’ll have a new file in your module: <code>my_blocks/src/Plugin/Condition/sidebarContition.php</code></p>
<p>The condition plugin contains two main elements: a form that’s attached to all block settings forms, and an evaluate function that is called by blocks to determine if this condition applies in their current context.</p>
<p><code>buildConfigurationForm()</code> defines the form array elements you need. In this case that means a simple checkbox to indicate that this condition applies to this block. We also need to define <code>submitConfiguration()</code> to save the values on block save.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">buildConfigurationForm</span>(<span style="color:#66d9ef">array</span> $form, <span style="color:#a6e22e">FormStateInterface</span> $form_state) {
</span></span><span style="display:flex;"><span>$form[<span style="color:#e6db74">&#39;sidebarActive&#39;</span>] <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span><span style="color:#e6db74">&#39;#type&#39;</span>          <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;checkbox&#39;</span>,
</span></span><span style="display:flex;"><span><span style="color:#e6db74">&#39;#title&#39;</span>         <span style="color:#f92672">=&gt;</span> $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">t</span>(<span style="color:#e6db74">&#39;When Sidebar Field Active&#39;</span>),
</span></span><span style="display:flex;"><span><span style="color:#e6db74">&#39;#default_value&#39;</span> <span style="color:#f92672">=&gt;</span> $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">configuration</span>[<span style="color:#e6db74">&#39;sidebarActive&#39;</span>],
</span></span><span style="display:flex;"><span><span style="color:#e6db74">&#39;#description&#39;</span>   <span style="color:#f92672">=&gt;</span> $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">t</span>(<span style="color:#e6db74">&#39;Enable this block when the sidebar field on the node is active.&#39;</span>),
</span></span><span style="display:flex;"><span>];
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">return</span> <span style="color:#66d9ef">parent</span><span style="color:#f92672">::</span><span style="color:#a6e22e">buildConfigurationForm</span>($form, $form_state);
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">submitConfigurationForm</span>(<span style="color:#66d9ef">array</span> <span style="color:#f92672">&amp;</span><span style="color:#a6e22e">amp</span>;$form, <span style="color:#a6e22e">FormStateInterface</span> $form_state) {
</span></span><span style="display:flex;"><span>$this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">configuration</span>[<span style="color:#e6db74">&#39;sidebarActive&#39;</span>] <span style="color:#f92672">=</span> $form_state<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">getValue</span>(<span style="color:#e6db74">&#39;sidebarActive&#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">parent</span><span style="color:#f92672">::</span><span style="color:#a6e22e">submitConfigurationForm</span>($form, $form_state);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>In the complete example you&rsquo;ll see there is <code>summary()</code> which provides the human friendly description of the values that have been set for this condition.</p>
<p>Now let&rsquo;s jump back to the top of the plugin and review the annotation. Conditions are annotated plugins and those questions I guided you through above were used to generate the annotation at the start of the file:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">* Provides the &#39;Sidebar condition&#39; condition.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">*
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">* @Condition(
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">*   id = &#34;sidebar_condition&#34;,
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">*   label = @Translation(&#34;Sidebar block condition&#34;),
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">*   context_definitions = {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">*     &#34;node&#34; = @ContextDefinition(
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">*        &#34;entity:node&#34;,
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">*        required = TRUE ,
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">*        label = @Translation(&#34;node&#34;)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">*     )
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">*   }
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">* )
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">*/</span>
</span></span></code></pre></div><p>This is defining the context you&rsquo;ll want passed to the condition for evaluation. In this case we are requiring that a node entity labeled &ldquo;node&rdquo; is provided when we need it.</p>
<p>The real work of the plugin is handled by <code>evaluate()</code>:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">* Evaluates the condition and returns TRUE or FALSE accordingly.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">*
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">* @return bool
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">*   TRUE if the condition has been met, FALSE otherwise.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">*/</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">evaluate</span>() {
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> (<span style="color:#66d9ef">empty</span>($this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">configuration</span>[<span style="color:#e6db74">&#39;sidebarActive&#39;</span>]) <span style="color:#f92672">&amp;</span><span style="color:#a6e22e">amp</span>;<span style="color:#f92672">&amp;</span><span style="color:#a6e22e">amp</span>; <span style="color:#f92672">!</span>$this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">isNegated</span>()) {
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">return</span> <span style="color:#66d9ef">TRUE</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>$node <span style="color:#f92672">=</span> $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">getContextValue</span>(<span style="color:#e6db74">&#39;node&#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> ($node<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">hasField</span>(<span style="color:#e6db74">&#39;field_enable_sidebar&#39;</span>)<span style="color:#f92672">&amp;</span><span style="color:#a6e22e">amp</span>;<span style="color:#f92672">&amp;</span><span style="color:#a6e22e">amp</span>; $node<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">field_enable_sidebar</span><span style="color:#f92672">-&amp;</span><span style="color:#a6e22e">amp</span>;<span style="color:#a6e22e">amp</span>;<span style="color:#a6e22e">gt</span>;<span style="color:#a6e22e">value</span>) {
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">return</span> <span style="color:#66d9ef">TRUE</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">return</span> <span style="color:#66d9ef">FALSE</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>The first conditional ensures that this plugin doesn&rsquo;t disable all blocks that aren&rsquo;t using it. Next we ask for the context <code>node</code> value we defined in the annotation, which provides us the current node able to be displayed. Since not all node types are guaranteed to have our sidebar field we first check that it exists and then check its value and return the correct status for block display.</p>
<p>Now every time a user checks a box on the node, any blocks with this condition enabled will be displayed along with the node. And the best part is that the user doesn&rsquo;t need to even have block display permissions, we&rsquo;ve allowed them to bypass that part of the system entirely.</p>
<script
  src="https://gist.github.com/acrosman/ab7e9ffce3996f6bc1798f9f1ca34c06.js"></script>
]]></content:encoded> </item> <item>
      <title>Time estimation: making up numbers as we go along.</title>
      <link>https://spinningcode.org/2017/06/time-estimation-making-up-numbers-as-we-go-along/</link>
      <pubDate>
        Mon, 05 Jun 2017 00:40:01 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=316</guid>  <description>I wrote a simple tool to create project estimates that simulates how long a list of tasks might take.</description> <content:encoded><![CDATA[<p>Any experienced developer, and anyone who has worked with developers, knows that we’re terrible at estimating project times.  There are mountains of blog posts <a href="https://www.sitepoint.com/how-to-estimate-time-for-a-project/">telling developers how to do estimates</a> (spoiler alert, they are wrong), and <a href="https://www.applicoinc.com/blog/software-estimates-suck/">at least as many</a> <a href="https://coding.abel.nu/2012/06/programmer-time-translation-table/">telling project managers not to rely</a> <a href="https://dzone.com/articles/4-biggest-reasons-why-software-0">on the bad estimates from developers</a>. Most of the honest advice doesn’t actually help you develop a number it <a href="https://softwareengineering.stackexchange.com/a/716">helps you develop strategies to make a slightly better guess</a>.</p>
<p>Any time I start to work with a new project manager on time estimates I try to make sure they understand any estimate is – at best – an educated guess, not a promise. I’ve learned to give ranges to imply inaccuracy and round up to offset <a href="https://en.wikipedia.org/wiki/Planning_fallacy">my bias as a developer to underestimate</a> (I recently noticed I’m frequently doing that too well and badly overestimating but that&rsquo;s another story). However, that still led to greater faith in the estimates than they deserve.</p>
<p>A few months ago I was asked about this topic by a program manager I really enjoy working with and who was trying to work with me to find a better solution for our projects together. One of the articles I sent her was an old one from <a href="http://www.joelonsoftware.com/items/2007/10/26.html">Joel Spolsky written in 2007</a>. Re-reading the article I again drawn to his discussion of using <a href="https://en.wikipedia.org/wiki/Monte_Carlo_method">Monte Carlo simulations</a> to help come up with estimates about project duration. While he argues it helps increase accuracy, I mostly think it helps emphasis their lack of accuracy.</p>
<p>And since I’m a developer I wrote a simple tool to <a href="/estimates">create project estimates</a> that simulates how long a list of tasks might take ( <a href="https://github.com/acrosman/simple-project-estimates">code on GitHub</a> and pull requests are welcome). It’s nothing fancy, just a simple JavaScript tool that allows you to enter some tasks and estimates (or upload a CSV file) and run the simulation as many number of times you’d like.</p>
<p>Currently the purpose of it is more to encourage people to understand risk levels and ranges than to provide a figure to hang your hat on. Since estimates are bad, the tool is inherently garbage in garbage out. But I’m finding helpful in explaining to PMs about the fuzziness of the estimates. By showing a range of outcomes – including some that are very high (it assumes that your high-end estimate could be as low as ⅓ the total time needed on a task) – and providing a simple visualization of the data, it helps make it clear that estimates can be wrong, and added up error can blow a budget.</p>






<figure class="figure-center">
  
  <a href="/wp-content/uploads/2017/06/TimeEstimates.png" target="_blank" rel="noopener noreferrer">
    
    

    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2017/06/TimeEstimates.png" alt="Histogram of time estimates." loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2017/06/TimeEstimates_hu_f22f2980752673d5.png 680w, /wp-content/uploads/2017/06/TimeEstimates_hu_f8784d97e702d22d.png 850w, /wp-content/uploads/2017/06/TimeEstimates_hu_9268ae8b3d7fbf90.png 1020w, /wp-content/uploads/2017/06/TimeEstimates_hu_194b51c1223c4e74.png 1360w, /wp-content/uploads/2017/06/TimeEstimates.png 1584w"
     data-src="/wp-content/uploads/2017/06/TimeEstimates.png"
     src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAABrCAIAAAAw3x3dAAAVw0lEQVR4nOx9WX8TSa93rb3YjsPMMFzM9/9Sz&#43;1zc877Gwh4aXfXJr0/Se3GhCSQYMd2OBoGHKdXqST9tVSVyzmXUhBRMyGiQqW0MsYoJkREAPpKKzlGvp8&#43;0Cl7QiattTGGT0Sl1XeH0al8fb0/4&#43;sV5NcTHd7oTZJLKXXbLsZoDL0wABYAa4zzzhirtSokoMJiIV4Y4q3Rhj8ybwoUABB&#43;ZaLimQBKTpmYS0chkGjlIsZa45yvKq9QxRRlBAgZY5xzFZNhOjeLTkskgM12u9lsEACVKoX4aZ2tqtpX3mhN7M&#43;lIEChA6zRzjnLJBJKMaaUjKEvIlPdtG3bQslhGHLOSmvcD3WlaOxba9u2vVkstNFd1w3DgIgiBudc0zTL5dJa&#43;7bHvpDT2mrjUfsEsQAgakBdisaCkNFohaAKGtYMxYZIOxrEoyZoZijrAn1hnXXgjKWvFPIAtoa4zmZNoxYBHKqQyKOUIlZLRv3vYHyEnHbetfMqI4ZgyXwrAFCojDXaWhq8GrRGa71vbEV64ZrKVs6OXFcKgNRGhMIDGcSMIELJGXjUy9hnKYwm3jnnvddaV1WVc570Y/qVtfbczHkNcmzVrVIayY4rHppsiDArID9JHwGMNVU1m83apmlbEoC4ZKUObMvhgJXPk3c9&#43;EB/6b3GKKWqqsIDIU1j/9APv2FyI8hBUKOblbcnTgGDH&#43;YuArAPQJxgkVYwcpl&#43;A3vbMloPPpdpj57oIPLEyB7bVJU/5O8hEHrzTD8kByXlOMQYcyGGAoJCJMMh5pj0Qyk0peR&#43;GLTRJYbojSUJ4R5NqpQSIrJbJuNjjWHoVGSYG2u10jmlXAgkpZydc7e3t/PZbLIzvxXTD8kh5Bz7OGxDTDSKGZtnsjvonHfWiqctOaehpKHbsYslV8ERg3OurmtCnDkx0tR1XTd1FWMcQiDr5lxdVdYR3KKDcgoh&#43;srXdT1r23O//vnJaaWcUd4oYLTCtkhpy6EY&#43;eBiCbY7Z2wp7EfJtbIxYiL0Yg254gK5FMJI4ADG36eS6ACtLQmTpEkwybGXdU79rqP&#43;kEgAWtC9mG8GM2I5jNExJq2VtdoaV3kvwBERJX4Wa661cWRJkI09Q1BjZvNZVde7XR9jBISqqtq22fsM1IYUxfyfAMQJl5zDEMhisL0WR&#43;opEuZoNpcUEwBYawkeVt47D4Axppyz5tHNAlAMR1POFE/d3Cwq73eqTzFa8hNYVZVzbrqxCHIKoc/KhHOSM9b6yldVRTGYGf9TShG7OSWgdWIMpEaQziYESrHGIEvLjoPekjYwxGTUQ&#43;FVXdcI4JwFABZYQQRhvWQoLMUX3jn35lMOjxHZZeerqq44uP0KCgnScEwkQNMwl0ktmNs06J1lezXiTmdtthaVsgSCjMDKyntFXj5zuikxuqUrI2DKCVG1bbO4uZm1s99WDxwAGfSY2J4owjaMVbK1rm0aYRZhx5RQqZhTlXLbthL0xhCQgFAyei64PqVMAz0Vharh4U&#43;uOOeSg41RYGtd1UqroR9yoQC4rhuoQanfIu79nhwy8Bd7QoaDrX7Oha2I9iNbiTspZwqmLLCBcpJCyImOtNb4yqNqEVVMCYCiBWtMXde&#43;ruhICjIouDPsfp0llx5j8pX/TZJuj5FDYAvPuNGy4decvGQQagDQWO2cNzNbF9IMkkSMiGSUZrNZDBFwVBHn3OJmkVIahiHnFJOZL&#43;aLxWJv9MeMBUdqtsBcIjXvvXW/rwz2KCgMIUbvfN3UDIVcKdDv&#43;g7RWUPYpyJPDYhhILLWtrN5XVUllzQMGw672tmsbWqO3UxkOGSMOQQ/U7ZnrPww/bbWX8gJXnHOZQqpRmJTBJlTB5JjdpajKOewrg2jT2O00oorBxWBVI6zEFXmgK1pmnbW1nUt&#43;Ynvb/w7M/2QHKfavpZKhPX7ypRSGilsZU&#43;Qc4ICRhvCNpyvyykCRVWEjBzHukphSkkpPZvPl8ubhtz1b4ovf5KcZC5TSjFEpcbcG/sFzIUAEbEVFf8N7J4zIjhyFd6wk4gx5pTJsBNsJdRkrPEkD6&#43;5xPYz432Cs78bOc2Dt2kasvwUE3mtKZgqBXQiZ6vIXnONxXqCO8lQFEYxWs1VF3Ldg&#43;7HwgBHcFIc3u26FIO4dBItBRl0qUM3IIUAZ21VN1Xlf0N1cUr6INgTaKW5MAucAzUyhIErXiknzsQpozQoLR6CfWzN2qBIDziegFK00SGG9UpZaxRXlbnORfwFoBCBgjVtcskSYdd1/e7dH8be&#43;N/PIY8pSSglxYQqccEFrNFun7eUMn0MAciY6FJyyfSB03HFUEDgnWSbOYZQWnntCgDhUE7eCXj1vlhrAYrWplIKdAkxioFSSklV8tzcOAM57/18caO0iTFyX4RSUrk1mrMRZmzeUYpzakqSoGJFLNsuX3lnbds0yBaG80UWEFMkpdHGcB0MpYg/dUUI00UA3vt21tqxU0hJ9Vjh9PEtawXZB/asmVsipGyO4pmHYYgh1k3dtu0Ur0rJXhjFYNRKWkLymuNFyb4rgEJoinNz91D/vdBsTC7tb4GoCkMxGg8cPDur32ru2nGKjeheg1uM8ePHj//&#43;&#43;&#43;&#43;HDx9ubm7qur5XZxd6YnCOYddYaFbfF&#43;6/L8QrTkblgkPKIRVObGPr7bzx3r1NmOTuvb&#43;QlLo&#43;f/783//&#43;1zn34cOHFzQK3jvywRPvfUmGK8Mu5vUu7UIKqWiA28Y53VpTE0p4c&#43;Qe&#43;wUiDsOw2Wykbe0VHgVRpQybIX3pwqYn7ueUdYy&#43;V3OrKi8lu7cmg6cEIAAURt9wcgLEIZW7Tfi0GVIB7gQA3Q9Dl7rK1rNG3MQrPMlr0qUEPpxEgm5Id9vhyy6GVKSZF3NJQ&#43;i60A0pZoA3B1UvRwAY2f5shxxzmZROeh0H8gqxC4l/c&#43;5nPSpdhABQqUL2J&#43;8CgZ97TBbZbENix/DWlOAyBMDgp49liKVMPY3fHhDpgBwOlONt0EUIAFDFXHZBjM8DByAFgBgS9HQM4IMHXSedXwBc0eThn0p&#43;3L4AYkhl3aduSG/JGT8KQ1&#43;HOOuAu5gF&#43;DNfH2YtspZs&#43;lh721T72TnXT25q8IcD48vZ5vwKEQAqdrBD6kJK&#43;Qn&#43;07EFsI8kg5vWNxKXnfThXoWcZB2Goe/7QSqRCJBL2e12XdedOksMgDEVAT9PmxUc00TQDbmPedl6j/oNtPeSBuSU1qv1p7u7XMBbU7hCGUL8slrHmE4nALE/fST0mX4O3XyTp/Pq6tnPTnh6b61wnEw6TQ466QgT&#43;9OFTPbnYfhz7/gJj5YfKczVkFNKe&#43;&#43;Xt8uqqgsU5jmJYbfbfWY6Xf6LkGUu2yENsSitps7UJwhJCSgwlmjZXL8NctxYaGezedO0h3Pqqqqaz2fuZD1riCoD9iGTAHKprPkZSEwei8XGVgjs9edH3VSlOuxIkAnTJ20VQUXR75bsTxbf85MnckAA2yEv2&#43;Kt0VeORs8WiCGqVMbI9qHsww9O3IXUsetWV&#43;4KzigALACZ&#43;4KfAP8PEgAOSVIXcO1ZifMIgEG9KqC4wv9sFk6eIEqweJqHfB06kwAQC2KSvokXSGBfPR7izwYQF0tnEIAM/0z2B188fCU11IU8pHLVSnAODUDFw5&#43;U4MWM40nIsAtjFH29rvgsGkADv/zC8B&#43;LaIAhlZ6t0PW64q9zVw6HI&#43;xnLZ3ilpJWA&#43;kK/oU7IGIsJICYoK2uNSp2UxtWSkk6NaUbZbfbhRCm5tljkYxcsv7Pwf4PXwpVzmyFYp437kqjYsezgCGEsNlsuQcLSskp5b4fVuu1LINyxPvJQn5if37puoydUsEu5E0fl62vnL3G7KijN0HIOfV933Ud8R9KSmUIIQxB1nE77i2BMegvK8DoS0Iq24Gw0LzGayzRuCkX7Ss/w5mW1mjEfhg&#43;/jv//NkdUa/H&#43;IsEcL/J94UXZGc&#43;kCsuqQC3V1&#43;ZCGSOGFkha&#43;xiseBZpVYp1XXd//vf/5Vl3Y54vxH/jMXHI8hAlKALKeSq9tdnhcZ5wlyRHObzRV3XVeVlIsbx19BADsHYBB3LsElP48A9RbMKri47Ok564dnXA/BkvGnpt6Or80EEcMzLihLs9m1bx7z06clIGXJcfUnpk7aASwvir2QgHr4sK0Ef85Dg6jJDPAVsXAjxtM8&#43;tjXsMxDHvRMgQdIxu3fka5&#43;WDBeBeRoXLyn5/VLaxyJGLCoByoJzR7743rjxeo/XJAH2sWxyAGE/A/L4dJABnXKXR5eByjAqwRVJwIz2p4x0KiuEnMH/tQzoD&#43;4gSVYyRAjXIwEzZcRkkbjTLRYALIOTsX/sXUyjkl2NBIxYZ82LDlRVLQI4hY0WQZ&#43;UL5LpS4UkcS0S4HQ0t8LtZ68XQUQxxmNZJO5oGzXgdHzByQqB5JrwKsJiJwuZKKVCjKv1OpesFeZcdrt&#43;s9mmdIzmXBT4L5bhtCNTXH0qUBl9FQ3sTmvteb3&#43;uFqHEHbdFgFSzsMQ1ut1SvHXBQAKD&#43;MvVCccmRLrJcCMyNshXLoISADO&#43;/l8PoQYQzRGoeE1ZgB5HRrzi&#43;z6Jv56BbvM64KwEhhn8PKzo052rLi5ufHe51xGPCHNuXd3d3efzE/0zD5FkoDj/M/r&#43;MV9wgMKGKsvXQmcLFZSV9Xheh3SG9q2za/vIzLGqGOA/SoiECVgGThjT91k/4s0FuW1MYecnnZj&#43;MXhs&#43;&#43;A&#43;&#43;UC5DNvKng0FjBa1/ail6M7eVvK6ABed2qpdN5FlkF&#43;Hd/zUjqtACS9JxWYV7I/X29NeDRy/90lS&#43;DkGlAmD/zqwankqGOBVwJgL6ITa8BUBH51BsiEMlKCwk2ol5qaOKEA9hkIhNNngR57gIIqsQwutlJ2Wg0QD3zG5CQrAUaAfbHs4uiESxUIFOEY&#43;HQ3&#43;TEB91EHbpeQLSzP&#43;TTf0VcBHK4j&#43;XWxspded18CGwuQZ3zt0RAVjAYpML4wEYwCGNfvjlH6oksp3W43DEPhRW9fQmNmeFR8fdoU3A&#43;fhSfkFOCdM/GiRDDWAwBg6PvVeh1DSDmllPshfFmtYkovAzDA9amz4J8HSQqihmPjSl/QWrxuQmyFizDDMCTifw4hppR5n8/nT6IT94snrAA/72lQoaa4TLass1wouBAJuP0KxKau6&#43;Vy2dSNbCrT98Pnu7vVl5csVSDgJ1MEdDHwGxUoFQtY3vfAXowrGH2ACMA5B&#43;PEUey67n/&#43;Z&#43;Ge35zLq0ZjKiibNJ&#43;8BvbTJFMTQgFftIjhEkSwz4ZyTdhaK84SEWVXpBc03KMi1ie4xNhHIOmQBZLqS9i76ZvNHZX6ClVe9mz74BMvc2U9HL0xhEICqHjj9vPK4MiBmKRfEqdfLsb2fEP71hXYdyGb887qOKYApuBLEpBn1&#43;4nqCAGnuDdOFVZ486HS4&#43;qARx8xQKJ4f9lOLkHSAYKAmTQnKm2ytlzyeCYAgCF3B5Lf2t1xsj3pwjGfTr0&#43;KiWNxB/dSkcTQCC/Wn4s2qf27f9mMRHZcAhg1YaUHmjHefsXlMMRxAATlnfAmMN9hhP9gokUUrh4ICMp6HgoLLGG9mnUf47Lf2SAKSFSObdhQIhQ5L2f0TZOwbHFoXx5ykow6l5YUp04L6FV&#43;3LN2MMtz8Dv73vNx/2HXff4K57XXjfz0r4&#43;gQFkaL2oqLW2WFt0XHmmv&#43;ovTXV6hugfhx6WACycq4058pn2T7&#43;mzfjVwIuOYU8lr/5DxdgQGsDinScExJaNitUkqHTir4pJfMmZZlYUHQxln7im5aiipF/iOTvopFPAatNKWSwYfzaFKdLMTkbrdEarZh9hauh9NRAP4qR5B4cjfQj98vwJnZIbMYCxNyUdbRmjNSMdnrcalxWiT1IIt3/91my0fvNyB8QgITBfd/LOgW73e7Tp09934&#43;7KI3DESfQGUqJRfoe9iUwRKvJnioG3YVdgkTVUqPXShmtQsyrL8NmO5AAalc5w4vYkzxy5YI3mLPabPzQqxxLSkmbPpWUwTsTPW/fl3h&#43;tjG5dmXwsffOW8uM03psSdJaCdKXdRoV5&#43;PM/kdUymr6RvSAfiun79nk2C6Z/Sqqh2qhvu7m9QwZCOubpmnb1nv/sAAy1wY894yuVqv//Oc/4&#43;by3GYymhneJFLiXll11egxzEGF8qAsACicX&#43;JtqDQqDfyURvGWPbu47RMqrJ11VssKNIjorSH5QdFD8DmpuoamKUqHDAXQWrLUWmuK&#43;Dik8k7X3taVc&#43;Om9&#43;NWZRKNiwDG/nh&#43;Tt6ikZRVjflRo8gP069Zf8YNtfjgUR4ykVF&#43;tPt5vGqaYncokD0bJ9IHm&#43;9L2u39&#43;/f//PPPcrl82AQZa9u2/eeff7zz/378d71eyxzKXEoYhhgjKuV8Vde14Y38ycYf2FqxvHrMKWXZYHtsgKwq2bRS9q83GWYkRGVBG9SGBm0W6xdL1krVzntvtcmm9FppQ7YNNWpbtMzv8TzRPPcpltIZ5auqqWvv3bQnnFLfPJv8W3IZAr2IUrqq6RRuwtTfHMz/y49QSogxDAMAeOdqns9up6URvrNGNBBLjiHGGMhmWte2TVVVIom2bZumEQOjv8cs0&#43;o1vCPqbrVa9X0vFcq&#43;7z9//rzZbBDVzXL55x9/NG0zbnf4gCopgLLb0Sldt7XW3ixvb2&#43;XJLZxh0R1r2EHAUIMu67b9X3X7ay1f/3513J5Q9x5BBnKU63Xq&#43;22g1Lmi/mff/45a2fmsYVISQ/GF1mv11qb5XL5xx/vmubRF5Ft7dar1d3dXYipaZrb2&#43;lFHn4qRAwhrFer1XoVhtC07V/v39/c3DiWmfd&#43;uVzSc85mDwjgcP2mw3XsAaDb7e4&#43;fVqtVoD47vbd&#43;/fvZ7OntmyGAl3Xffr0abvdWGtv3717905k9ig3Qxi2m81m2223W&#43;&#43;rDx8&#43;3N7eyvIVj50iqyyvVuuc883y5u&#43;//17M5089Fb/Ip48fV6uV1ubdu3d//fVn&#43;/je0yKAz58/f/z4MYTYtO0f9B7v2qZ5LGDgXdj61ZfVly9fhmFo2vbvDx9ul7eyEvGUeyYd&#43;iFqP2yZjjF2XRfCgEq3TTufz55ezUOmOu3olGgsqV7btjzt4NHnzjmFIZDuxmitWyzmvNfxo9yUp9rtdsMQAKBpal7xonp6j8UY47brwjBobdq2mc2eehExCTumnIv3nt&#43;j&#43;cGLMJDpyfxm7/1isbj3IqP1elbYNHVLiC2TnTyfOH7aDQ4Bx&#43;1Zf9SqjNNyaaPvklN&#43;8Eiyz4HmxhPrrCx38YwXsT9IS4sMpt3Bf&#43;ZFYH8PciSPv/vzBHCoED8frp/uFBnL/a7PORtLslIsM97i2Nsn16N&#43;7lMdMuqIp7jnNu28IE1yulNkz927u7vdbuf2A7&#43;q6sXNYj5fGPOUeXzuU53oLRwAvIEN9SV4VAr5XUw&#43;3ZT/Y5MehuHUK9WfjkYT1PcpxhG5McirmaYdoi&#43;Z/n8AAAD//6VgtHcG7FVHAAAAAElFTkSuQmCC"
     data-sizes="auto"
     width="1584" alt="Histogram of time estimates."
     loading="lazy" />



  </a><figcaption>This is the output from a recent set of estimates I was asked for, hopefully it&rsquo;ll be good news</figcaption></figure>

<p>Please take some time to play around the tool and let me know what you think. It’s extremely rough at the moment, but if people find it useful I could polish some edges and add features.</p>
]]></content:encoded> </item> <item>
      <title>Writing Good Directions</title>
      <link>https://spinningcode.org/2017/05/writing-good-directions/</link>
      <pubDate>
        Sun, 28 May 2017 17:00:10 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=298</guid>  <description>Writing directions can be thankless: you know you provided good directions when people use them and never complain about them.</description> <content:encoded><![CDATA[<p>Last fall I wrote about the importance of <a href="/2016/10/documenting-your-work/">writing good documentation</a>, and part of writing good documentation includes writing good directions. I have a pet peeve when it comes to poorly written instructions of any kind, but unfortunately I&rsquo;m still learning to do it well myself.</p>
<p>Writing directions can be thankless: you know you provided good directions when people use them and never complain about them. If you write bad directions everyone who gets stuck complains about your work – and usually not nicely because you left them frustrated.</p>






<figure class="figure-center">
  
  <a href="/wp-content/uploads/2017/05/AHC_3102.jpg" target="_blank" rel="noopener noreferrer">
    
    

    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2017/05/AHC_3102.jpg" alt="A greyhound wearing a vest labeled donations" loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2017/05/AHC_3102_hu_52c194e0fee0e3ac.jpg 680w, /wp-content/uploads/2017/05/AHC_3102_hu_718e6cb7042860a4.jpg 850w, /wp-content/uploads/2017/05/AHC_3102_hu_7423d7fa64074505.jpg 1020w, /wp-content/uploads/2017/05/AHC_3102_hu_b4b014edf92d9572.jpg 1360w, /wp-content/uploads/2017/05/AHC_3102_hu_be78035b5a8fd63c.jpg 2040w, /wp-content/uploads/2017/05/AHC_3102.jpg 4928w"
     data-src="/wp-content/uploads/2017/05/AHC_3102.jpg"
     src="data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDIBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAFUAgAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AOXNh5g3msy50KGU8pXRAOP9qkLjuKAOVj0IW8vmQAqasS2l/ONjkMPYYro9w2fdpN7AZxWYHO2&#43;mXEdX47E7Nj1fS45&#43;5R5rvJ93FAGXJpoBaonsZHxs/76rUuGGOvzVV814&#43;FNAFSSxkA&#43;d&#43;ax7mJzBcO7/d&#43;WuikSSVCw54rn74Eaa7d2krSkFUytQ/49bVPavRPAp/0MJXnep8TRr/sCu1&#43;Ht15jSR5&#43;7RVCkddrUnlWEo/v1x0cMn94Vu&#43;J9TgtpIoJn96wP7Wsv&#43;eorhsFUratvjsHrnLDpMT/AHDWprOqR3Efkw/N/tVl2vFvP/u11YakZHowkCfxZpC0T9TiqMt1bwJud9p9Kx7nWVGfKG761odVKlUqHTG4jA2blqPzQf4xXES6vck8/KPrU9ve3txHmJGbb3FBp9WOwEmzptNKglnf5UwPpXJi/uoX&#43;feje9adnrV7IwiIDE&#43;lZtWD6ujUubNI&#43;Xfn25qjl9/7iAs3uM10tjpT3MXm3S7fbNbOmafHPdJbwRjB6tWXtdQeGsrnCpp&#43;u3ufLtJCAOirTm8AeJbqyVVsm65wxxX0BZ/2dY2iJvTK8HHrSy6zbKrmKNnKdQBXaqZxOofN2ofDzxQzbm09jhQOOa2fA/hPXNN1B3urGREI9K90/tO4lB8u0yucZ9aqza1cwuqtDHnuvpRUCmeCfELTr4a0rG3cRheCBXFFWBwQc19aWM1lrEEh1C2i4OMMo5ryzxl4X0241GR9OjWEr2XoayqVaVM09lUqHjpDDsamjnWO1ljwd7Yq9qdvPpshSWPnscVn28wkkbeBTVXsa/VS3J9plfe7M4o3KOHjOa6K3WOPjYrVZktoZI8iFd9dX1EP7TpnPW&#43;kpc/vJtwX&#43;6K6bStJmaJUtoysfrUcMgiwGiFddpGnXE0cc4&#43;SFvStKvs8NTOH2tTE1DHl0OTrOibR61Po0WnC4ZVVDMvtXU3unJJbsxbbtWuN1S0WyVbyxl/eJyw9a8uriamI/do76WHhTOovGMNqCByeAK6fwVoUkcT3Nzn94PlrkfD2tWWsXlsk7xq2OVY969itkjW2XaVC44xXPhsL/wAvKhpicT/y7RQTStPTKFdzZzzV&#43;KGKEHES/lVG7uLe3l3vPGq&#43;5rK1Hx1otiwQ3O9/7qDNelc4bGtfXRtbd3VQPwrkDdC5leRz81Z&#43;r/EeylieOG1lbPeqOkagl6Qem/1rixJ24akbLswHykj6VnyRCWT56syzLFJ5ZIqOSPP7xK4XTOqmc1r&#43;hQahbyKyfN/Ca83n0N9NucP8w7V7FN/qnz1rzbxhI8UsL/WtcNV6GpZji/2KlCY5oQ4/i/CszU7y42EIhRa&#43;u/hnylJe0L5Ky3IhV1JY8&#43;1dUWvntoILScRRRdT6155phbzPN3kP3zWiNQvWDIshVR0ryMVV9qephcKz0G8eZbMK1ypyvzHNcLrUyRxSpDM8jNxxVaee9mVRLckiqkhkj52764fZnr&#43;yMJEntJxKryI4PBBrq4PG&#43;tW0MaPqUrR9NuaopNHLxJHUVzp8ciZjWtQ&#43;qna6d4qtJ4x9sd3Y&#43;rVfvtPW&#43;iS603y3Y/wtXm&#43;naebm58khgw9K9Q0fUbTT7SK1uHjLr05rKr&#43;7MqtE5a9OrWznfppx3KjNb3hwmeweR02OhrpC9veRFI5B8/41Ws7BLBHizu3tWXtfaGfsjJNyNTLiOXbNExGM1Na3l5Au2Zcr0rh9ZXUNK8TTz2W4ozZ244q/F41ljjxcWjF/YVr/AMuxezqHZXnNuJF4Brg/HVm/2e3Pqa3bHXptXUwC2dYywbLDpWN41uftUsdujr8lZKnaoa0l7QyzfzheNm/6VW&#43;0zS5&#43;0Srj&#43;7iq0ch/jqykcEqcnaa7vrVU1pYDDIkilXPCirYk/wBisz7PsPyTVZhldHCPWZ02SL48sj56EijP3WpCY8UyKTnhaDUfJajslMjiIfD1ZEvzjNSOR9/bQBRktpFkLxMyf7QrFuPtEdyx81mb3NdJLew&#43;Uw71mRwfaZS7j5aRl7MjsdZ1CzkBWYjH&#43;1XS2XjmcYDFXNczc6KWfMb4qhLY3FqePm&#43;lZ&#43;yM7Ho3/CVxTHdJZxufXFQS&#43;I9MA3vpibv92vPINRlhkw2R9a1o7&#43;K4j2HGaPZB7Ombtx4tLIUtLdY19hXNXt2s0pZ13O1TyRxeXw4WsiWRE3KjbmrT2Yv4ZfIDHkVFc/ukG2pR1qK&#43;&#43;4KZsAJ8jPepLOZmk&#43;b5qiH/AB7Utj/raANdlDfNToOENJ/D&#43;FLB9w0GhWuLhxLitCJybcZrJuP9d&#43;NacP8Ax7igdMo3f7tWYUltqMmzZsXFLf8A&#43;raqVt1oMjTjvJDLtOMVLKclTiqUX&#43;vq5J/BQaFeazguFIZAD6iubuENvckIxrqx3&#43;lctqH/AB9H60HNiRfOcpyalt7ZGbcetVh9ytC26CgKR//Z"
     data-sizes="auto"
     width="4928" alt="A greyhound wearing a vest labeled donations"
     loading="lazy" />



  </a><figcaption>No one ever asks where to put money when Leo wears his donations vest.</figcaption></figure>







<figure class="figure-left">
  
  <a href="/wp-content/uploads/2017/05/AHC_4698.jpg" target="_blank" rel="noopener noreferrer">
    
    

    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2017/05/AHC_4698.jpg" alt="Sign with arrow pointing left label Cake and one pointing right labeled No Cake" loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2017/05/AHC_4698_hu_f5fd73e852d7bef8.jpg 680w, /wp-content/uploads/2017/05/AHC_4698_hu_e763ed71c3748921.jpg 850w, /wp-content/uploads/2017/05/AHC_4698_hu_9364abfd0e6e5508.jpg 1020w, /wp-content/uploads/2017/05/AHC_4698_hu_4b8a08be9d098274.jpg 1360w, /wp-content/uploads/2017/05/AHC_4698_hu_947a4ff61b812df1.jpg 2040w, /wp-content/uploads/2017/05/AHC_4698.jpg 3264w"
     data-src="/wp-content/uploads/2017/05/AHC_4698.jpg"
     src="data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDIBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAMEAgAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/ALfhf59NREro5JI7SBhHzK64ZvSuW8Lyv/ZzbPeugEBuIifuhR8zV3VTNGN4VhddRu5JQAoJNYvj2TzNQicelaXh1pH1y6hydoNUfHgjF3EF7CvIZ6&#43;F/iHGnpUWnf8AIX7dO9SnpUWn/wDIWP0pHfiv4Z2sFlHqcEcMy/IAaztLthavNEh&#43;QSHatbujAeWpyBjiorvRJNJne5kkDpKcrtp1DlpF3T4blm8yCSMMv8L0k9xqCvcNlRM5AIQcYpbHSrq&#43;h8&#43;A&#43;22tXTNPkgZw5&#43;cEg55opGWKNax/tP8AsqMQywyRFMY6YrM8MTSprE1vcoE2k&#43;XjofWlNpe2gby7hwjtwg6VY/sm&#43;QQvFJ86Nu5X&#43;tdJ5h1lJ/wGoklbyRuX5sc0vmUAB7/LUUf7s1LmqsslAHnvg2ATxGIybBmupmkQBreH7q9WPeuO8JkhHx612ES7EkllTqPlruqnMjmdGuXTXbiBEXJP3sVB400ya4nhMKGR8fNirmkxwQ&#43;Ip5d25iPu1N4nDLAJBIUcKWFeRVPcwp5vcW0ls22VSrehqhZyONX&#43;Vd3FX5rmS5JeRy5qjZcatx6VpSOrFfwjuLOcmwPy7TnFX57vYkaKrOwH8XIrP0mPzUQH&#43;9XZ29jCsXOAW9RTPM9r7OmVtMvgNOeRMxlAcqKv&#43;Gne7tzczfxE1Xlt1jhmRTnch7Vd8LRPFpah/elT/iBUq&#43;0pm1ticjgcVfjePbiqIjqUVqcpKfLzUUnydKHj6fNSSfIPWgCMy1VlkqWTmopI6APOfCbbXlPpjiu1LtfKq/dAH5Vwvhjm4lArt4z9nt9nWV/0Fd9U5qRzmn2&#43;3xRKS/7tf1q94ghFwcdiprOs9zeKivOO9bmpugkWMj733a8eqexS/hnAR6Ekr7FyozzTv&#43;EQ8q98&#43;KU7e&#43;a6S5eOzbpzWFe&#43;JNtwsESliTgn0rRVDp9nz0/aVfgNjSrKO2K&#43;Y/8AFXTfa7UDHmCvML6fUmuCsd0FQ&#43;lV8XuPnvJK19lUOarVwR60fKuQoSRP&#43;&#43;q1rG3SG2VA4OPQ14jG15F9y7l/Or0Gr6zb/wCqvCf940eyqGXtcMe2Y4ory/SfHWqx3Cw3Vv5oHUrXbad4jsNT&#43;6&#43;yTuposJ4db0zaNRE/wvQGDdDmo5DyKDmehJUUtWR5bxio5I4/WgDyrwufLv2&#43;ldj5nzNM/pXFeHP&#43;P/8ACu12BxtPSvTqnKYVjcN/wkG3A&#43;bNbGojzLm34&#43;6TWP5kdv4hQooO7j6VsXTZnhX3rx6v8Q9mj/DOT8QXgWSVQ2GIwD6VzCIqrgHLHqa0/Ekn/EyI&#43;tUtKtWvr&#43;CAdXfBrqw38MxzJ&#43;/7Mmhtridd0cUjgdwKI7a4lzsidsdeOldje69BoGow6dbwqIYhiXA5anWt3LeNGdPiWGJpNzFhjd7V0nkHF7G3bdpyO1PwfSuz07SFvNY1EjbhQR9M1A0NjAksqW5k8g7QMfeNAHLwTNA&#43;4Ha1SQOYLsXERPJ&#43;dR3q5ryoZoplhEJkQHaKzI5cGk9jalVZ6Z4f1BHvfsbSlgyB1J6ge9dLJHH2NeYeD5jN4glkz91QtejbvevOpno45W9mSbQOM1HInvVaQnfuzSbj61ocx5poHF&#43;PpXbj/VhB99q4TRDi/Tmu7AyGm/ur8teocpy8cZTxJ&#43;&#43;/hJrclP8ApUR7ZrnjKW1xy7cg10EMH2iIMzn5MmvLrfxD1KP8M4PxHJH9ub&#43;/modAu47HWbedz8gYFqr65Jv1hx6VS71thv4ZjmX&#43;8HoFzpVn/bM2pXd1G9o/zqN2SfarcDWE4t7uK7SKGLOIieSa4XTrK91a6FtASx9Ca3r/AMOnT7PywJpLn0VeBXQeaai6iNMR5VlUvLPltp/hrUkldIZRYSw5Zt53Y6GvOTaXq/6yGQ/gaCbmPk&#43;Yv50Aa2uXjz3oDzK&#43;1cZUVmDnvUWc85oJO00PY1jujsvA9lsu5Tu687q7wx/7dcT4AB8l3eu38xK82nuetmPxqmRSR/JUMnAq0ZExVWX95WhxHmGif8f8VegZ/dKv8NefaL/x/wAVeggiODnndXqHKcXdkL4gOPu5rp9Of/QpWb0JrkNWbd4g/dDjIzXTWNx/oE4X&#43;6a8ut/EPRofAjzrWOdSkIqkMnpV/WTsvs&#43;orW8GWFrdS3L3a5j27Rn1NbYb&#43;GZ5j/vEzK0vU5tJvY7qNiuDz7iuj1nxNOZY7qzu2IlXJQ/w1q3ug6fZJHFJCJCwKg/3fesHSNJtPs11fXfzxI2xFFdB5xX/AOEq1PgmRT9VFLNr91dW7JKkR3dworXt9As7iyJ8sgMNyknnrxxTLjwjGl2tvFcFpCN5GOgoA5fJzUgGatarpv8AZt55YcupGeaqxfPIiDvSexvQ&#43;JHovgeIJYSH3rqce1c54THlaf8A7xroy9edT&#43;A9TMf48xMCo/Lo8yl8xK0OI8l0g4vIT/tV3/8AyyDGvOtIk/f2/wBRXovWFfpXpnCcJr5MWuqU/ixWtpNwTYXQP901ieKHdNbX5uMCtDS2/wCJXct7YrzMUephN0c14hTZdRn1Wq8Go3NvCYoX2A4Y1P4gl8y8A2/dUVkZNa0v4Zjjf94mbz&#43;JdRlgMbTZzwTTdO1260&#43;CSFAHjc5&#43;YZ5qvouo21hOz3Vos6Y&#43;6TW6Nb8PSj59JKZ/utXScpPp&#43;tam2mvIsCyJH1IHOKSPxbul/wBIRlcgqXHUCtTw9qGitfiG1t51Z&#43;CucqawfF9pY22tMlk/ynll9DQZlfVb&#43;G7kTySxCj7znk1Fpo3XqVnYrU0YZu/90E1lV2Oqh/FR6l4ZiCaUhPrWuay9FOzSovcVf8yuKn/DO3Gf7xMKTApc1FmtDmPHNGk&#43;a2P0r0kEiAH1FeY6LJ&#43;6tvqK7&#43;&#43;upIrHMf8Adr1DlOU8WpIt9FIRww61Lo8hOlzR&#43;pFQeIbya5063MxB&#43;am6Pcp9lZB1ZgK8vHHfgv4kDN1u3kOqNDGm59oqibC8UcwsAPatHXrl7PXJZI2&#43;bAFUjrt6QQ8gYH2rppfwjmrfxWVxZzFd4jYil8t&#43;mw/lVy11qa3A&#43;RTjpmrUeuqsLSGKPfu9OtMxDRdWk0hZmjgLSsuFbH3az5JpriRppclicmr8WuruZnto8NU6atZlNn2Vee/WtAMutXReZ3/3ahiurAu3moe&#43;OK0dK&#43;zmR3g/u8/nWdX&#43;GdWG/wB4gemaXHjTYf8Adq32qGyj/wBAj/3adXLSNa38UKNnvRUfNBkeL6L/AKiD6iuu125eCxi2ttBArjdEP&#43;i2/wBRXU&#43;Jf&#43;QdD9RXpnKZmsRwvoCSvL8&#43;75RUGgxYjU9jIKZroz4eix/fFXNG/d6VEQPm38V5uO3PSy744GFr8m/WrgejVm1o3&#43;nahLezTNbyEM2elVv7Mu0Tf5T/APfNWtjklT95leipPsd0OTE/5Unkyj/lm35VqSOHapRx0qvtYHoakwfQ0zMkzXQ&#43;HOr/AFFc1gg8g10fhj95x38wVlif4Z24L/eIHrdtKBbKPaneaKqJGfLXntTfLP8AtVkiJbssmWjzKreVJ/epPLk/v0GR4zoh/wBFt/qK7HXkZtJQhc8iuJ0U/wCiwfWuv8QGRtDTD46V3GJn3VoLzRlXeBhhxWpa2nkQ2S7epzWdZWclxZRJGfmZhmukvQbaezjP8A5rixx6WW/GW5HVOCBT4/LI&#43;4v5VnXMvmP8lLazP5oBPeskYPc1LiOEWrExJ09KoRQ20g/1Mf5Vq3yqbJEYj5j2rPht0zwa0ENGlWRf57aP8qlGh6eTn7On5VbEdSx&#43;Z/doAxbrQdP3gNbDDEc06bRbTTry3&#43;yx7dzetalzl1TP94VDqB/4mVoM06n8M6cF8Zuw8AZqaTZj5aqiTgUSS0jje5JUdRebUnmigR4fox/0SL611&#43;syf8SNfpXF6Of9Ej&#43;tdfqz/wDEjUe1d/8Ay7Mi34WTzhGueldZqsMYiRnRd4/ixXE&#43;GjJ5Akjf7tb15fySRiN3rGqa0iKTy6jCLngmm5Dx9ajD843VzGhoWcJup2QyPhR61eS3S3&#43;7k/jWXa&#43;Zbu0iN971q15txJ/EPyoMzUj5G6jzXj57VQjlu0H&#43;qB/GrVvI80qJKuxP4jWgEd1c&#43;YqY/vCke2luNUhk42LUWuW6286LYs0y8E9qWPWBA4SSCQP7DNZmlKr7M3PL4qMx1mSyavcfvrPyxF/dcYNQG/1G2mSK6WIM/cGgzNUx4NHlyVXWWcnBKN9GqcGdB939a0A8U0Y/6Iv1rqdak2aEre1chox/0YfWur1Lnw&#43;&#43;/n5a2ETeFLlFtPm71oaidh31leDohcokYrrNV0SQQ7/vYFZVRnO&#43;efL61f0qL7RJvPSs3yGJ2gGr1jY6lEwMSN5dZGh0Jhjx0qOOPBqwsUm0butO8qtDMI5O1S8GovLqWOOgAki&#43;TNPsFQ3A3gH604/6ultdguF3LmswLuoybYdke0M3HFczLotxfuDNc/Kv3a1NYa7hbfCgaIevan2sgaFA5&#43;Y1oBlQaB9kYutw7t7mrEZkgkUu7Knuc1pnHeqt0EML56YoA8P0b/j3H1rqtR/5F&#43;X/AHa5XRv&#43;PcfWuq1H/kX5f92qAn&#43;H3&#43;tT616fqX/Hq30rzD4ff61PrXp&#43;pf8AHq30pMDi4P8Aj5P1rqLb/UL9K5eD/j5P1rqLb/UL9KyGNem/xU56b/FWgg/iqWOov4qljqQA9KLb/j5FB6UW3/HyKkstap/x4Tf7tYtp/wAeyVtap/x4Tf7tYtp/x7JWhBoH7w&#43;lQ3HUfWpj94fSobjqPrQB/9k="
     data-sizes="auto"
     width="3264" alt="Sign with arrow pointing left label Cake and one pointing right labeled No Cake"
     loading="lazy" />



  </a><figcaption>You don’t have to ask to know where to get the cake.</figcaption></figure>

<p>Over the last few months at work we’ve been updating our development workflow. It started with a large project to migrate our code repositories to Bitbucket and move all support clients onto new testing infrastructure. With a large number of support clients, we had lots of updates to do, so we shared among all the developers. I did the first few conversions and then wrote up a set of directions for other developers to use. The first few times other people walked through them I got corrections, complaints, and updates, and then after a few edits there was silence.  Every couple of days I noticed another batch of clients got migrated without anyone asking me questions. The directions got to be good because no one struggled with them after the first few corrections. But I didn’t get, or expect, compliments on them, but they achieved their purpose.</p>






<figure class="figure-right">
  
  <a href="/wp-content/uploads/2017/05/AHC_7646.jpg" target="_blank" rel="noopener noreferrer">
    
    

    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2017/05/AHC_7646.jpg" alt="Switch for a microwave labeled No fish, no curry." loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2017/05/AHC_7646_hu_10b8c7581ac02c4b.jpg 680w, /wp-content/uploads/2017/05/AHC_7646_hu_ce57d4a856878697.jpg 850w, /wp-content/uploads/2017/05/AHC_7646_hu_c13cba0259bc9d12.jpg 1020w, /wp-content/uploads/2017/05/AHC_7646_hu_8b0b32f71aba0eb2.jpg 1360w, /wp-content/uploads/2017/05/AHC_7646_hu_bb6ae47ed2e358bf.jpg 2040w, /wp-content/uploads/2017/05/AHC_7646.jpg 2606w"
     data-src="/wp-content/uploads/2017/05/AHC_7646.jpg"
     src="data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDIBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAI4AgAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/ACjvRUgFcJ1CjtUtRVLH1AJrMAxSgc1dFk5GRS/Ypv7tICrRVr7FJ/do&#43;xSf3aAKtFW/ssn9yk&#43;xSf3aAKtFW/sUn92kNlIBk0AVaKCMGitQA9KiqWjFAFCpR0qKpR2oAKZMSGjx/eqx2qK4&#43;4n&#43;9SpgbsMv7pfpU/mmuR1zxIdHjhVYwSV5Jp1j4sFzorXrwHcrbdvrT9kB2Ako82uVTxP9pOLaHcw6jOMCrV34gjgtLeYREtJ8uM9KPZAdB5ntR5tcw/itY02&#43;Sd&#43;ce1TQ&#43;IreeQR42uWAx9aXsgOh8yobqT90aUcgVFdf6uoAzF5U0mKlT7lBoAioo70VoBVxR3pCcUeW8nfFAEw6VHP91P8AepPLeM/e3Us/3I/96ikBh&#43;MJLNEtxMmZQOp6CpdGudNTw3JI0bbAw3fWtHWPD8OsrE7OQ6&#43;o4NS2Xh63t7D7I7lg7Bm/CukyMoPpJdjaRytI2SfLP51qST6elpaMIGf&#43;6velj8MW0LM1vK8RJJ49&#43;1WptESS3gSOVo3i6NWQGXcRaXd&#43;ZIfMiYYLD61DDdaPAQFVwUbeD64rQPh5Gk/4&#43;X5x5me&#43;KfJ4XsyylSRkYJ9aYE8PiexZeQy445FX3lE1uJB8oZeM1QHh&#43;1jjKqRgsGxjpir04AiAHQVlVNSsP9XR2o7UVmBF3oqQ4qOtAKoRH&#43;9SjjpSUUAS1HP9xP8Aep/Qf3qZJ91P96ikBpRf6oVMKhi/1YqYUAS9qKinuFggZ2GQKrG9ljiDm3YKemaALvFLVVbklwrxMu71q12oAKiuf9XUtRXP3KzAq/wUnalorQCKipCKjoAq0d6KO9AEoSop&#43;qf71Sg1HP1T/eopAacP&#43;rFSioYfuipq0MilrUnl2Yx/eFRG&#43;uZEX7pAHpVm8tvtls0LNtJ6NWeNIuAMCbIHvigC6Lya4miEu3g/w1o1l2WmyQSb5HzWpWZqFRXJ&#43;Spaq3P3KAIqKQdKXNAAelRb/apcik4oAo5oqKpAaAHDrST/AMH&#43;9RUc/VP96taQGxD/AKsVKKhh/wBUKyNRuL1LzEQYRY6ikZG7R5iVzNjd6gZ2EwbHOKha71E30iNuWJehAoEdZ5maK5OS71NA&#43;C27qox1pY9Q1Qp&#43;8DDp2oGdhVW8&#43;5Rp8kj2itIcn1pbn7tZ1TUqJn&#43;H7tFSO4AwBUdABRRRQBQoozRQBKHqOfrH/vVJUU/WH/erWkBsQ/6oUpAPUVFEeBzUtIyHhV9BRsT0FMorMQ/Yp/hFG1fQUzmjNaDJQABgcCorj7lSZGKr3P3KzqmpDRQOlGaACjNB6VFQBQqUdqiqQUATZFVb2aOHypJDtUGpaiuLeO8j2TLxWgCDXrMcCQVKNatv&#43;egrN/sGy/uH86l/sGyx0b86DI0f7atv&#43;egpf7Ztv&#43;egrN/4R219W/Oj&#43;wLb1b86f7sDX/tm2/56Cj&#43;1bb/notZH/CO23/PST86P7Atv&#43;ekn50gNj&#43;1bf/notSPdw3KgRyDNYf8AYEH9&#43;T86tW2lQ27b0dt3uaKpqaXao6KKzAKKKK0AoZoqKpR0rMCTNLmoqB1oAlqWoqK0AlqTio6KAJaOKiooAlo4qKigCWjNRUUAFFFFAH//2Q=="
     data-sizes="auto"
     width="2606" alt="Switch for a microwave labeled No fish, no curry."
     loading="lazy" />



  </a><figcaption>This is from a hotel, but every office should probably have one on their microwave. I doubt the person who created those labels hears about them much unless someone broke the rule and microwaved fish in their room.</figcaption></figure>

<p>It’s easy to complain about directions, but it’s hard to do them right. There is another set of directions at work that I know are bad: because everyone complained about them and then gave up on the process they explain. I need to try again, but frankly it’s hard to get up the motivation to replace the current silence with either new silence (if I succeed) or complaints (if I fail).</p>
<p>Usually when I’m writing up directions the outcome doesn’t matter much. If your Drupal Cake isn’t the shade of blue you were hoping for, or my colleagues have to ask a couple extra questions while migrating site configuration, the world will not end. But there are people who have to write important directions that can save or cost lives.</p>


<div class="gallery gallery-cols-2"><figure >
  <a href="/wp-content/uploads/2017/05/IMG_0066.jpg" target="_blank" rel="noopener noreferrer">
<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2017/05/IMG_0066.jpg" alt="Street sign with a suggestion that the road narrows and up and down arrows." loading="lazy" />
</noscript>
<p><img class="rcf-image lazyload show-if-js"
data-srcset="/wp-content/uploads/2017/05/IMG_0066_hu_547a6d1bac244cf8.jpg 680w, /wp-content/uploads/2017/05/IMG_0066.jpg 711w"
data-src="/wp-content/uploads/2017/05/IMG_0066.jpg"
src="data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDIBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAKYAgAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AOJ3k8YpPuPRv9qPn/jrIA61VuYqtb/akIyKYGZQKtJZZkNSpa7M1p7UzKtSxSeXQbfy8lqi8zmtANOKYcc16N4J0wPC9xcQhkYfKxryyEkyCvWND1A2PhbMjrk8JzTEdLp9xAspgt0O3mtPtXJ6JqlsJWAYszcCunByAa1MgooooAi70UUUAeDHApnmH&#43;JKTPmOvpVmQBY/l5rzDqKvmCl8zPajy0P1ojjfft7VoAe9HmVKV7YqIxbfamBFLJkVRbIyavGPY9RSjf8ALitDMjtpcNn0rrIdeSfTI7FYsPn71clHFirNm7LOhX7wNaCPQvC9vcNqSNt3RJxXo3auM8Lt5UCGNS5PLV10cvmJ867aZkS1FRRWoBUWaKKAPDRs2Uh6fLUUUg2VJIcDNeWdxH8&#43;alG9Eqr5tSxzeprUzLII&#43;7UcmD3qLPO/NRyk/wANMCR0zjmkkAjFRxk96lkTzI&#43;tAFVP9ZU0caiTIqH7tSxSCtDM6Xw9r8mm3So7sUJxXo2oaqkGlecH2u4yua8aSfa4YdQc10Gpa2L7SljZ281QMDtWgjufD&#43;q3N4CJpFat7NeW6FqkNmtuWkO7d81emRSpLCkiNuVxTMiaos0ppK1A8Cz/AHKl8w&#43;X89RRkZ&#43;WpHkHFcB1CnZ5HvVaM/vKfJJ81Rx/6ymBbj/1nPSrDiPFVvMxR5vNAEvl8/7NRE&#43;W&#43;3tUygykAVpQaTG9nLJI/wA/8qyqVfZs1p0vaGFJ&#43;86VGMocVaa1khk2HpUJ4fmuhO5k1YAmec1Zj6VWQ81L84pga2iWf2u/jiXscmvWrdRDBGgxwK8Zsr6SynWaM4cV1nh/X53vZZLubcm3ha1p1DI9CzmqF7qcdmcTfLWDYeIvtepSfPthTpWX4l1eOe4haIlsA5oMjzmKWpZG96oCSpQc965jqLXmUmfnqLPFR&#43;bzQBf/AOWNRCT56IjlOtD/AH6AN3Q5Lfzv3v3v4c1fky32gr9xpAOK5hTIzoY&#43;GFb9vfONMdHjXf6561w1cLUdT2lM6aVWxLrptVgjCkecB2rmwd5&#43;7S3HmNP5ku4lumTSA100qbp09TKrU9pUJRGm&#43;iSos&#43;9BkrpMyUGP1qUExt&#43;7fGaoZ561KJaDM1LTU3tUMaqNx/iqKW4MsmSeaoCTNLk76BGVxSx9ahjPz9al6c0GpLJ7VFR5n8VAkzQBatzxQd&#43;&#43;ogfSpR/v1mBNbSEMykdjWhqsEC2VkYS6vIvzc1mxY8z5nA4IrVltp73T4p0ZPKt&#43;Gau3DVDmqGbNuS2iySTzTYzmOpZpE8tU3BvpUSD5DWdX&#43;IaUiPJzUkY31EetSxSYrI1LNrp/2sOS&#43;3ZVJv3UpjznFa&#43;nyoFm3Ln5azXjBYyVnTASOTmrIxJVHPNSxE&#43;taGZmC2OeKkkGBirUY8vqKLmLf86VmBn/AD0sfvUvl0VoaEsfSl71EM5q1CORkUAWr21hhtIXXcHZcmtjTT/xRl5/vioPEEP7mzCjkxDpV3T7WT/hELhNnzM4rMDlgPapY5O1X4tLkPWr8WiR96AOdkBJ4FWrazaWBnwcqRXTR6Xbp1TNaFtp24bUiwPpQBzFlYXBScbMZHFWP&#43;EbuGiUhhz15rrRYxRDLN8390Uo2f3dtAHEt4Wu8npj60h8NX/y7F/Wu74el6VoB5dGQ52mpcbm9hU8WkyMmd43VeisMR7D1rMDClhMh3JUUdpKZOhrp4rGOP8AgqXyIwfu0AYMekTycrV&#43;HSHVQZG6VsxDA6UEUAJexRzmFl52IBWhbvEujPHu&#43;dj92qEcdS&#43;XigBI4qniiJbA60QQs7BVBJPQCuqs9Ni0u2W5vFDTN/q4/wDGgClbabHFB51z1/hX1pJJ2b5VARfQUtxdPcOzNwewqEGgCM9aD0o/jokj&#43;StAI8nPFSeZioshO9Eh44oAwRjP3alAqKpPMwOlZgL9x6Mb&#43;goT94m81JHgCgAjDD71LUfmc1IOaAAVMiF2CgEk9qSIEnAGTXYaJpEdjb/2pqGFC8oh70AGmadb6PZrf3oHmkfu4zWTe3815cNLI2M9B6Uatqb6ndPIT8g&#43;4PSs/PvQBL5tL5pqGjzK0AlEn7yp0jkuH2RKW&#43;gqnHJzWlaaxcWPMGwfUUAJPoWoonmNbvs&#43;lUGR0OGUg&#43;9en&#43;F9ZbV9OkWYKZlPTFch4jvyl5NBJbRhl6NjFZgcIKlxxRx/DRQAbMd6KM0UAFSxjNRV1Phjw/JqM4nlGLZOWJoAu&#43;F9BTH9oXoxbpyN3eq3iLWv7QuTHCcW6cKoq74o1&#43;KNRptn/qU4bbXHmWgCXNGareYc1J5taAS&#43;ZSZFR&#43;ZUeTQBL5nNSebVXf7UZoA6jwzrqaLdu8isyMO1J4m1ez1WdZ4EKt/FmudjO7vUUtAFWiiiswCpY&#43;lRVJH0NAGjomnDU9QSBm2qTzXoWu3Q8P6GLa0TbkbciuL8H/8AIaj&#43;tdX47/48V&#43;tAHnrOXcsxyT1ptFHegCTyxR5Yp/aitAGeWKPLFPooAZ5Yo8sU&#43;igBoT3pJI6eOtElAH//2Q=="
data-sizes="auto"
width="711" alt="Street sign with a suggestion that the road narrows and up and down arrows."
loading="lazy" /></p>
<p></a></figure></p>
<figure >
  <a href="/wp-content/uploads/2017/05/AHC_7708.jpg" target="_blank" rel="noopener noreferrer">
<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2017/05/AHC_7708.jpg" alt="Hazard sign saying the grave yard is fragile" loading="lazy" />
</noscript>
<p><img class="rcf-image lazyload show-if-js"
data-srcset="/wp-content/uploads/2017/05/AHC_7708_hu_ed4a1589f256e8d6.jpg 680w, /wp-content/uploads/2017/05/AHC_7708_hu_64d33dd2505eb4f5.jpg 850w, /wp-content/uploads/2017/05/AHC_7708_hu_80ab996d572a84d3.jpg 1020w, /wp-content/uploads/2017/05/AHC_7708_hu_7c516c64b92c82f0.jpg 1360w, /wp-content/uploads/2017/05/AHC_7708_hu_526509e624d64b40.jpg 2040w, /wp-content/uploads/2017/05/AHC_7708.jpg 4928w"
data-src="/wp-content/uploads/2017/05/AHC_7708.jpg"
src="data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDIBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAFUAgAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AODqX5P71RE/7NReZz0rhAtHpUVAl&#43;T51q1FbebHlGFAeyuVcGg1fGnSyDO8YFSx6PI4yZUAoH7KqYx8yiOQit46EVHM6DNN/sJ&#43;oYflR7IX1aoZHmSUVqjR2OcSA4qNdFlmlxHIDRYPZVDOorVk0GYEIZADS/2BNGOXOPpQHs6hk0VsHRP3RPnrmsiUeXKY/wC7QHsiGQVF5dWeCKj8v3oD2RftLdrpsAqq9y1WntdMR9kl4u7vtFY80sixJEr4DfexSR2yJyeT710/u6YG&#43;LTQyOb5vyqGQ2FtJttrgyJ9KyvJB6CprKxkvJ/IhX5&#43;tZHThv3dQ6HTriG4t5bYyKmedzVeuIbf7FbJHMr/ADYLLWTb6BfwxyqYQd3fNXrWwv7W3WLyFYqcjmtrGtW3/Pwv6gsTWWQMNCcZx1FRwah5Vk9xMyhcbUXHWoY7fVtzmZA8bjG3NSyW080KxvYqdvC/NWhnen/DF01o1gMzgt5zYHHSpLGJYZLtVcKy85aqUttqvlokMIjVD0Bp72upOsmIBvkUBjmiwXLxnULEZSsjMeGWqFpq7XV5dW7gFEzzinWljqMEKxtArbTnk1JLYXpRxDaRxl/vNmiwXpmJLexhmHbNYtzcwGUnD/lW7daHd28Ekkijaoz1rnSMnpXN/D/iCxPs6n8MikukH3Ub8qikvVk&#43;4jLVmQD0pYrczHEceT9KPaHMJ5eY0kzUn3xVK2uTJa7Ch&#43;WpBIe1aVQLUe9D96tjw5L5esp/tZrDWQr97mr2kSbNWhf1aika1DvdUQvApV3U5/gqhHPLEyszSsPpWleHdZn7/wDwDrWXvfy9myfbXccI8ysY&#43;HmDE56U9mkZYx5su7ruxVbZv283NXre1&#43;0QbfNlTaf4qYivE80rkGeVc&#43;1Hnyq3&#43;ulOD6VpLp7BQvnN/vU3&#43;zx5m/zW69KB3M9rp5JAfMlX8K3ISViRd&#43;/NZ7aeST&#43;&#43;ardtF9nT/WlvrQIq69LjSZ/pivOQM13niaTOky49q42zs3u3AHyRj7zVy4lGtIitrGe5m2ryvc1pfbLbTIWhtwHuOjN6VHcagltG1pZjgcNJ3NZBO1ix5J71l/DNRsYjAfAqPHNSR4o48z/dp/8ALs1/5eCo&#43;wcirFu&#43;y5gf0cGq&#43;PM708MFZBtOAQc1khM9LkYtZ5RtpIzmsoXtznaHPpytA1WxmtYlW58twBkU7&#43;07Yf8ALzHXpJnFYc97MjhAw46/LR9vuQ23cuPpU8Wp2Gz57iJmofVNN/57R0XCxF/aF052o4XA7ikk1KcD5HXP8XBqb&#43;1NO6&#43;dHR/aenf89Y6LoCrb391JLy64&#43;laom6ZPNZ8mpWPl/u5Yw1N860ZELXgRvXNFwE16WP7Oiu2EY/NXL3l8GTyIF8qId/WtPxNcwSW8UcMyuQc5BrmSS/4VzVaprSEIOflo&#43;59/mgSelB92rlOgjHWkfO&#43;jIjOM1I&#43;C4PtWw6gCUD5KlSTjmo8x&#43;2&#43;jIHL1kaAX56UeZ8lJ5g3&#43;1L3/ANmjUNACOeQaX5f41NJG3LBRSGQd&#43;tGoaEw&#43;5xSqMkCooXlaTYEJzWlH5dmN8o3Tfwp/jR7NmWhJHbx2Sedc/wAX3V9azbyVp5N/QdlouZ5rh/NlOSOg9KjTMnVK1DQT5zjNSOjrHwvy/wB6l8v/AGamRcx7AKy9kBn8o&#43;0c1auPKeCJx95eGWkMYLlVqubeTJ5pD/dlC4J&#43;0NzVrefISqlx/wAfDVZ/5d0rqMgVdzbj1pzkvFg0kfSj&#43;A0ARo5B21JHM3WoU&#43;&#43;adH0/GgC4qrhpMc0MiyAMV5pV/wBU1C/6ugDUUi00xriNRvxwT2rDS5ln3SO3znvW3c/8gI1z1r/q6DMn8s7d3mNmpklcxjnpTf8AllSR/wCroAk89/MXmh53V&#43;DUX/LRaJf9ZQA6IkAjPfNLLIdlNjok&#43;5QB/9k="
data-sizes="auto"
width="4928" alt="Hazard sign saying the grave yard is fragile"
loading="lazy" /></p>
<p></a></figure></p>
<figure >
  <a href="/wp-content/uploads/2017/05/AHC_8186.jpg" target="_blank" rel="noopener noreferrer">
<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2017/05/AHC_8186.jpg" alt="Sign with pictures of news articles talking about people&#39;s death" loading="lazy" />
</noscript>
<p><img class="rcf-image lazyload show-if-js"
data-srcset="/wp-content/uploads/2017/05/AHC_8186_hu_a3599e273db27c0e.jpg 680w, /wp-content/uploads/2017/05/AHC_8186_hu_71336015cea90fae.jpg 850w, /wp-content/uploads/2017/05/AHC_8186_hu_7dccc54835317a50.jpg 1020w, /wp-content/uploads/2017/05/AHC_8186_hu_cac62a93ff7dabfe.jpg 1360w, /wp-content/uploads/2017/05/AHC_8186_hu_9120a0c0743d3868.jpg 2040w, /wp-content/uploads/2017/05/AHC_8186.jpg 4928w"
data-src="/wp-content/uploads/2017/05/AHC_8186.jpg"
src="data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDIBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAFUAgAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/APORFGejZ/CjyUjO/DflWt9nigOEUn3xUy2rTruEYQfxZNHsgMMhJBnDflS4&#43;To2PpWo9ptbaDlfapNkfAORjtij2QGNhMfcbP0oQhzzn8q3fsIZxhuvWoJLFYZd&#43;M0eyAypGb&#43;CM0eZK4CkNittUJyPLC04MkbhHjG31x0oAwtzb&#43;AaI3lEmfLO6twpEgyq9/SjfHIvEYUf3jQBmSPIY/uNuqt5csp2bOfrWwWdI&#43;ApGe9EJhRi5I30AZX2Obo0ZpTpr&#43;XnbWqQQhkYYX&#43;9UTXDBF6FaAMo2n&#43;xUf2BP7laabyTgFvwolWQJ8pANAE89xfQjywI2b&#43;Emm21&#43;Zf3dzIA/wDdWrUsCX107iRFiX7q96yY9NkgvZJivmbeVCnrQBrrdQxwM7OyovX5eahm1jTAiESlmX1WqVzqLXml3CPCYyrDtXP&#43;WD3oA7eK/sboeZFPsx14oN7Z3MhH2peOOlcvajZaS4FN0iDzdTiV1ZY2bGaAO0CW1wcLOPl9sVFcCIBUknTK&#43;1a3k6bp6hDKvmnsTV0eG7G&#43;j8/efmA6GtDM5Z5osbPOjzU4itmjT96lXtZ8Lx2iI1oS5b72as2&#43;jvFpj&#43;ZbqNqferM0M/8As6Fo/wDXRt9DUcenxZ2sV56UxYBbgnIq1pjpIhMo3bW49q0MyKWxhhbZNKoRv4RUBsFl/wBSgKJ707VZxDLvYZ9KqDUrgWcrwbBz3p&#43;zF7QWdktVB2e3BqCaKOUBwG47Zqa3ummtNssA3d2FPuLqKGHEcQLBetZGpi2Fjczn7TLctGo4wR1pZjeQahm3jdx6gV0lyIYrcICqn2Oahtrtp5dihVC9GNAGHK91LYzLcx7csO1UbXTftNwEWug8QOV0tsNk7xVGwjeMJIPv0AdFpOk20bG1aJS7L/FzWwui2ohkiARWOMEDG2sSzllTVbWZz1&#43;WuyEZjJ&#43;Vdz960A5f/hE/7Sv8tcNtQfeNdbbwJpumxRIC5Hy7iapW80OlmVricMx6DNNh12G5URhfmz3NAF&#43;XHyecu3d05pJ8SWcsYfhlNVbm6FyiDH3feqN5d/YECH5t/vQZnN6npN7GwxPuibsvWtLTraaG3UBRhv71JNfojBvI&#43;b3ao11ESuMR/d/2qf7sRrpo6T2266Vd3tXOXtrBaSSIoDRb63Y9UnC/6sY&#43;tY&#43;pkTAO6qEZvm56UVApmfsS4V7eJiuf7tZLWWrxynZCTGvc9607&#43;aCCIrpzgSdyaqWF7rt1J5Csh&#43;tZGps6lbhpMoyqnRTTYbNbOBi8wbdzXPW80yWRWWZmf&#43;51p1sdRnt5Fwcdi3agC1r9xD/ZbFTkhh0qvptwl1CH3MuBWJeC7j06VpeBvAqjY6hJbyEeYduPWgDsLfVvtd0sC7t0TDbXqaAyQxk9dor53iv5orrzo5Crbs9a9e/4TKz07RrSS4cyTPGDtWgCte6Nc3mpyswbG7rurQt9D8tdyzBZfrXNt4xS7vn2pLFu&#43;7V6PXhEOsjN7ii5man9l3kc2ftPy0&#43;SOBpf9JfzJU&#43;6orMk8UL5BCIzP71h3Pi62jk8xYpDNjHTii4WOlvHt5SqmLnpxVFI7W03rGkxc&#43;vNYdv4rtFm3tHKX9KbL4vhN15iRPt&#43;lFwsdHHdr5Z81GX2rO1NfMtleEvsVvmFZp8ZQ&#43;aN9u23vxW3ZeILK8snYxZXoMigCjaOruqsiqnqVq08ojk/0cqP51hXuoXT3JigiJTttFVo9QkhuN94Qu3&#43;HvQaHYWGgW9hbskrh2boxpIVhWeWFpPkqvKl2IvNumICehrMuYUMDzW103m9dpPWgBfGEMKabGInXaZBmuPubK2WRVhn3Ajnit/UopbvTV86QJjB&#43;YVhCyiQ/LfRg0AVZLVI&#43;fM/SnwebdXsEayZAOF3VbfTQRl76Iili0pGIkjvowRQB0Za/SQbba3kYDG6tK1e9dVkaGEkEgqe1crb2lzJN&#43;61Bdy&#43;9XBo&#43;pSx7jfhVJ9SK53h7mntDWu5ryKUyRQwEkdAazJI7ma5VTDbqyAsR65qJfDWoO&#43;1b8H8TTpPCl/BIrPeDc3fJo9mP2g7/ShN5f2W3DleDSQRXsMflvaQYJ&#43;8cc1EfDl75hIvlyO&#43;TUM2lXcaEyX64X3p&#43;wF7QuXH2sIQ1lARjrxRokDz6bL5akuGPyisdYnLYOoqfxrovDtgyQFhcj724YPWtKdP2ZmQ2K3a3bqw2dssKjvdGjknMkzlm&#43;tdDcLPL/rI0Ct3FUjpMhOfNZv9mrAgu72WeQRynchPTpWhC8MDR7bZOPWsab/j4H1rU/iSgCPxVeGXSXTykA46CvPIl3zIp6FsV3PiX/kGv&#43;FcPb/8fMf&#43;8KAO7/sO0gsx8u/cveuYeyWKeYK7BV6Cu5n/AOPOP/dFchN/r7igC1pemx&#43;S0u9t1dEkPnNEjMdgXpWVpn/Hm1bVt/rU/wBygCm&#43;uS28xgihjVRxmlu9ZnNvESq5Jxmsm6/4/wBvrUl1/wAe0H&#43;8KAOkvYBHbgqcF0BNcPrAeF9okJUjODXe6h/x7R/9cxXCa9/rV/3aAObPU12&#43;l5h0CIocFm5NcOetdxYf8i/B/vUAbETSzW6RtKfrikRX08PIJWk9mpbXolOvf9Q1AH//2Q=="
data-sizes="auto"
width="4928" alt="Sign with pictures of news articles talking about people&#39;s death"
loading="lazy" /></p>
<p></a></figure></p>
<figure >
  <a href="/wp-content/uploads/2017/05/AHC_8175.jpg" target="_blank" rel="noopener noreferrer">
<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2017/05/AHC_8175.jpg" alt="Caution sign that has a wave above to swamp a stick figure person" loading="lazy" />
</noscript>
<p><img class="rcf-image lazyload show-if-js"
data-srcset="/wp-content/uploads/2017/05/AHC_8175_hu_aaea64bc7486f574.jpg 680w, /wp-content/uploads/2017/05/AHC_8175_hu_bb66b3aa9ffdb5f9.jpg 850w, /wp-content/uploads/2017/05/AHC_8175_hu_19f8f963146ba7a7.jpg 1020w, /wp-content/uploads/2017/05/AHC_8175_hu_f5aaef2b0a77de6c.jpg 1360w, /wp-content/uploads/2017/05/AHC_8175_hu_bb6caec3b2708aa7.jpg 2040w, /wp-content/uploads/2017/05/AHC_8175.jpg 4928w"
data-src="/wp-content/uploads/2017/05/AHC_8175.jpg"
src="data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDIBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAFUAgAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AMGwt/3CEfL9DUqvAZJGlwjr/Fms6GW6ihaNE/3TTPsk0RcyTBt3J4zigDSuIkvYs/aUSNfvc1HpYjimeOJ02dscViXc8EEA8uN3GfmAzg1e0y5Mt3GRAIvlxsYUAbtwGiiK2zPvPU&#43;n41iGTVrZfNMok3HoGzXSI0szlJGiSPHJrnZZHh1MxwTxyxg9F5IoA14tXg8hIp4i0zDoOtRwzO7vhSPRW7VmXsU5uElQou0ZI6GmWF2ttetJeSySK47dBQBsSXTxlVZSx/2akilSSTeVIP8AOoluLGeT91IQD6UQ7JZngjYkddxHNaAaQWKWNtxKv/CPWsy4SB5NssXzjpmmBmt5y4y2OOucUkU6XMhSQkH&#43;93oAQiGNcybQzcciobqQqojUIR6A02eCMSrG43j&#43;8xqS0sbO1umuZdzMB8qk1mBE4P2RmZNprDvL&#43;W0RXa2JQ/xEda17mS5mdvLQhT0qo85SDZcEOO&#43;aAO7bSFSP5Gz&#43;FUW0yJY3&#43;Zg3euy8uL&#43;7UPlQGXGwZoA49NJjCKSfk64205dLhkuPOwxzwMLXZSLbwbfOKKtMe5sYVDK429uKAOWfQzMrIiNg&#43;tMj8Kon3YDG7dXBrsJZ4oofNjw3y7uKy7LXIblpRcgw7TxmgDIj8Mpkl2eTH941LJoloiYmiXb0wOpremvIYYC&#43;7Ib7vvVK2aK4l815FL9kz0rhx2O&#43;r7GtKl7Qw7XS4YL4tawgDoQetX4tMxNM7KEJHy4FX7m33gvE22Ve/rVeO&#43;mChDHukX7wpYHH/WAq0vZmXJoEhYES9Tk8UP4aZzvDnPtXV297Y&#43;V&#43;9IVx1qRLuynB8mZeOtd5kch/wi5OMyNUi&#43;Fyr8TZ9c11CNbzKXSZWIqS2SKeUh5ApoA5JvDiqdhuSM/w1HL4Ngkh&#43;dzmupu9HWW8WQMx29PSpXRgMODxQBjHUzdIrqWH0HFQ29xKJpZUO70JqKKe0tbPDF5G9qjNzbQRF2V2zztUdK0AztZ8STLcCD7HI7qOSBxU0OqQmFGnjkHoBTxeJIS3kGTA4Pp9atWMcEs6gogyMkZrMCBbssTiSTb/AArT42YnZtOOuTVqSOLeZEjU4rHuicSSLKQw6gHgUq237sC1Ms1/epa&#43;YSqDc5HYelNtrVGvWnMogigOMd2&#43;tSeGb&#43;1kjK5zMT8zN1NQaqE&#43;2SFQnthv6V8y6k3VdOR2ryM7UPE5tNaIDko3EeeB71uQ61aXkbO0qRuhwGHeueutCW7aK6mikBX&#43;Ijg/hSRWkSMywg5/iCDmt/Z0tPZgzplaPU4XMUsaEcM2ajh00achaKZpg/3q5K8h1XTYjeQTK0O7lD1/GtHw/r8&#43;o72uv3aKPpXt0v8Ap4cxZne8siGiLxqzcBqss&#43;p2Uf8AaCTbvVDzWDcSNcai00d8zlG&#43;WNjRHd6rFc/vg0kDn7pPStTM7DTfFVxcTILpREv5VsS6/DGR827PTjrXHQxx3koIUll7YqS4njtw28jcOlADb/UJICMWbFF&#43;9tqxDqNpcvE8w8uLb8yjqPrVRLK4kj2iViOrc5NTBo1hZVstzL/EeN1aAXJJLH7QDanzImHPGMVJJbx3NsJ4FEUoO3isQyTRBnMMkcSjJ4rPHiWVvNEY&#43;QcKSOazAv5mtGd3umdefkI5NJFsvYy5lEI776yE1AvcRs8wLk/cNdKZ7a5tjC6xA45oAjgsrKHD212DN/dUZrRgdDIgljTf/fI61UtYkjYG3Masy8cVBLHIZOZdzr1wa5cTgaeI2NaVX2Z0k12I08oFM1mQXFtb3DJIAHfn61jSWq3Uq&#43;bcOv40&#43;C2gs7vzJJjMq9A1Z4HA/Vwq1faE&#43;rXdm4e1lwjP901mafo8giZiw8rrknis3W1&#43;03byhWZP4QvarenzTrpnkEMVP8JNdxka1jotrNC0lu4My9fT86fFZmWXZJIhPTaKg0&#43;2MUL&#43;TvTP8JNLbLOJS6xtEU/iPOa0AlIfT7giNuV/KoGeS5l3SAN7dKsSRSSv5jZLd6jdI/4j5f1rMCJUvLSVpo4pFRhjaxzVO91u4Db50VUi6KvU11sxeZOFBPvWVc6ZaX29ZV2y&#43;q0e0NDGPxAubhdi6f8Autu1vlzmqEeoreXSrbqhJPKbelOufD2oadIds5ELnjitfTNHtLa3MsQLzn7zUGZC&#43;nrPcI7w7ZF/iAqVdMieZeDndyc8mtr7HNNaqYnUnvVeNF&#43;1JAQyyH2oAhYGBzGh2/hk4qza6a0iTShhtAzuPetRraxsbdri6bcFHJrnbrVLq7VlsAsdv2J60ANwRKqso2Z&#43;Zu9On0dr262QTDb1ABrL0cu&#43;rlL64&#43;TOeDXaSX2j6fF5vyhwOCD1oA5r/hHLsS&#43;S77S35VO&#43;itZweZKQdvcVZi1CXUrp5o5QIwOB3oJeOGRHnDg8qCe9AEUCKsRJLFj90AVbS4jht9jRMZccA96ZaLdSRPIdoRV65qkJpILlXHzY7kVoBNNd5mGx8N3QCpriAlFeR12t1FQxXqCRzhNzH0qFhJcM80LHaBgqeRQBRg1S5vLMMzlWbuD0q9pBfz9jSMx9TWJpn/HlHW5pP/H4KzA1dejNvHb/ADlw/XNMilSKyAWIZPU5qfxN/q7SqY/49V&#43;taAM811WUIdu3pitO1fNmJWAZ/U1k9ritS2/5B34VmByfi6/uP7PkIchV6L2rho/Et/FZ&#43;Wj4Fdh4t/5Bs9eb/wDLD8aANGO9ucPJ5zbutS2&#43;pXFzIBI5Iz61Ti/1DfSl0/8A1w&#43;tAHrejRA6dGe&#43;2rkMEbsAUHPGaraL/wAgyL/dq7b/AOsX60AUZrKaQvbpeSRxqeijrTDbeSB87Nj1rQ/5epvrVa471oBRMiybiY1znGa1NJuF8qWDyU2&#43;tY6/xf71aGk/6yWgD//Z"
data-sizes="auto"
width="4928" alt="Caution sign that has a wave above to swamp a stick figure person"
loading="lazy" /></p>
<p></a></figure></p>
<figure >
  <a href="/wp-content/uploads/2017/05/AHC_8104.jpg" target="_blank" rel="noopener noreferrer">
<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2017/05/AHC_8104.jpg" alt="Caution sign that suggests someone might right down a hill after rocks. Or maybe fall. It&#39;s not really clear." loading="lazy" />
</noscript>
<p><img class="rcf-image lazyload show-if-js"
data-srcset="/wp-content/uploads/2017/05/AHC_8104_hu_ae78573f23149723.jpg 680w, /wp-content/uploads/2017/05/AHC_8104_hu_da90c47b53e115de.jpg 850w, /wp-content/uploads/2017/05/AHC_8104_hu_cb73d32a4af769c0.jpg 1020w, /wp-content/uploads/2017/05/AHC_8104_hu_7d013aab86ecde44.jpg 1360w, /wp-content/uploads/2017/05/AHC_8104_hu_8652e1c8617fc707.jpg 2040w, /wp-content/uploads/2017/05/AHC_8104.jpg 2681w"
data-src="/wp-content/uploads/2017/05/AHC_8104.jpg"
src="data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDIBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAIkAgAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AOjiR8ZHapMv61SjuvLRkU/eo80&#43;tH7wC7ub1qUMPUVSjZfU1KGT0NH7wDd03VHtyI3OUrolvreUAiQVwoK&#43;9XrG48mUA42mj94B1v2236bxVS5mt/4ZlH41yfi7W20TTftEKB3Y44rya48canJclzLgf3aAPd3lB5DriopJU/v15VovxBkhIS9XchrsdN8T6ZqsgjhfEh/hNAG1JJ/tVFJJ/tUSYqI9K1/eAHmf7QqMyH&#43;8KTFIQKP3gDN656iguo6kUmADnApHZWfcwFH7wDHjqUVVz71LHJWQFoVL5lVQalrQC1HIKlB5qiOtWfMOOlFwLdyLe70&#43;SC6QOuOM15ZqHh20WZmwQWPyIvU13Ooal9nQRRDfM3RfSorDSMN9qujunbsf4fpXm4nHezNaVI8/Xw7JEd88TpEf4hzius8L6VBaagkgBclflat0aewZxI2&#43;N/4TWdGG0O/XeCbZzw39yssLj71DWrSOrNFQpOJEDKcqehFLmvXucoGoqlqImmAVFIaCaiJoAwsmpI5MVFQKyAvxy1L5tUAalGTwKAL4krP1TW4bILbiRfPfgDP3frWVr3iKLSYfLibfcH9K89nvZbq5eaWQs7Vm/wB4B7BpNlCALh5BNK3JfOcVrV5t4M1&#43;O1la3u5CFb7pJr0dWV0DKcqehr53F0qlOod1Id71DPDHdQvHIm5G71X1DUYdNi3SHc38KDvVSx8Q2l4/lP8AuZf7jcVzKlV/iI1IILibRboW07F7Vz8jf3fat9XDqGU5B5rGfUdN1SeXT94Mg6&#43;1V7O8fTbj7HcPujJ&#43;ST&#43;le7gcU/4dU5qtI6LPvURNIDkZBqPNescoHNR85qQyVVub6KBOOXoAzOf7lJv9qteZ/sUilWBZlAA6k1mBHGe&#43;2sPX/E0NlGbe1IM5&#43;83pVLxH4pjgD2dg3zdGf/CuGeRpGLMxJPUms/4hoS3FxLcTmWWQkk00HHNRUZ966EZmlpNsb/U4IeRlq9stBHBaxwKwOwYPNeNeGryK01iGWf7gNemS6Kl8Td2l/Kgf5vlPFeJmdvaanVhibWdQ06xQXFyUaVPujvXnM93f&#43;INbEtpGQQflKjpXT63oltY6VNJdTme5f7hY1r&#43;EtNitNHikWLEknLMRXNTqU8PT9oa/xDm7My6Q8r3Nk5vn4Vx0NdNYaK0mlsLskyS/Pn&#43;6a22t0mYFlBI9RU4GBjtXLVxftNUaeyOdsL2S1mOn3hIcH93J/eFackoj70mo6al9Fzw4&#43;447Vhi4mjVrWbIuE4Gf4x616&#43;BxxzVaRdub7ZxmsiaYsc1VmkleXBzSeZXp3ucp05RQCScAda4TxP4pIL2Nk2F6M4712YileORc8lSK8k1W2ktb&#43;aOdCrbiR71l/EqGhRZixyTk&#43;tJRRXTYzCiiigCVTyOa9n8OK0PhmEx/vG2ZrxQHmvVPA2rK2jSRzNgQ8/hXk5nS/d3OnDFm00a71O&#43;N5qbfKp&#43;SH0rrERY0CqMKBwBWUqtf3MN5b3DCBeqjvWvXhVantNDqpBRRUdYmoZxWfqmmrfIWQ7Z1GVar9FUm07oyONZWlDRuuy5j4YH&#43;L3FZkshiJzXWa9p6yW5uYm2zR/Nn1FcbqzlFimBwHAJFfQ4HE&#43;0OarSNr&#43;2JR/yyas7V9NGvWzMI9lwgyG9fatjbajnI/GpRd2sacOi16VSnz6o5Tx&#43;eCW3meKVCjp60zPFeieI9NstXQy2rqLlV6D&#43;KvPpIWt3MTjDCinUAgzSjNGOakrUAFd58PwEF1NOcQKvzCuDr074eQwzaRcKcMxOGFcOZ/wC7mtL&#43;IdRa6ha3NjI&#43;mlWMY&#43;70rO0DXr3UL2aC6tihU8NirUunTWDRDS0jjQtmTNU08V2cerfYfJxJnaWA714CpKz9mjuOpqKgNuGc9aK4zUKRmCqWPQdaR2VELMQAOpNYE9zc6zM1tYhhbp/rHH8X0rWjRdUyZDq2qfad1vbtiHpJIf5CuL1mWS4fEYxEi7VFdNNaOvmW5gfyx0xWLdabIi/Jn5q&#43;hwuG9mcNWqW4rN5PkaQtVm30oo/74Eir1tNaxx7IwzP6kYqUs8h&#43;T/gVdxkVo9NTzfMTC7fSsrxN4Z&#43;223221TEqfeUd66LzHjH3fyqWN5SMPIMHtWdSnbVAeMMhRirDBHBFJXd&#43;J/D8cm69tE5/jVf51w5ifJwjce1aU6vOAyut8C6hLbXFzBEcuyZVfcVymxgfun8q0NBujYazBcYIAbDVlioe0pGtI7K1vPEc&#43;sx/aUlW33fNgY4pniLxFp1nfD7JaIblD8zMKuax4o1C01GFYLcPA&#43;MEDrWpf&#43;F7HW7MXDwiG4kXOR615Tq0qbhOodOplaB48S8uRb3iiN2&#43;6R0ruJLhIbfznYbcZzXlZ8CXNjcrPLcIsMZyTXVxyT6iscTkpaJwB3asquFpVal8OFOr/wA/Ca5u5dYn2I5hs1&#43;8f71T2tyLTMcBCqvTb3qtOIl&#43;ReAOML0qtsKSfIa9XDYX2ZzVaprtrLIPmjVx3yKjlmtJBvMC/gao70hDA8s3rTWbyx83zfQV1GRf36e/KRlaVks9m4b13elJFo0oOXZdn1rQj0iAqCZcAe9Z&#43;zNfaFECyMf&#43;sk&#43;X2qPfZZx5zflW9Hb2scJ3CMe9Z9xLp9kVmlVWOfuqM0ey/wCngiGDT452zHISp6gjrUDeHrTTZnlmSMwvzhl6Vqx6raTDdCMD2GMVn6hqErYgceZG/rXLUwznsOlUK9t4etJ5fM8uBoyOPlqy3hbTxy1vFWfZ3T6XcCGRs279G/u&#43;1b7TxAKWkyD0ryKzrKpY7v3Y1dNjVEURRFU&#43;7mpm3Rrhwo9Bmq15fw2MBlkbGPuj1rFi&#43;039wt3cuVX/AJZxDt7ms6WFq1dw9r7MnubK91KYvOpWBPuxg9fc01bG7Vwu1tp6Y7VYLzbtu4/nUZW8U/LMa9qlhqlM4atUhexlQt8jGpfs7YVvLNPLzoMmYk0G&#43;fy8b23fSur94H7sgliYxZ2HPuKijhY9QanjvrnOwsGHuKsi8YDov5UfvBGdYGWVWSaVlzzy1XyzAbFY7cdc1j2//H1LWqv&#43;r/CtTMhZ5duwMStV7hbmUp5Ywi9c1YP9KsD&#43;GgCqouEw0KKVX72aR53Mw81U9tpq8/8Ax5y/Wufj/wCPgfWgCzdSCR/u5QjBFRLLPAqqoWaNfu7mwR9alk61l3X3q4q9KMtzanNluSSS5m8y5YM4&#43;6o6LWlEXEQbdlqybf7v41qf8u1bUIKOxm5ssAyP8&#43;aPNffTYv8AULTU/wBa1bkknmvmk8wb/nwtQn76fWkueq/WgCcywrzxVG51e3iqC7&#43;6awLn/UvQB//Z"
data-sizes="auto"
width="2681" alt="Caution sign that suggests someone might right down a hill after rocks. Or maybe fall. It&#39;s not really clear."
loading="lazy" /></p>
<p></a></figure></p>
</div>

<p>Even if your directions aren’t signs that hopefully save lives, it is worth trying to do them right. I’ve already admitted I’m still working on getting this right but here are a few things that help me.</p>
<ol>
<li>Write down the steps as you do the task. Include pictures or screenshots when they are helpful.</li>
<li>Do the task again following your directions to the letter.</li>
<li>As you edit them (because you will find mistakes) add tips about what happened when you made mistakes during your previous attempt to help people know they are off course and how to recover.</li>
<li>Repeat 2 and 3 until you are sure you have removed the largest errors.</li>
<li>Watch someone else follow your directions and see where they get confused – if the task is complex they will get confused and that’s okay for now. Ideally this person should have a different experience level than you do.</li>
<li>Edit again based on the problems that person ran into.</li>
<li>Repeat 5 and 6 until you run out of colleagues willing to help you or you stop finding major errors.</li>
<li>Release generally, and wait for the complaints.</li>
</ol>
<p>This of course is an ideal. It’s what I did for the migration instructions, but not what I do most of the time. Rarely do we have the time to really work through a process like that and edit more than once or twice. You can shortcut this process some by limiting the number of edits, but if you don’t edit at all you should expect people to complain to the point of giving up.</p>
<p>One last thing. I’ve often been told the first part of writing good instructions is mastering the process. I disagree with that advice pretty strongly. Most of the time I find that beginners write better instructions since they are paying attention to more details. Once I master a topic I skip steps because they are obvious to me, but not to people who need the instructions. That’s why for step five you want someone of a different experience level, someone more junior to help make sure you didn’t forgot to include the obvious and someone more senior to point out that you made mistakes.</p>
<p><strong>Welcome Piscataway Students.</strong> I noticed the start of the annual bump in traffic from the Piscataway LMS and figured I&rsquo;d say hello. A few years ago one of the teachers started to assign this article, so I see a bump in traffic here when they post the assignment.  Tell them I said thank you, and that I&rsquo;d be interested in hearing from them about how this article gets used in your classes. I hope this year goes well for all of you.</p>
]]></content:encoded> </item> <item>
      <title>Fixing the Expert Beginner</title>
      <link>https://spinningcode.org/2017/04/fixing-the-expert-beginner/</link>
      <pubDate>
        Wed, 05 Apr 2017 22:55:39 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=246</guid>  <description>I’ve worked with expert beginners, and I think it is a curable condition. It requires three things: mentoring, training, and pushing yourself in ways they can see.</description> <content:encoded><![CDATA[<p>I’ve been reading <a href="http://www.daedtech.com/additional-information/about/">Erik Deitrich’s</a> blog a bunch recently, <a href="http://www.daedtech.com/how-developers-stop-learning-rise-of-the-expert-beginner/">particularly two pieces</a> <a href="http://www.daedtech.com/how-software-groups-rot-legacy-of-the-expert-beginner/">he wrote last fall</a> on how developers learn. They are excellent. I recommend them to anyone who thinks they are an expert particularly if you are just starting out.</p>






<figure class="figure-figure-right">
  
  <a href="/wp-content/uploads/2017/04/IMG_0006-e1491432722625-300x219.jpg" target="_blank" rel="noopener noreferrer">
    
    

    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2017/04/IMG_0006-e1491432722625-300x219.jpg" alt="Failed Sticky bun" loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2017/04/IMG_0006-e1491432722625-300x219.jpg 300w"
     data-src="/wp-content/uploads/2017/04/IMG_0006-e1491432722625-300x219.jpg"
     src="data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDIBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAF0AgAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AMEXYBEua7HS/GkdjbCN5mV2X5VrzXRpradDBeO3swpZSLW88xnLxp9zIoA9ei8fyY&#43;9L&#43;VR3/jUz26qWcbWB&#43;YV5bJ4sYJiOFVcflVSXxLdXzLE6qPda0Mz2yTx4YPLG8HK1yWr66t5evdPIcf3QK86h8QXNqzKcPnoWq/LrcptFkYJn&#43;7QaGnd3EN5nYO1cvfRfZ1d6kj1a9lb93bq30qvfS39yrRPaMPoKzAyRc&#43;bcbKtCL95Vq00YpLE8kUiZHzFhU2qGGzCNaKXb&#43;LIpXQ7FXB9KsWU0dpMZ5Yw6r/Ce9VoRPeRuWkSIj&#43;FqqvBO6uFfeSOgNQWaEmqx3UpeKyTHPAqXR77fqIh&#43;zInP3hWJbi9tN2xCAww3FamhiRbsyyDoK0MyTXJd&#43;pyP6HFQabF5moRf71Vr&#43;XzLqRs/earui/8fe/&#43;7WZoWZrWWP8AfqFXPqcUT3wntvLfZuH8Wa2z4ZuUZ0uYZUTvlTWTJ4VnaYi33OvuK0Myt5di8a/6RtfHpmosWq/8tx&#43;ApLvQryxfEsMgHrtqMWak4CsW9KPah7MD9k/56k/hUcksHTexFWodKlmbAhYfWum0/wAHWYg8&#43;8lA/wBmsvamvsij4Q0z&#43;1LpmXeI07DvXoX2e00yNSVQkddwrnrCaLTneLTNqxAfM2e9U57y81lJLZDtfpurmq1faHTSpezJtW8TWjXRgARgTjgUDTdPlKPbDezjO09Aa4660W50y9Vp8vk/erRttd&#43;xuAi1n7N/8uzXQ3oNH065uWt7uILJ3ZTUWqfDp3uYn0m4xE33snkVg3GtXUdw10CFz2rV03xy/wAoZSCv61p&#43;9RnVpUzn9Z8P6vpEjpIkrxD/AJaKODVXTJ5BDJvOOK9m0vVrfW9P2yIp3dVcV5n4ssP7M1GZY4fLhflSK1p1faHL7I5NzmYnPetPSpfK3vWOTkmr1vL5cFaiPoO9&#43;Idu4KW&#43;mByf74qDS9RuNTvElmsba3tVb5224NbmqabpegrGwt4zu7kVx2q6u9xKYwoWEf3eBWVXE&#43;zHSpe0PSJLTRr&#43;3yscLoB1wK8k8YQWFjqvmWNuiKO4qpP4gmsJPLglfB/hzWRqd/LdyB5D8prL2vtDqpYb2ZZt9StpJA91hAO4q3d3FpdxZt7o/Q1iz2ULW&#43;5uBVqz&#43;zWlmrPGHkP3azNSuI1RvLjdsnrWnY3EensBInzHvVCQp80qYD/3aktr0SHZcpuWkaGnr0tjf6WVV8SqN2QK8quJ5ftBXkYNer2gtovmS33g9mp8&#43;laXNvnewQt7U6VX2ZzezPLYo5bgYdzitOxigt5A7jNdbLaaNJGQsPlv/smubu7eKIny33LWntfaGlM1Y9dFvjYdn&#43;7VybU7bVbMreKZWQZUiuHlJz1otr6WCQBTweKPZBVK12MXUjRptTd0pplxHXUXdjpq20UlyzxvKM7hyKzpdLtWH7m5jce9dVI4T6M1fTo9QtTDcXJA/hJNcTL4EuQJZYdQ3RgZxXfy6Us8gmkdtnpVpms4bQwoq8jFL2QUqp5Xc&#43;GLS3tcF2kudpbdniuQu4yqmM9RXoOs2N5bytJCS8OeCOSK4jUdrTENgNXNUpHVhqplR6pLHC0DJ5g7CrVur3CJvOz2qpGAk53YWpfMUP8AeyPrWZ03NSK3tv45DUv2Ow/57HNYct4iJtU1U&#43;2Hf1peyD2h2MSCKP5bgN/dzUW&#43;689S86eT/EM1yh1SXpk1ImobkILcmj2QHdrbaQLQ3DOqg9TXBa7atBfE2uZLd&#43;dwqGSeUxsnnNs/u1NaarLDGI2CsnvWq0MzF3MjYdT&#43;VWba0N3IFRMe9a8moW0nzG2Xd64pFuB/yyQAmj2grl&#43;PTojYJBeSiQ54/wBmuR1W0NjeOisQn8OK7HTtPlmcYw&#43;eSSelb8nwxuNc0/7V5vlTD7qkcEVrS9octV0j1jULySR/LiHyL6VWhspJELmn6FcxX0DscF1NaEr&#43;Q&#43;7&#43;A10nMYs4FvEWYA&#43;xrzXxHDbz3buqbG/2a9G1YlwSv3TXCanplw0hkAJFZGiOHmtpCTVJ7SZDkA1081qQ2COaqSh4&#43;qflWRtcx/KUR/vBzUPlx5q/cvu6jFUJP92g19oQ3EY/5ZqapuGj/gbdV3ds70hnYnqKDK9QrhrmUYSM1astH1C5k&#43;41PivGj6AVfh1q5j6Sba2/dnLVq1ST/hGryH558BPrTobKNJMM61XuNVurkY8x2HvSW8crdc5rT90Z0va/8vD0Dw1YW/mpIzbiv8PavSYLwKgVQAAOgryTw2lzHIOTivSLHzPKGazD2ZiW17JoOtSRnPlOa7OK6ivrfcpDA9qwPEdjDLbSSEfPGchqwdJ1O4hYBW46UGh1d1bOhyvzJ/dqoqRlvmX/AIC1aVpK00IZupp81ujc45oA5fUtCguMyRja9cxc6cbZyHjLD6V6G8e3oarSW0UwO9AaXszX2h5hdWlq&#43;cLg&#43;9Y81gmTgV6Rf6TbZJ21iy6fDnpWRr7Q4c6YaP7KJ7V10ljED0qeK0ix0oHaBxX9jy&#43;lSx6NKeoruY7KInpV2LT4fSgRxFtoUnpW9pug8jeK6m2sIfSta2tIh2rUy9oUNM0eOIDit&#43;KPyo6bCgTpTqZkf//Z"
     data-sizes="auto"
     width="300" alt="Failed Sticky bun"
     loading="lazy" />



  </a><figcaption>I am a good baker but this attempt at a giant sticky bun failed because I am not an expert.</figcaption></figure>

<p>In short he argues for a category of developer he calls the Expert Beginner.  These are people who rose to prominence in their company or community due more to a lack of local competition than raw skill.  Developers who think they are great because they are good but have no real benchmarks to compare themselves to and no one calling them out for doing things poorly.  These developers not only fail to do good work, but will hold back teams because they will discourage people from trying new paths they don&rsquo;t understand.</p>
<p>I have one big problem with his argument: he treats Expert Beginning as a finished state. He doesn’t provide a path out of that condition for anyone who has realized they are an expert beginner or that they are working with someone who needs help getting back on track to being an actual expert.</p>
<p>That bothers me because I realized that at times I have been, or certainly been close to being, such expert beginner.  When I was first at <a href="https://www.afsc.org">AFSC</a>, I was the only one doing web development and I lacked feedback from my colleagues about the technical quality of my work.  If I said something could be good, it was good because no one could measure it. If I said the code was secure, it was secure because no one knew how to attack it. Fortunately for me, even before we’d developed our slogan about <a href="/2016/07/always-make-new-mistakes/">making new mistakes</a>, I had come to realize that I had no idea what I was doing. Attackers certainly could find the security weaknesses even if I couldn’t.</p>
<p>I was talking to a friend about this recently, and I realized part of how we avoided mediocrity at the time was that we were externally focused for our benchmarks.  The Iraq Peace Pledge gathered tens of thousands of names and email addresses: a huge number for us. But as we were sweating to build that list, MoveOn ran out and got a million. We weren’t playing on the right order of magnitude to keep pace, and it helped humble us.</p>
<p>I think expert beginnerism is a curable condition. It requires three things: mentoring, training, and pressure to get better.</p>
<p>Being an expert beginner is a mindset, and mindsets can be changed. Deitrich is right that it is a toxic mindset that can cause problems for the whole company but change is possible. If it’s you, a colleague, or a supervisee you have noticed being afflicted with expert beginnerism the good news is it is fixable.</p>
<p><strong>Step 1: Make sure the expert beginner has a mentor.</strong></p>
<p>Everyone needs a mentor, expert beginners need one more than everyone else. A good mentor challenges us to step out of the comfort zone of what we know and see how much there is we don&rsquo;t understand. Good mentors have our backs when we make mistakes and help us learn to advocate for ourselves.</p>
<p>When I was first in the working world I had an excellent boss who provided me mentoring and guidance because he considered it a fundamental part of his job. AFSC’s former IT Director, Bob Goodman, was an excellent mentor who taught me a great deal (even if I didn&rsquo;t always admit it at the time). Currently no one person in my life can serve as the central point of reference that he did, but I still need mentoring. So I maintain relationships with several people who have experiences they are willing to share with me. Some of these people own companies, some are developers at other shops, some are at Cyberwoven, and probably none think I look at them as mentors.</p>
<p>I also try to make myself available to my junior colleagues as a mentor whenever I can. I offer advice about programming, careers, and on any other topic they raise. Mentoring is a skill I’m still learning – likely always will be. At times I find it easy, at times it’s hard. But I consider it critical that my workplace has mentors for our junior developers so they continue progress toward excellence.</p>
<p><strong>Step 2: Making sure everyone gets training.</strong></p>
<p>Programming is too big a field for any of us to master all of it.  There are things for all of us to learn that someone else already knows. I try to set a standard of constant learning and training. If you are working with, or are, an expert beginner push hard to make sure everyone is getting ongoing training even if they don&rsquo;t want it. It is critical to the success of any company that everyone be learning all the time. <a href="/2017/02/are-you-moving-forward-or-backward/">When we stop learning we start moving backward</a>.</p>
<p>Also make sure there are structures for sharing that knowledge. That can take many different shapes: lunch and learns, internal trainings, informal interactions, and many others. Everyone should learn, and everyone should teach.</p>
<p><strong>Step 3: Apply Pressure.</strong></p>
<p>You get to be an expert beginner because you, and the people around you, allow it. To break that mindset you have to push them forward again. Dietrich is right that the toxicity of an expert beginner is the fact that they discourage other people from learning. The other side of that coin is that you can push people into learning by being the model student.</p>
<p>Sometimes this makes other people uncomfortable. It can look arrogant and pushy, but done well (something I’m still mastering) it shows people the advantages of breaking habits and moving forward. This goes best for me is when I find places that other colleagues, particularly expert beginners, can teach me. Expert beginners know things so show them you are willing to learn from what they have to offer as well. They may go out and learn something new just to be able to show off to you again.</p>
<p>Finally, remember this takes time.  You have to be patient with people and give them a chance to change mental gears.  Expert beginners are used to moving slow but it <em>feels</em> fast to them.  By forcing them into the a higher gear you are making them uncomfortable and it will take them time to adjust. Do not let them hold you back while they get up to speed, but don’t give up on them either.</p>
]]></content:encoded> </item> <item>
      <title>Why I won’t wear your free t-shirt</title>
      <link>https://spinningcode.org/2017/03/why-i-wont-wear-your-free-t-shirt/</link>
      <pubDate>
        Mon, 27 Mar 2017 01:40:57 +0000
      </pubDate> <guid
        isPermaLink="false">https://spinningcode.org/?p=237</guid>  <description>A few years ago I was traveling to DrupalCon with a female colleague who was attending for the first time. The all male team had attended several times before that and she had always liked the interesting variety of t-shirts they came home with, and was looking forward to finally getting something for herself. Only she didn’t.</description> <content:encoded><![CDATA[<p>With DrupalCon coming up I want to talk about a question I will be asking vendors giving out t-shirts: do you have women’s shirts? I’ll then request a men’s large (since it’s the size and cut that actually fits my body). Given <a href="https://techcrunch.com/2017/03/26/sex-and-gor-and-open-source/">the reminder</a> <a href="https://docs.google.com/document/d/1tcwuuip9qAMtGNir7_aD1zhWubEkisNnkG3n7CHFPbM/edit">this week</a> <a href="https://www.drupal.org/association/blog/a-statement-from-the-executive-director">about</a> <a href="http://buytaert.net/living-our-values">the problems</a> in the Drupal community around misogynism this seems appropriate topic.</p>
<p>Close your eyes and picture a Drupal developer (go ahead I&rsquo;ll wait). I can&rsquo;t say who you saw, but too many sales managers for technology companies just pictured a man or group of men. They want those developers to think well of their company and to wear shirts with their logos. They will buy, and in a few weeks give away, t-shirts for the developers they just pictured. They will forget that our community is strong because we&rsquo;re diverse, and gender is a critically important form of diversity for us.</p>
<p>Thinking about this through t-shirts isn&rsquo;t a new or original idea. The first time I ran into a form of this discussion was this <a href="http://headrush.typepad.com/creating_passionate_users/2006/12/tech_tshirts_ar.html">2006 blog post from Kathy Sierra</a> (which I probably read in 2007, so I&rsquo;ve been thinking about this for 10 years). I was a big fan of her work at the time (and was until <a href="http://geekfeminism.wikia.com/wiki/Kathy_Sierra_incident">she was driven from tech circles</a> shortly after), and the support she got from women on the topic was almost as influential on me as the attacks she received from men for daring to talk about her own body. And it&rsquo;s not just tech: if you listened to the entire <a href="http://seedtoshirt.tumblr.com/">Planet Money t-shirt saga</a> you hear the NPR staff complain about the same problem.</p>
<p>For me usually the conversation starts something like:</p>
<blockquote>
<p>&ldquo;Do you have t-shirts for women?&rdquo;</p>
<p>&ldquo;Yes, do you want one for your wife or girlfriend?&rdquo;</p>
<p>&ldquo;No, I’ll take a men&rsquo;s large.&rdquo;</p>
<p>[confused stare from salesperson followed by them giving me a t-shirt.]</p>
</blockquote>
<p>Like many tech conferences, there are usually <a href="https://pantheon.io/blog/drupalcon-shirt-pouf-practical-swag-storage-solution">lots of chances to get free t-shirts</a> from various vendors. For anyone who hasn’t thought about it, that t-shirt is meant to make me and you into walking billboards. It puts their brand in the minds of people in your office, neighborhood, and anyplace else you go. And it works. After I got home from New Orleans last year I wore shirts from several different hosting companies everyday for a week. Since we were talking about new hosting relationships at the time, I got questions about the company on my shirt each day – we do business with two of those companies now. So giving me a free t-shirt is a request for me to advertise on their behalf which could easily pay for itself.A few years ago I was at DrupalCon with a female colleague who was attending for the first time. The all male dev team members had attended several times before that and she had always liked the interesting variety of t-shirts they came home with, and so was looking forward to finally getting something for herself. Only she didn’t. Very few vendors had women&rsquo;s shirts at all and none in her size. Even worse, DrupalCon itself didn&rsquo;t have a t-shirt for her because the men who had checked in before she arrived had thought their female partners would like the design and had taken all the woman&rsquo;s shirts.I should have known this was a risk for her since it&rsquo;s not like the topic was new, but I didn&rsquo;t and while I felt bad about it, that doesn&rsquo;t undo the insult. Instead of making sure she got to fully participate in our ritual, we allowed her to be left out. Several years had passed since the Kathy Sierra triggered discussion and I wrongly assumed we’d made progress as a community. Oops.As part of trying to apologize to my friend for my own cluelessness, and in part to try to do something to make our community better, I took up asking vendors with t-shirts if they have women’s sizes. Not because I want one for someone else in particular but because I want other people in general to have the same chances I have. And I am not willing to advertise for companies if they are making our community worse. Anything we do that makes women feel less welcome makes our community worse.Over time I’ve had interesting conversations with people who have said both yes and no.</p>
<p>The people who say yes are sometimes interesting. Usually they are just confused because they never thought the issue through. Sometimes they cite Kathy Sierra, sometimes they cite a similar experience to my own. Usually we&rsquo;ll exchange thank yous and I&rsquo;ll move on.</p>
<p>If they say no, the conversation goes a bit differently. I am always nice, but I don&rsquo;t let them off the hook. I&rsquo;ll ask &ldquo;why not?&rdquo;  With one exception the answers are unfulfilling.</p>
<p>The most common answer is “I don’t know.” While the salesperson is sure no offense was meant (as if they would tell me if one was), I generally offer to wait while they call their boss to figure out why they don’t want women to advertise for them (no one has taken me up on it yet).The next most popular answer (usually offered right after saying &ldquo;I don’t know&rdquo; didn’t get me to go away)  “It’s too expensive to add those sizes.” Typically this is from a person who gives out hundreds or thousands of t-shirts a year. This just isn’t true at that scale. Most vendors are still going to order enough shirts to get over the same price breaks they would have with their current order, and every t-shirt they give a woman is one they didn’t give a man. The <em>only</em> way for this to really be true is if they end up giving away more total shirts because more people want them, which is the <em>whole point</em> of the exercise. The time a RackSpace employee gave me this answer I just stared at the woman, in a woman’s cut RackSpace t-shirt, and said “Really”?  The next year RackSpace had women’s t-shirts (this probably had nothing to do with me, but it’s nice to think it might have).I’ll also sometimes get “We didn’t have room to pack them.” I usually get this answer from smaller vendors who may not have as many to give out as a company like RackSpace or Pantheon, and are therefore concerned about bringing shirts and not finding a person to take them. But I’ve gotten it from big companies too who will admit shipping five or six boxes of shirts. Either way, sorry, but no, avoid insulting potential customers by splitting your packing space.The final answer I hear is “Women don’t want them.” This is the go to excuse from men who don’t want to think about why women don’t participate in anything related to technology. I even got that response from a man planning a Drupal Camp when I pointed out that none of the women on the planning committee had shown any interest in having shirts at all – his daughter being one of them. When I commented that maybe they didn’t like shirts that didn&rsquo;t fit a wave of nodding followed: we had women’s shirts made.If you are attending DrupalCon, or any other large event for that matter, please ask everyone giving out t-shirts about women’s sizes. If they say yes, take whatever you want, but if they say no I encourage you to think hard about if you want to advertise for them. And draw them into a discussion on the topic. If you are bringing t-shirts to DrupalCon, or any other large event I attend, please bring t-shirts for as many different types and sizes of attendees as you can fit. The right ratio <em>is</em> a hard problem to solve, and I know you have limited space. Ask the conference for an estimate of attendee demographics and make your best guess. If you guess wrong that&rsquo;s okay, apologize, and try to do better next time.Do I think refusing to take free t-shirts from tech companies will suddenly solve all of our the gender issues? Of course not. But it does force people into conversations they aren’t used to having, and it makes at least some stop and think about ways we create unfriendly atmospheres for women in technology.</p>
]]></content:encoded> </item> <item>
      <title>Are you moving forward or backward?</title>
      <link>https://spinningcode.org/2017/02/are-you-moving-forward-or-backward/</link>
      <pubDate>
        Sun, 19 Feb 2017 20:29:53 +0000
      </pubDate> <guid
        isPermaLink="false">http://spinningcode.org/?p=227</guid>  <description>In technology, communications, or any other job that involves one of those two things you are either moving forward or moving backward: standing still is not an option.</description> <content:encoded><![CDATA[<p>Every week I try to ask myself: What did I do this week to make myself more valuable? Am I moving forward toward a goal, or further from it?</p>
<p>In technology, communications, or any other job that involves one of those two things you are either moving forward or moving backward: standing still is not an option. You are either learning new skills, trends, tools, and concepts, or you’re falling behind as other people build new tools that drive new ideas and trends.</p>
<p>I read lots of advice that says to plan your career two or three moves in advance. That is good advice, but I don’t think it’s wise to trust your gut that far out. The technology landscape changes too fast and too dynamically to believe you know where everything will be in three or five years. On the one hand I think it’s important to deepen my skills for the path I want to be on, but at the same time I try to broaden my skills into areas other areas that have things to teach me. In the back of my head there is always plan B and C, just in case plan A doesn’t come together they way I hope. In part, because I’ve never been able to stay on plan A very long: life always intervenes.</p>
<p>When I was 23 (and sure I wanted to be teacher) I was advised to read an hour a day in my field, and that it should not just be reading about the kind work I was already doing. At the time I was the new kid in IT of a <a href="http://www.afsc.org">mid-sized international nonprofit organization</a> doing whatever no one else wanted to do: which is a great way to learn a variety of things. I didn’t really know anything yet about how to have a career – I had a job, and I liked my job, but couldn’t envision a career path.</p>
<p>But I took that advice to heart and tried to find ways to constantly learn about things I don’t know. I read books, listened to podcasts, and taught myself new skills. I learned about communications planning, economics, corporate strategy, algorithms, and a variety of other topics. The ideas I pick up from those sources help me think about technology more creatively, and helped me understand the importance of making sure I build tools that are useful not just cool to me.</p>
<p>For several years I also taught myself a new programming language every year. I taught myself <a href="https://en.wikipedia.org/wiki/Active_Server_Pages">ASP</a>, <a href="https://en.wikipedia.org/wiki/C_Sharp_(programming_language)">C#</a>, <a href="http://www.php.net">PHP</a>, <a href="https://www.python.org">Python</a>, <a href="https://www.ruby-lang.org/en/">Ruby</a> (on rails and off), <a href="https://en.wikipedia.org/wiki/R_(programming_language)">R</a>, <a href="https://www.haskell.org/">Haskell</a>, and <a href="https://en.wikipedia.org/wiki/JavaScript">JavaScript</a> because I heard other people talk about them as important or interesting. I have used five of those professionally to create actual software people used. And the others all forced me to see programming differently and helped me be a better developer. I don’t force myself into learning whole new languages annually, it was too broad and prevented me from deepening my knowledge of individual languages and the ecosystems I work in frequently (although I’m probably overdue to teach myself something like <a href="https://golang.org/">Go</a>, <a href="https://developer.apple.com/swift/">Swift</a>, or <a href="https://www.rust-lang.org/en-US/">Rust</a>.</p>
<p>The biggest thing I’ve learned from all these different inputs is that I need to live in constant fear of getting behind, outmoded, and sidelined. That fear keeps me motivated to learn more and push myself harder. By the time I retire I cannot imagine I will still be paid to be a full-time Drupal developer, I doubt that’s what I’ll be doing five years from now. Certainly by in 30 years Drupal, and the web as we know it, won’t look anything like they do today and I will be doing my job very differently. This is <a href="http://theoatmeal.com/comics/running">the blerch</a> that keeps me motivated.</p>
<p>So every week ask yourself: what did I learn this week? Did I move forward or fall behind?</p>
]]></content:encoded> </item> <item>
      <title>How to create a good trouble ticket</title>
      <link>https://spinningcode.org/2017/02/good-trouble-tickets/</link>
      <pubDate>
        Mon, 13 Feb 2017 04:03:55 +0000
      </pubDate> <guid
        isPermaLink="false">http://spinningcode.org/?p=222</guid>  <description>If I can’t reproduce the problem, I can’t promise you I fixed it. If you can’t reproduce the problem, you can’t check that I’m right.</description> <content:encoded><![CDATA[<p>This week I was working with a new colleague on our account team. As with all people knew to working with technical teams and bug tracking, she’s having to learn how to create good trouble tickets for when clients report issues. This is a challenge I’ve seen played out in every place I’ve ever worked: developers want detailed tickets so we can dive in without asking 16 follow up questions, and people creating tickets don’t actually know what we want and assume we know how to find and fix the problem.  And so I&rsquo;d like to try to offer this explanation of what we&rsquo;re looking for and why.</p>
<p>At the most basic level I need to know at least three things to find and fix a problem on a project (either a web site or some other tool I&rsquo;m supporting):</p>
<ul>
<li><strong><em>Where in the program is the problem?</em></strong> This is usually a link to a sample page that has the problem.</li>
<li><em><strong>What happened?</strong></em> I need a clear explanation of what went wrong. Is there a picture missing? Is the text format wrong? Is there a big red error message at the top?</li>
<li><em><strong>What you expected to happen?</strong></em> What is the picture of and where exactly was the picture supposed to appear? What formatting was supposed to appear on the text? Did you do something right before the error message appeared that helps me see that message again?</li>
</ul>
<p>These things are part of allowing me to reproduce the problem.  If I can&rsquo;t reproduce the problem, I can&rsquo;t promise you I fixed it. If you can&rsquo;t reproduce the problem, you can&rsquo;t check that I&rsquo;m right.</p>
<p>Developers will often say that if you can&rsquo;t give me the step to reproduce a problem I can&rsquo;t fix it. But in my experience sometimes a problem is actually really hard to reproduce, and you need a developer or a professional tester to actually figure out those steps. So it&rsquo;s okay if you can&rsquo;t give me perfect directions, but give me what you have.</p>
<p>If you find yourself writing a ticket that doesn&rsquo;t say more than “Search is broken” or “Blog post didn’t look right” the problem better be massive (think big red error message level). As an account/support team member that may be all you got from the client but someone has to fill the gaps – and developers are terrible people to have fill those gaps.</p>
<p>As a developer there are several reasons that&rsquo;s true.</p>
<p>First, rarely do developers get the luxury of working on one project for an extended period, and when they do those tools are large and complex. So we probably don&rsquo;t have every detail in our heads at any moment. If we could store all that information we wouldn&rsquo;t need task tracking systems, you could just call us and tell us about a problem as we&rsquo;d call you back a few hours/days/weeks later and say &ldquo;fixed&rdquo;.</p>
<p>Second, we&rsquo;re terrible at finding mistakes in our own work. Like everyone else, we need editors. If I could see the problem you are reporting, I would probably have fixed it, or at least reported it to you so we could open a task to get it fixed later.</p>
<p>Third, we probably don&rsquo;t spend as much time in the project documentation as you do. So if someone needs to track down the original design to check for a discrepancy between the design and what&rsquo;s happening a developer is probably going to be much slower at this task than you are (or you will become soon).</p>
<p>Also remember your developer probably will not look at the problem today unless it&rsquo;s mission critical to the client. So they need to be able to figure out three weeks from now what you were talking about.  If it just says: &ldquo;search is broken&rdquo; and I run a search in two weeks and everything looks fine, you are going to need to tell me what&rsquo;s broken about it (maybe a result is missing, maybe it&rsquo;s formatted wrong, maybe it&rsquo;s working perfectly but the client doesn&rsquo;t like the results).</p>
<p>Even with all that context, I know it is intimidating for many new support or account team members to crack the code developers use when talking. We over explain this, using technical terms, and get annoyed too quickly when people don&rsquo;t understand us. And we often forget that teaching by analogy is helpful.</p>
<p>My new colleague is a baker, and so as I was trying to help her understand what I needed to be helpful on tasks I switched to bread:</p>
<blockquote>
<p>If I came to you and said “my bread didn’t work out, please tell me how to fix it” how would you start?</p>
</blockquote>
<p>That helped her make the connection. Just saying my bread didn’t work out, doesn’t tell her enough to help me do it right next time. She’s going to have to ask several follow up questions before she can be helpful.</p>
<ul>
<li>Did it taste wrong or look wrong?</li>
<li>What kind of bread was it?</li>
<li>Did you follow the instructions or do something different?</li>
<li>Are your ingredients fresh?</li>
<li>Did it rise enough?</li>
<li>Did you knead it enough?</li>
<li>Did you set the oven to the right temperature?</li>
</ul>
<p>On the other hand if I come to her and say:</p>
<blockquote>
<p>I tried to make sourdough oatmeal bread over the weekend. I followed the recipe closely, but my bread turned out really dense instead of having the bready texture I expected.</p>
</blockquote>
<p>Now she knows there was a problem getting the bread to rise. So we can focus questions on the yeast and other details of getting air into bread. Yes, there are still several things that could have gone wrong, but now we know where to start.</p>
<p>Frequently new support staff are intimidated by all the technical things they don’t know. And too often developers brush aside new staff who don’t give them the information they need and just say things like “Oh I’ll figure it myself” instead of helping their colleagues learn. Part of the solution is to help people understand that the first set of questions aren’t actually technical. Baking isn&rsquo;t the right analogy for everyone, but it helped in this case. And hopefully next time I&rsquo;ll do better at getting to a better explanation quickly.</p>
<p>Also, my bread came out fine and I&rsquo;m taking her a loaf this weekend. You are welcome to try <a href="https://docs.google.com/document/d/1Uz-sVFubTgV2wFR8yRklUIsRLvzIT63V6puTFjyUk_o/edit?usp=sharing">my Sour dough oatmeal bread recipe</a>.</p>
]]></content:encoded> </item> <item>
      <title>Yes I wear pants and other advice for working from home.</title>
      <link>https://spinningcode.org/2016/11/yes-i-wear-pants/</link>
      <pubDate>
        Sun, 27 Nov 2016 21:06:46 +0000
      </pubDate> <guid
        isPermaLink="false">http://spinningcode.org/?p=171</guid>  <description>Yes, I wear pants to work even when no one can see me.</description> <content:encoded><![CDATA[<p>I’ve worked from home part-time or full-time for the past four years. The first question I’m always asked when people learn I work from home is “Do you wear pants?” The answer is yes, I wear pants to work even when no one can see me. And frankly I don’t quite understand the desire of large numbers of people to work without pants, but it led me to realize that it might be helpful to share a few tips for people starting to work remotely.</p>
<h2 id="wear-pants">Wear Pants</h2>
<p>Okay, it doesn’t have to be pants, but get up and get dressed in clothes you don’t mind being seen in. The clothes we pick communicate, not only to other people but also to ourselves. Pick clothes to help you take your work seriously.</p>
<h2 id="set-a-routine">Set a routine</h2>
<p>Have a routine about when you start, and what you do to prepare yourself before you start for the day. Your commute might be a walk down the hall instead of a drive across town or a ride on public transit, but most people I know still benefit from a pre-work routine. Walk the dog, go for a run, eat breakfast, or some other basic activity. It doesn’t matter a whole lot what it is, but have a routine that gives you a few minutes to get settled into a frame of mind to be focused on what you are going to do at work.</p>
<h2 id="make-sure-the-technology-works">Make sure the technology works</h2>
<p>You never want to have to say “I can’t do that from here.” or “I’ll do that next time I’m in the office.” This is particularly true when you have a part-time remote arrangement (i.e. if you work from home 1 or 2 days a week), and the systems may not be setup to fully support remote workers. Push hard to get the technology fixed so you can do everything from home at least as well as you can in the office.</p>
<h2 id="have-back-channels">Have back-channels</h2>
<p>Make sure you are set up with ways to informally communicate with colleagues. Whether that’s Slack, HipChat, Google hangouts, or some other tool, make sure there is a way to discuss totally unimportant stuff to maintain your personal relationships with your colleagues. When times gets stressful it’s critical to have good will built up and important to have a way to work out issues in private.</p>
<h2 id="have-an-office">Have an office</h2>
<p>It doesn’t have to be a nice office, but have a space you go to for work. Make sure it’s setup well for your work, and make sure you don’t spend lots of non-work time in that space. Don’t use the room with your TV or other simple distractions. Ideally you want a space with a door you can close so you can block out any other people who are around and focus.</p>
<h2 id="have-boundaries">Have boundaries</h2>
<p>Like a morning to routine you need to have boundaries about when you are not working. We all have times we have to work late or step into an emergency, but that shouldn&rsquo;t be happening most days. Finish your day at a predictable time most days. Make sure your colleagues know when you are available outside normal hours and limit how much you let them cheat. Most importantly sometimes be truly unavailable.</p>
<h2 id="get-out">Get out</h2>
<p>Get out of your house/apartment at least once a day. When I first worked from home I realized that I’d gone a week without leaving my apartment complex and I was starting to go stir crazy which was bad for me and made less effective at work. Even if it’s just a trip to the store or a walk in the woods, get out and remember there is more to the world than your work.</p>
<h2 id="be-productive">Be Productive</h2>
<p>Lots of work places treat work from home as a privilege they may want to take away again. Even if that doesn’t seem possible in your company, make sure you are proving you are able to be productive with the freedom working from home gives you. Ideally you have a work space free from the normal distractions of a conventional office, so use that environment to get more done than you can in the office.</p>
<h2 id="get-together-with-colleagues">Get together with colleagues</h2>
<p>If you work remotely full-time you need to make sure you still spend face-to-face time with your colleagues. Humans are geared to appreciate time spent together, and for all the technology allows us new freedoms about where and when we work, there is still a different quality when everyone is in one place together. Some companies do this at conferences, some hold retreats, some just call the remote staff to the main office a few times a year. Figure out what makes sense for you and your company and push to make sure it happens.</p>
<h2 id="show-personality">Show personality</h2>
<p><a href="/wp-content/uploads/2016/11/Puzzle.jpg"><figure>
  <a href="/wp-content/uploads/2016/11/Puzzle-300x225.jpg" target="_blank" rel="noopener noreferrer">

    
    
    
    
    

    
    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2016/11/Puzzle-300x225.jpg" alt="puzzle" loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2016/11/Puzzle-300x225.jpg 300w"
     data-src="/wp-content/uploads/2016/11/Puzzle-300x225.jpg"
     src="data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDIBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAGAAgAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AMa28d3ccf8Ax7w/981ai8f3f/PtD/3zXLyX1hZbI5rcu/sa9F8O&#43;C7fWdNivfJ8tZPuqaP3hoZg8d3f/PGP/vmpf&#43;E6n/54x/8AfNdR/wAK1iz0X86k/wCFdRf3E/Oi9Qz/AHZyf/Cbz/3I/wDvmk/4Te6/uJ/3zXW/8K6i/uJ&#43;dRn4fJ/cT86L1A/dnL/8J3d9Nif981QvvFFxfW7xuibfpXZH4fIP4E/Oql14LEUZ&#43;RPzo/eB&#43;7PNvtPNQ3FxniuuuvDPlk4Rfzqh/wAI7IZOgrM0MWx1KTT5/MgHz/St&#43;Lxtqcf8Q/Kr1l4VEhGdtbEXguI9lrT94Bz3/Cdap/z0/Sk/4TvV/wDnp&#43;ldZH4Gtu4WrUfgKz9F/Kj96Z/uzhT471j/AJ6H8qim8d6uI&#43;ZB8394V6GfAtkB0X8q4rxv4cgsoFeIfL0&#43;Ud6P3gHB29t/aOr28JGWLgGvpLRQlrYQW6/KqIAK8L&#43;H1n9q1lrqQZEY/WvY7e78oZPaikB1Il461L5lYVrqSXEW/oo9aufbEwPmHPTmtTM0fNqKSSqvm5oMlAEkknFZl9zHVppQMknAqjdTxY5kX86AOevUwjHv2rml1B/3iyfK&#43;cDFdJqcsIgaQOGKn7oNcnKRLfFkjKrnLUjQ2rG/dJlhkXjbndWjJqj2mCh3k9qwQ4N38wk2hew60TXpJCIAFX&#43;LFMDYuvE0mwbf3frnrVlPF4jEeAW9R3rlZbyGQLkBsdTjrUM8sU5H2bGR&#43;FamZ6bbatFeRZUkHHesfxBai/0&#43;ZEwXx8tcXFfXyzrHBGx465rorG5uYbRzeEn6VlVA57wRBBYaOrsQJJPmOa3NWupFtUnglwA3O3vVFdLtiAFBAAwAD2q7B9kWP&#43;z2&#43;bI6VkaE9lqnmgRTzKUZc4XrU6zPLtELOy54z2rIudKjt3SWElU6HnpUkOotYXKpADJF/FWhmd3as8dsiO25/WpvNxXMWWtNOJZpIysSfdNSLrfnXUSRriNu5NBob1xsngZM43ViXOg20g/1j/8AfVaPmiopJM0/aAcZ4h0eKytBLC77iw/iqoUe0maV1JRkGOO9dZf2kN9EI5egOaw9bAjeEF3EK9QB1rIDOiv5TcZU9uahWR2ldSTgmpXkhfLxodvQHFU8zMzfOoP8IFa&#43;0D2ZakhCTJ5IJBHzUSwi3i85EG7&#43;6Kjh8/yHLt9084q19tg&#43;xskibX/hY0gKmkXMzSSySgoq&#43;taD&#43;Io44CghJ3d2rnGL3D/LcFQG/OpXaTzNrASxKvRRQB0ctyba3d9m8r6VNYSRzqt0Ytjkd6qfaI/P8jOWq/EABgdK5zQimhe8ucCb93/Emaknu7PTU8jYC5HyimW9okF08ylizUt3pqXs0cpbDpWhmX4r2FbIhgFO3OysRpLhJjdRxFgfuj0rTisUjnMhOSRipruy&#43;0Rogcpt/u0AS6NPPNal7k/P6VfMmazLGyNnu/es271q72oAU81BcKjD5wCPenFsAn0qhBex3kk0RVht4rM0MTVALeUPC2YW&#43;9t7VlmW0ltn/wBZvz8rDqK6G70ZJbV44pWXc26sC4tnt/3VsVlcfeNaGZNb3h&#43;wtG&#43;N7fd/&#43;vVK8kmkt2F2hjVejDvUdpctHfeQQpYcsT2qPULpdSea3DYVehBoArRXW1dkYBz3xWvZK5dEWZV3etZFk1rCqxTMQ/8AerSWYHENuvmPn73egDZt4h9reR60I5RnrVaO2Q/3vzqUWSerfnWZoWRMid6sxzL7VSFinq351KLNPVvzoAs&#43;dHnrUnnR/wB&#43;q32JPVvzpfsSerfnQASarBG&#43;xzlqE1a2kfYrGk/s&#43;3JyQSakFhbDkIKAIptQjQHCk1m6VJcPqExdAqN92tn7PB/zzH5U/wAqOP7iUABGFOa5e&#43;Gy7aSL5Fbhq6mqF5YQXiYbigDkn8iI&#43;bhWDfKW71HDpqRss8hBRzWzB4bVJpRMSUP3amTRUgsnid2k&#43;bK0vaD9nTKFxo1nJbMbXDyrzisaCKSxk&#43;1SbomiblfWuy07Torf5wpDN607UNLt7&#43;N0fij2ojjv&#43;Fg6fH/yyej/AIWNYf8APB68ryc1JTA9R/4WVaf88HqT/hZdpj/UNXlVFAHqP/Cz4P8An1b86T/hZ8H/AD6t&#43;deX0UAen/8AC04v&#43;fU/nTP&#43;FqJ/z5/rXmfl0UAel/8AC0/&#43;nX9aD8Uzj/j1/WvNKB1oA9GPxPkz/wAev60o&#43;J0n/PqPzrz19mKI8UAejf8ACyZ5P&#43;XVfzo/4WDP/wA&#43;6/nXn3mYqWI&#43;ZSA7v/hYN12t1qtJ8Qb/ADxAlclnFRGSgD//2Q=="
     data-sizes="auto"
     width="300" alt="puzzle"
     loading="lazy" />


</a>

  
  
</figure></a> Do things that help give your colleagues insight into who you are outside work. I keep a puzzle table in my office to help me clear my head and avoid boredom during long conference calls. At a previous job we did a daily stand up video conference, and some days I would point the camera at the puzzle and worked on it as we talked. It served as a friendly way to help people see me as a real person not just a source of code. I also share pictures of my dogs and other things that round out people’s understanding of my life.</p>
<p>Not all of these things are totally within your control, and you will need support from your company to make sure the environment is right for you to be successful. Work with your manager, other remote employees, and other colleagues to make sure the environment is going to allow you to be successful over time.</p>
]]></content:encoded> </item> <item>
      <title>Looking at a project from different angles</title>
      <link>https://spinningcode.org/2016/08/different-angles/</link>
      <pubDate>
        Sat, 27 Aug 2016 19:20:21 +0000
      </pubDate> <guid
        isPermaLink="false">http://spinningcode.org/?p=65</guid>  <description>Walking around Sydney harbor got me thinking about the advice I’ve been given both about photography and about my work: make sure you try things from different angles.</description> <content:encoded><![CDATA[<p>For our 15th anniversary my wife and went to the south island of New Zealand, with a long layover in Sydney. We only had a few hours in Sydney so we went to see the Opera House and then walk through the <a href="https://www.google.com/maps/@-33.8599424,151.2222651,16z">botanical gardens next door</a>.</p>
<p>As we walked around the harbor I took pictures of the opera house from several different angles. And that got me thinking about the advice I’ve been given both about photography and about my work: make sure you try things from different angles.</p>
<p>Too often all kinds of experts get into a rut and lose track of the perspective non-experts, and other experts with whom they disagree. Cable news channels like to package those ruts as two talking heads yelling at each other by calling it “debate”.</p>
<p>It’s an easy trap to fall into even without watching the people paid to yell at each other. Sometimes when we look at a problem twice it looks different because we changed something small, and we think we’ve seen all the valid angles. But we&rsquo;ve just reinforced our sense of superiority not actually explored anything interesting yet.</p>






<figure >
  
  <a href="/wp-content/uploads/2016/08/TwoAnglesOnTheOperaHouse.png" target="_blank" rel="noopener noreferrer">
    
    

    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2016/08/TwoAnglesOnTheOperaHouse.png" alt="Two angles of the Sidney Opera House with the sun coming between the shells." loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2016/08/TwoAnglesOnTheOperaHouse_hu_ff69337583e689ad.png 680w, /wp-content/uploads/2016/08/TwoAnglesOnTheOperaHouse_hu_909097cf16b2703e.png 850w, /wp-content/uploads/2016/08/TwoAnglesOnTheOperaHouse_hu_639743e53d946132.png 1020w, /wp-content/uploads/2016/08/TwoAnglesOnTheOperaHouse_hu_eb48f2728170889.png 1360w, /wp-content/uploads/2016/08/TwoAnglesOnTheOperaHouse.png 1600w"
     data-src="/wp-content/uploads/2016/08/TwoAnglesOnTheOperaHouse.png"
     src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAAAqCAIAAAD028QUAAAc3klEQVR4nNR76XIcV5beXXOpBQWQIEG2pFZPz0R7/KR&#43;FL&#43;K/ccRdk8vakkkAQIF1F65512P49ybWShQCoeliZ7oSSYLiaxELmf5zneWFP/tv/9vSiillMQfuEXir2zcffpi/CDjr/FQcvYtOfuWsrCH4QZhLHyGnYwRzmhYiWBUcCrHNRG4Ss4SSRPBpOBCMM4ZY/Fkz4snpCOkAqIIcEJEWDmuNHwSNqww3uY/4iKcJ5QChSg1CNImeMcQ/kVRQhRrXCH8xE8C4dco9/Pt8CujxIc9hABKwBNgKDVCwqmBAC5xg3gAP2wQ76ln4D11HrgHD8DCweQncmRB0DJsjAqgfNxPw8Y/rOjjIlAeEG42LDR&#43;DHuCJJ&#43;/pT/5PN943qZB4OHvng&#43;GcCE6nvb8eAhKiUoclDFIHz&#43;ZB089IegDeBx9vhuG0gcWtsWXhh&#43;vRf6hxU&#43;IOMeWL8CGvsCmM5wZXIGSE/gMuBRRa9jDBhQaIegnfz6C2KDrwfyB&#43;sEhaNAEOAfBIoAQzxg71wELD8BgMHn&#43;n0r0cRHn8j7Dd/qzgWGQ17koR9Gf/y0b48FL0Y&#43;nGgPF6Amjf3yxAgR49NSd7pYFHdDoSTAafjwFHz2L0v8coo&#43;LwNhGTqJ5tv0vf74w22j75Atjpy&#43;1xU5aYfGAl8GZDnaKth/wCk43NSKfA4wcQdT&#43;hJEALBwetinh58H/32H1EP//hytPsGe7P1PDM748S/kL24/3eqI6518xcvKDgfaMAPUC2sgpHDzvP&#43;0BFHlwgvGwuMUodac/RtWy4bS/GnOCq4Fz3gfdcjwnmsx/jCYEZWeIT&#43;g52TwR0udfT4BDA4chQCJVCn7EXjhR0A35mchBz6R/OucJPtDagTgg4PHsEI5gQR8OvyHP1kAoI5Qx/u8yfABjfdn0&#43;7JV2qaSzybpfJJmqRT8S&#43;L791iiB5BzFCJnYnph&#43;ISeSCret9G67713UogkTZMkoUKcTnLCHHYGEePWyeoDk2HkFI0hsHsHhDrUKzIjhvTUeTxPuKw/2TqlVFAG5xzuly/OQ9n0P95vv7vdFHU7yeS7V7Ovby7fXy8Ws1xK8ff2BIFW&#43;gJ7BuA&#43;BxxyFmwDCnut1WG/2283RvVJmszn84uLi9n8Is8n7FkN53HizBUYHfKJMTzE9TkUA8bdEeYjNUJJIU2KKcmYW1FKhOC/&#43;uE9gNJmtSv/8vHp3354PFZtItnrxeTbzeUfvr35/ddvri9nSSL/rjoQ56B8Tmaeoy55oQMCYK0tisPD50/L&#43;899Wwsh5vPZq9fXNzfvrt/ezC8u0zR9hprnbJm8UExQAwtRVGDYGOw4SHkQf8wBY45m/eBV43dBbX5I0H7d4hyCz93T/uP9ZrU7dr2mjFR1W1ZN0/XOWvq7d9dXF4kUP8WiQJF9DEpnqPrLFcDYC&#43;QnL8niM2yMzMd733XNdvW4vL9dPy616hmjxT457rfVcd&#43;19fuvfvvq9XWW5YydifvEYkfAYRRGVxg8IJg/hFwMBl4UQowH6oKYPZDzxwzljRiIfg0GBfR3u6L5/LRf74u&#43;751z1JHO2a0z3ltGQAqWSHF1MTv3M7wT75UxnVIeIBMyTRLBOWO/RgcIQWeCJy8TgHMdDNhvrSmPh/XT8rBd913jnaWUOKuN7lXXqL4xWhHir9/cZHl&#43;ciwy8tEBfFgMoBA4KBmoZlzoF9kA8QSoJ7EAEvknjArgwTl&#43;xQJArPNV2z9ti8fNoWpa5&#43;ygfU&#43;0dofCf3wg01xezPIsTaYsDTlgpEy&#43;12ZXVZtjYY29yPPXF/P5dJImCefsFysg6O3M5H&#43;COeex13vfd&#43;1&#43;t95vV11Te2ciGfIA2jvnrLPGO8cYDUW0G4FYxM4IaDT8oBKGtmuDG3vKBONDSjGIOAhjVIOL2QK8sHTUnI9M7Je5AJ7Q&#43;6pVD&#43;vjx4ft5lBqrQEcjacKB2jtD0V9u9y8vZpdXUxTKaTEzFwb13T9rqzvd7vH3V53apGkv3l9&#43;c37N69fX2Us/aVYdMqEn6X/wgPIGT0laP5VedxvVnV5tFYjVYyPFDmp943369UjFyzL0izPEvk6uuYgfUbOWKzXpu/bBqzL0nwymSYy4SyU&#43;siL9NjDkJnRLytxvxL/vfN1q&#43;5Xhz/9uPzhbnUs62D&#43;Hq9GBxUBob3W20N5t9y8v76cT/OMkF6ZXdmstseH7eFpfziWle1UTl17mEvmp5MskZLzX0YKYgwgLxPgL5BjCL7eub5rD/vtYb/tAvicCWAwQ&#43;egbZvN6mk2nV4uFrPJREpOKadDujQAmQcwWheH3Wa11H23uLh6&#43;/bdBUbvTFJ&#43;FmoH3I&#43;2T39i6j5WEn/J4rxvlX7cHP/848Nffnx43Oy7XnnvgssNV4WYAzpouv5xe7hfbS8X0zTLNsf69nH3sNrvDlXdtKrvfN9I17F&#43;&#43;uZq/pt3N7PZ7Kdl8zHN/plq7hgDyMtKA3kmjuRM&#43;l3X7HfrzdOyPB4M&#43;qwP9/ysgygLZ6Ftqu1quXn96tWryyzPhoxmIJoenNdGlcVhef95ef&#43;pb5uL2aKpqpub969eX19cXLAkOcl7UC4diqUvH4rGCPz/qYIYPDtlVrvqu9unv35YPq53bdt558gzAzgJjIZcxxzK&#43;vPjZjJJmZCfN8XD5nA4NqpTRhmvWtcXzPUpc7v9oaybxeUlHUE0tD3wwSHwJec97uH8C1L7RTHuOeNlZ&#43;J3znVts3l6vPv04Wl53zSVd5GYjKgZjGbUg7fGVEWxeXq4uXl7sVgkiaCUoxa901q3TV0Ux83qaflwu92sjOoP8ljs98Vu87vf/4sU/yRl7KwMwj2JHkZsOuG&#43;H8t23gP5f5JBCKSz7vTTrvzb7dOffnh4WG2btnODHwMdq/JjJR4vEZyge1hvHHGOsk3Zl43S2nobahcY9IBaKJtutdmv1rvZfJFmqdEGvMuzZDrJkySBkG30vRKc53ka09VnBTD2cxXNsV4ZEBORZ716/PThh/vbT8f9zmgFAf3pwFOe/SwuHnyvut1us1ktr2/e5tMJZcRa2zT1Ybdbr9fb9Wq/25bFoetbsKZxpt6tVLXLs&#43;T6zZvZfE5e0r5BKGN8GDKBaP4erHMEPGNMcE7Zz/MQh5xH3a2Of/7w9N3Hh/vluqoaaw3ErtDwFHBeUAoeg9F4W5Sd057yVhGDXInFcpdnwhHmjS6VenzkH&#43;&#43;uWZILmdR1DVa9eXXxzde/uVwsgJCm7bf7YyrFm9eX0yl/oQA&#43;lNV&#43;RgdIGL1Xqt9u1ncfP9zffTrsN0r14P2ZZJ6hgp4eAIgxtiyr7WZVHnYXi0vLxbEoHh8fH&#43;7v1&#43;t1VRxV31qjvTdgFKi6tT2z3fH9&#43;66tvbehzExH3QZMJi&#43;kT0KBNIRosNY5awQXLP35nMh76JRZboo//rD8t&#43;8/L1fbtmm8M2hGox/TZ6Amp&#43;IoatxBp61peqDcWuYdjxVA74zralPvbL3rrWJeT&#43;cLA4JxXhVHsN1vv3o7m&#43;bTyYQyXjXd42qXJXySp3mesTMriTSU0C/TgMGQlVKH3e7&#43;9vbh822x35q&#43;I6P0T7XkoWYQP2NYCPXFvu/3&#43;91u/TidzYwn9w/L27u79XrTNLXVGrwlYMFqryrblsRqyUhx2DVlgd8mybktj9SUxssFxCGItqFVqbXuuy5JpBD8pyQEgBjn9kXz/d36Lz8&#43;3D9tmqYBZzGED/VEoGeKhdjxGS5JLTBiuQulbwj1EEq9sdq2e1utbXPQXQ3WgrP58sGDIJTV5Y54xUF/9e7d9evXSZprY6umNZppbfxL2iAYPUuSTikAAcT9rtvv9p9vP93ffjxuN7pvAdnCKR2Fl83JkxH5qBdjTVkUD/d3zvumNw/Lp81213aYcBIIqzdet67vnHEEaN&#43;b/W6/Xa9u3n&#43;VZikXEgUd033GGOehCYN0AB/D&#43;zSRkHAP1PSqLMvpdDLJJ/AyW45m1HZ6uTl&#43;f7d6WO/qpsXkMUifEnhO&#43;4YwM6AvF5wx5kIZyroYWENNxFmvO13vTLUBVXqjlNLOIok67LaUpR5IUx0ZMXki15vN119/LWQSwrD3GDf9F5xhKEUw8kL6xtiqqtar9f3d3fLudrt&#43;6tsaedkpURlJzcl2hur0GJMDHfJVVd3ffT4ey067omp6dYp4IXziByMspZITb43zh/1u&#43;fn2LSog50KovteqJwQmk8ns4iJJUkKIMaYqC6P0xWI&#43;zyUJHXsalfSSAaIjOqe02R6On&#43;5X94&#43;bsqqtNTT0/&#43;mAYSGM&#43;XD7waUIpVnCL&#43;fTLE2qVlet8s6DdzRwCNvVqtqoYo38B1Ci2jhr0ebqqqJ8Zz3p2oYRm6Xb1dO6qqrpbDa6InmBoScFnKM/QMy2yvv7h08fPj4&#43;fC72O9Whz9LR&#43;E8lgWCRUe7RhGAoFUPsZ0GvYLM/HqvOAbOhshOBjjFOmSBUhGoC865xVnvXlwf/9PD54e6WUg4A5eFQFUdG3dv377/953&#43;5evWaUNb33Xaz6eqawM3VfOJzQQkRQkghzrE1ksiqrjbb3fefHv7814/L5bptNbpUmJHhYycPfcpojORUUCEF55Lxy4mYZMKqrrK9NY5RIE7rruqKdVesTXP0VgX9MQeYIwouvffWmV5DqzRxercv1uttcSxeX19HVwZPo0PDWVIpnrPTIFDrXVPXj8uHDz98f393W&#43;x3uu9Q/4Pw6FkTN6INDAsBzLZCeyEGzVDGCTDjDGU80kQWLZVLxriz2tnOdLXuCqdqBqYjZr9Z3X382LXKGlPsd&#43;VxS4mtq39eXF7M5zMhkr5tV49P5WGfSHb9apEJcKrr2pYLPplMw9lZxIu2a&#43;&#43;XD3/&#43;y1//&#43;Jcf/vrj/bZUnvIA4yCEyLIsyXLGmNWqa0rV91TINJ8mUrSW7VxRMNgf27I1wDC4ONO1x3V9WPf10aouoDFQxvFhZCplslhczC8vDkXbtNRYqFu1PxwOx2PXdc4aZ7Tx1FhrreNcnExFcAZj5oVApbpus366/fjh8f6uPOx03zhrwPuzPs1QOqYQC2Uwgk84APXJh3iJOS0DyoGyYeCEhnjHOBBitVJtoeqt6QqrW7CaUzCM1uVx/fC5qxtnbVnsy&#43;OWgOOCffPtt29v3vEpM1pXZXnY78s3V4fDoS6PqimbulosFr0yV1eXsR4AAEVZLZ9W3/3w43d/&#43;9vj07Y3HihTfW&#43;tljKZLa5mF68Q6Nq6Lvaq73giQU2cFJ0ze6fR4pX1LE0n8ySRuquqw7qrjkYrTIO8pwCMOYGeh&#43;QnTdMU835gBBhj3kPTYBA9Ho6tMk1dcQqHw2GSZ5PJREoZjVmESkRs/BEXKp0Pnz8/PtyXxcEaBaFSiSlPqAczOHVf4ZkzjwlcsAYkuYHdRXcIkyIQ6zmhsc7AWbCqNV2p6p3tSu8UOiZ4oMRZ27dNedw566w1xXFfFntC/ORpun5cfvtPv8&#43;zDO3EWhv6cbvd7nDY79ZPZVFMZ7Nvf7t69/ZNnk&#43;SJKEUyrL88PFu&#43;bgpqtpY5S3an&#43;k6Y5SXieReMM&#43;ZUH3rVMPACG&#43;JNtZQo/DkulfGeiZSZ7Xm3PS1amprLYYJxmOaFACcASDl2&#43;62TdO2vWbgppnMs5RTUhyPy4eHttdPj0trtDNmvdrM5/MsG8qrgsUsnxLvfN81m/XqabksDgfMtogPHSvuPQ3sE877iWNjMEYGyoTI8yzPEArbzhjrw7QOjREOuUhos3vnjVW2K017sKomzoRcPRxGMVnTWnVtA8C0VmVZtE1DKDkcDuunx&#43;q4v7q8Cu1hQEroMFZ9&#43;nR39&#43;ljUZZJmn5erhYXF2may0RSAl1bbzbrp9Wq61suLIABZwVH0&#43;CCUrBW1Z5y4l2a8GA8eFqLWa4NT8Xwfq1WTWkp9d4wisEGPKYCYV4yxEwPwZxJW9d921PKJtPJ4mI2n04W81x1DeZPZX376b5pmqfl42Q6RfSTA88WDI0bwUcrfTzsHpcPu&#43;2m79tQa/ND85WddbcIHcvCMI6oUCA8TbPrq6urxbRXZrU9mrrzPrRVAnOMNu5R/L3rC9senW4BH2moxMa00zqvtem71jpQSnddr62jFJq63m3Wx93u3bv3wZNQB4Cy6Q/7w&#43;PTuqprLsSxqGWSCBFKkoAQ0tYlSj/x6dQmmesp8ZY4j/knowBOQyzWCrTAcIPOWTQWzgSRjBBujLZ9a8DFqQO8S0yFRZLgldBxPeR5PpvPpEy881yI&#43;TRbzPLpJJWctHVRFofdoVyvMP&#43;oiiJJs6FGFIxXOItUr2/bqiw&#43;f7q7v/3huF9ppWAkjEED4Zkpee4JBkRC70AXYs5TyVmeimmWBCwhDh8l/AmqF1k/OOtMZ7vS9oXXLVpZjOyEoUcj1faBaYM2WltQBompD3mXUqo4Hg/7repaCj7ApkeSaU3TtkVVtW0juDDWSiEDDIbiuDOqb43tU&#43;EniUsE9YZ3FaKbkJIxYNIxgezOGXDaYToSuhOAouZCiAA1oL2xmLgh4nBKGA/DwmhXljGe5/n166urywWlVFsnhZhNJ4kUGvXfeOdUr&#43;q6a6sGiVaa8nhvfmBGoi0Pm6eHzdPDdrO&#43;v394uH&#43;s254wSSn3Mf8PleQwyYz0hQD1KF2DlxeE0oQS6R3XPRQHYvuq6XRZVKpTyNFosC80E&#43;tNZ7rSdKUzPT4xjH0tCiyO9zAqk3R&#43;MZdJ3nYmDOoEauW9MbauquKwV11DecIo&#43;lPQV2gXOwjK9s46PB3Sc0cCUqFuGfdGq0aRhIFLGXhOQFIqE8Inlk8cBTA1OkNo/4/j24xzIRMmkiRNs9Q7yykJM9siy1IhpLW2aTsCZHGxeH9zc/P2GgjplZZ4QAbe11VdtVXf9Vora5xgdDKZvn9/c7FYxGmMUM1zoikPy7sfPnz3p6fHx/3hWNWtJ5zLPBxkgHrOqZCMyZSyjJEEYitFtUYpQpG5MZoCCE1IX&#43;0YsmXdKeOAMCY4svME0wurTI/SN6rz3hHvh0QiPDGABcQCOZvPf/PVN0IkT6uNUtrGekPgjm3XFcdj1zb5BOMVwhp4xkUynaezhR2KvYIQGqzLMeIZZyJNEs&#43;Msc2&#43;U8wnPMtkmlOf50kykfwKxBwhSTMiHfOC0zhfSsPIC5dMJCGM&#43;SB9mgo2ybP5fJokSdch&#43;mmt57PZYrG4vLzkQhhj0yydTSYefFVWk8kkcFDrrNPGzOazP/yXP9y8e88YDXiLnFSAM1b3ZXE87Hd13RhjCRPBR6x1PaHWcfBOMJhyekHBeW&#43;NbjUqwILjmilGJd63dxDcwjnrkO8xJhKR5DTJUP66MV1ldIeh5bmNC3HcOTBZNHeUWJoKkQRkDiEEaQAeqZWpq6qpSrRozNqsd05wNpvOLi&#43;vBPGcESkEQpPT4JjgEItDGI07VhyRiGfzyfxiKggkiciu8uSN5DPvjFHUO8mZTxkVcdSMEOqAUp4gEnGRSpEInspANPKMMa6Vurq8MlpnWfbq6urV61dpnjFKJ5N8Op1yxjQyqd4Y7awLZbF9mqX/&#43;l//9ZvffiulACChhevEbvVYFWXXqVhgwbjgLZokJt8aqAbqvBUWU0funQ6Zcg&#43;gowC9scMcCTqVCY2H0KmNXUeEWEqQ&#43;DTWqPDNOYEaJxtDQdA7X9XV4/JRyqSpK2sxa0X845wzDDp13WzWG2ts09RK9Vp1xPYzbl/lNHMyS9NJnqF3GEXAZqnIEsyNgUDfzfa5bNtusbh8fXkpCKDmrmbT6xmfMOSmU08MT0TGmRx6IoyhFXEpE&#43;T3iUwS/C/TJGWcO&#43;etMVor8JBl2eJysVgs0izlnCdh4WFew4XFaL3f7z9&#43;vAUCi6tXr6&#43;v0zQdpszAi//1P//Hdrva79fWdYxZEtgK8Y5TQFrGh5cuQtG342Bi85dzTiV1wBA2Y3MmIHIchgvMCoOUt9qBRY06i/u5AApjKek0k/Jcvum7fr1Zx3Bqkf9wKRgX&#43;C9NEq3043JZleV2symL436XSQbSVleJzSd8Ok2m05xR4lzKGMmzNEklY0O5dHGRq17Np/P5bEacl4JfhMRV5hJl8RojnRBSYIqO8C8kRmAeyI5MUAEiSaRAh0CaoPH&#43;vMeEK8vS2Ww2mU5DYB8rUnQc5PO&#43;V8o4wuTaWkMRloWU8lQyFH/64/9Rpna046mVQG3PvLYUDJ4DYZkC46HIEEqzGDlj8oGmiXQkaCwUs4L3BE4DwGKpHawOVAiVyIVk6GJDaxQ9m7NQJXQx2HPO8c6ABF90lNBUitDZlxjZ0lQwWh6PZVGut7uqqmwgiLNMvpplfppm&#43;STPJ2jyYeJISI4paiihem8WFxn1Pk0yIaS3nlGW53nKRUIFD22cIPeANxwFJGUiJDJa/CVJcZUpRmUugNDg5tHW8J6RkcrIvuhZI5GMZo7Jv3VgPfWxAXHWtBCHwx5YL&#43;cmnQEnAmVnDQET0FcgFnMGSNlC5wzi60wk1JVCJxCG1uTwdlPw3jheE1YLLlIpZDowji4xxqSUaZJgINLoVYyxJEmzNEXapw0GZc6zNJnmaSIRy6UUFHzXNsa4uqzKqtKqlxQmX91czGdCCJlkmH&#43;F6wRzgcCsgMVGWppgGsVEyMWRTAoG3mmnMSngnKO/Uw8&#43;zBt5FmaDfSibY3jDCDcyq2goIe9nockbN8ahgzPpn5QhhZjOpt65JJFfVMuFAwvUoYYSgvaiPdF4pbFFHSa18eaoH6pwEGDHBybiYRhYHlAl3lNg/zQW89EzgAxr7DXjYVSgdIikMgZZKUSO&#43;aH0yLhRHyhSBFM0K&#43;9BK2WNUVoBkBAAlHembVttgv7C0IyzwVdFKHuwQCvDjB0yXRpptAu3ysPLI0DBRTmTYXaJnEYoR/nQcTQmVvTRhoMhBa4aemPjxOSpXUdPxc5om5zzxWL&#43;&#43;99948FfXi6EEC8UQDLmJVMJAepSTkjOqPV4XRvHdzDPYmE4LbSfLHgWeTZxQ21tHDYJgM5CqTk8PfWEBYuJIwLhbtHWRFij2xLKIPhyksjZJBeCG627PrEO0LsjTmHO6vteWWtTJQMHN85ZSpi1BjNVozBZcIaG4hP3ATXDGBILYkZGxcN3EHbE/DxoJ8K0x6fyUcZDkjQ0UPhzvzX0dhi8WEhI9089/aiC4e2dUYucs8VinqYJAEZswV8qgF4mIMBIbalzlKQZlRDKRIpTSCiVcfqAxrcmfRwlpNQHmfLQqIs7Y4OJccpDAgmeUg4cxvdbUAJCyCxNsizN0zTLMi6ECz4U7J1nKWKNcy5XGuN6KCXJUHOxBqOyUkqbyMsdnjC&#43;HhMbVRDKkyRMPIbibHyvII5YjQ0jHyimDwbz3Dg69VAJ9Zhkeh7RFdMkhtjgvQiExSMJZ44Bj1MYPr4zReKMJYTazskUnxeEICmj3KPjPM/wECKyqywUlYzDDFxgxBHApWO95DalIAjE52QulBy8IzYUROJwP7hYphuaSqHZEarQMI7FBIpKkThRiaQizVD4uFDKNGjCSCJDXyhUODhjCESCxZZvmvBECjRzZKUWg4fgBJyzfJKni4vZNM9SyQUiMWWccAFMUC4GqnAauuGccvS/ABlMMKR3nFIxvIE89tJgmMqOU/SMvhzSG/55QPYX7C0SdwqeMM5eDgScj&#43;3RgWqHV3mHFvTgWmIxzyzhjXW9I6mQ0zRPkb47BGA/YV6A84IJRoVzxFgwBpM65xwPdRHnwGEwcKHS5owJVQq8JR9IAhvnSSBEBW&#43;M7Yhy1qleAyEOuSZJk4RxDAU8zC0BIRwJn2SBgqJ6KMwmeSKFDF2vpkEXu1pc/Obdm&#43;ury0RyPhQzEHxEQpg4dY5CkwLhKITLUPTElWAygC40vMA2vGdFBk5BIhcVoTU8vAHEzsQ7ToMA8ejemK6fmfzz5tks8aiWsfM8KOb/BgAA//9KdOOlU3NIlAAAAABJRU5ErkJggg=="
     data-sizes="auto"
     width="1600" alt="Two angles of the Sidney Opera House with the sun coming between the shells."
     loading="lazy" />



  </a><figcaption>When you look right at the sun a small change can have a large impact, but you may still be fundamentally in the same place with a fundamentally flawed perspective.</figcaption></figure>

<p>And sometimes you look from a new angle and something easily recognizable becomes new and different, but that’s not always an improvement. There are reasons for best practices, and sometimes we just reinvent the wheel when we try to break our own path.</p>






<figure >
  
  <a href="/wp-content/uploads/2016/08/AHC_7436.jpg" target="_blank" rel="noopener noreferrer">
    
    

    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2016/08/AHC_7436.jpg" alt="You don&#39;t see pictures of the opera house from this angle often – which is probably for the best." loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2016/08/AHC_7436_hu_3b02a85f4b7dc28.jpg 680w, /wp-content/uploads/2016/08/AHC_7436.jpg 800w"
     data-src="/wp-content/uploads/2016/08/AHC_7436.jpg"
     src="data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDIBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAFUAgAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AIvLo8urXlUeVX1Z4ZV8upRHUvlUvl0AQ&#43;XUojqXyqXy6AIfLqUR1KI6Xy6AIfLqUR1KI6lEdAEQjqUR1KI6Xy6AEEdS&#43;XxQI6lEdAEXlUeVVryqPKrIDB8qjyqteVR5VagVfKo8qrXlUeVQBF5VHlVa8ujyqAK3l1IIqmEXNSLFk4HJFICLyqTy&#43;ateXxVu306SePzFWk6qhuBQERqQRVcMBU4I5FJ5dHtLgRCKpRHR5sUbBXfmrQjDYKVh7UCHy6Xy6teVR5VL2gGF5R9Kk8qr/kiodg8zZmtfagVvKpFiDqdvOOuO1XzEMYrzHWPEOoeEfFhMTGS1lOWRuh9ayq4r2ZrSpe0PQBFUnlcVn6XrVtr9ob3TZV8xf9Zbk8ioJvESwsVaEhh1FFLFe0FVpVKZr&#43;XgE155f&#43;Om0bxeARutlO2RfWuxXX4JdPmkZGXapr5&#43;1y5N3q8z5OGc1y42rY1w1LufStxcW93pkOo2DB4p8cD&#43;E1uaPLtiRG6jrXifw68Svp6nSrx98D8x57GvT7LxDaO/l52MDjNcM6lWasdVNUzS1bU9Oh1uKykcRSyjK571Ldae1vGZDyuM5FeLfFfVJf8AhI7eSCXDRqNhBr0v4b&#43;LY/E2jHTdQkH2uNNpJ7iinialPcKmGp1DBub2SW/eTPyA/LXSaRfiUAE1SvfDm2SU2rb1ViMGs62E9jcbZEKjPWtva&#43;0MfZHeiPIzR5X7xaTSJRc24yea0JIhvStPanP7I8ui8ZTy8hIC393fUNr4sg2TT3EqRyKxwma5uXQEnFrJveJ2Ub1QVTvfDsEc4k819hYAgiub617Q9KnhfZm&#43;/wAQYwjb23N2xXB&#43;INTuvEVyZ3KRov3RmtubwrASSk5XJ6Y7VXk8LRoP&#43;Pj9KPa&#43;0D2XszB0S/vNBvVure4ZWB&#43;7nhq7nWvGNhf6fBdwxiO&#43;IxImOPrXPweG1a6WLzdynNDeFJXDhJRxWXtbGrpXNiy8YWg0C5t7mLdcuCFI6Vxum&#43;H7nU7syCJipORxXU2WhwWNvm5i8xxXSXNzbQaRBFYRGK4YZL4oq1TOnSMjSfBaWrC51K5WBV6Fmxitg2&#43;mmTfa6xESOo3DmuT1jRdW1WQPNfs6kcLnpWQPBWoA/u7gD/gVZqpM09kb&#43;u&#43;G5NWuvOW6RyvTmsmxuLvwnq8dzFIBIhwVB&#43;9Vi08MapaQkmctIeh3dKl0/wAMXX9ofaL5xKBzzzWntAOt8P6l4l1m8a4RjFAzbmBHrXZTwTXrpaOSrL0fHBrgLrxbq2kWb21vYoIsYDqOai0n4ptZmNb&#43;3kLL/ERWX7wdqZ1mqy65pcqJZyBUHDN1rWsfEy6fbodRumkkPPTpWAvxH0TVNqGTyjzneKz72&#43;0rUbvAvUwwAp&#43;0YqlI8/jv/E8GNpkOKc&#43;p&#43;JJlCybiA27kV0/mCpN49BSA54ar4hfAZFx/u1IbnWpRzs/75rd3j0o4oAx7MX8c6vI1bls8ef3gNM4qTjFBoakb6eY8SBj&#43;NW/tukxoq/Z920Ywa53PNJJJ7UAalzcW877kTYPQVDx/BVES7valEpoMy9l9n/16QSuP4TVbJx1pfNNAD5WZ&#43;CoNU7vTbW4X97Apb2FXY5PWpMjrxQBxeo&#43;EQT5loxU/3TVOLwxq0UgfcPzr0A7T6VHux/DurX2gGRuNSRscVDUkfSsgH7jT6i71L2oNAFS1F3qWgAooooAi/jpY&#43;tJ/HSx9aDMs9qTaKXtRQAVl3qS&#43;Zlbh1HoK1Kz7z71AEUUMhxm4k/Or6IYAPnZvqarQ9quSdBQB/9k="
     data-sizes="auto"
     width="800" alt="You don&#39;t see pictures of the opera house from this angle often – which is probably for the best."
     loading="lazy" />



  </a><figcaption>You don&rsquo;t see pictures of the opera house from this angle often – which is probably for the best.</figcaption></figure>







<figure >
  
  <a href="/wp-content/uploads/2016/08/AHC_7449.jpg" target="_blank" rel="noopener noreferrer">
    
    

    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2016/08/AHC_7449.jpg" alt="This angle was even worse. It&#39;s a good thing I wasn&#39;t using film for this exercise." loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2016/08/AHC_7449_hu_de66bb0b1b74c2cd.jpg 680w, /wp-content/uploads/2016/08/AHC_7449.jpg 800w"
     data-src="/wp-content/uploads/2016/08/AHC_7449.jpg"
     src="data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDIBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAFUAgAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AMby6PKqXy6l8uvcPMKvl1KI6l8ql8ugyIfLo8urXl0eVQBEI6PLqby6k8ugCr5dS&#43;XUvlUvl0AQ&#43;VR5VWvLo8ug1KvlVL5dS&#43;XR5fvQBF5VHl1LR5dAFXy6PLq15dHl1mBD5dL5VS&#43;XUmMDmgCt5dS&#43;XUnlikLqvVgPxoAZ5dHl07zo/wC&#43;v51MAhHDA/jQBH5dL5dS&#43;XR5dAEXl0eXUvlmpPLoAreXR5dWvLo8ugCr5dSeXU3l0eXQBnNe2qojmVAre9Ibu3Vd5mUL7mvHJdWnmZDJI4CD5eaim1K4uWBaVgPTNcP1k6vqx7I&#43;tadH965j/Oue1/xGps2&#43;ySFfmxuFebSXDn5Ofrmjz5SmwucUvah7I77TNdmuYBHJPhx/ExxW3Fbm9DqtwGYdcHNeVBmI4citHTdZurFspKwrP2pp7I9GXRJd/EpqzZaZMbzy5JSFHoa5mw8dPb6jC0yh4m4cVr/8JXYJqayqTtduR6CtPamfsjX1C4uNKmBk&#43;aD&#43;E1Zsb&#43;O9HyVH4p8vU7GGO1mTaRu61zGjXp0&#43;4aOdwoXvmj2wexO0lnih/wBY4&#43;lZI8R2u6ddrfu6zfE9&#43;JUtpLVSwPDMtc5LdNZ3L5QsHXmn7UPqx6ZZzx3Fuk6n7y1F/aFt5jJ5g&#43;UZavOh4oMabYt6hRgc1Wh1qMPIWLZbk81r7UPZHqcc0c8fmI&#43;UqVWDDKkEe1eYJ4keGyaEE8/d5xS2ni64tbbYGyd2eTR7UXsjkzo93/dH506PSpR94L&#43;dP&#43;0P/wA9G/Ok3sf4jXL7I19qN/syYndlf&#43;&#43;qP7JdXz5qc&#43;9OyfU0ZPrR7IPaDxpTf89k/OpRpi5GbhKr5PrUmfej2Qe1L40i04JvEz9K0La30uEB3kEjisCpRWv1YPanXRa1ZRDLIWA4xmquoaxYXEeI4Np9a5vPvS0fVqYfWah0sWvRCz8hogy&#43;tYl1Kk05cM351COlGKPZUzP2tQiMIJ&#43;9R9mT&#43;/UtGPatfZB7UrmyQ/xtSfYk9Wq7S0hXMuig/IKI6zAMUVLxQY8/drQCKjZ3zQY6XC7P4qzAkFFSR9KjPfdWhmAqXfx0qNJEz0p&#43;8elAC&#43;Z/tUeZvoSMffNBw/3eKADzMVKLgelRYx/tUYz2oAl81C/WjzUqr5ew5o3p6UAV5GOykDHFI/3KQdK5jQtx/wCroTvRH/q6E71qAzcc1ID7VD3qUUAKr7X4AokfP8Ipn8dK9ACoAz9Kk2DLNUcX36l7PQAzzjjGBTUO402nRUASt8qcUoYgUkn3KT&#43;GgBqMSTmnSAJHkCo4&#43;tSzf6ugD//Z"
     data-sizes="auto"
     width="800" alt="This angle was even worse. It&#39;s a good thing I wasn&#39;t using film for this exercise."
     loading="lazy" />



  </a><figcaption>This angle was even worse. It&rsquo;s a good thing I wasn&rsquo;t using film for this exercise.</figcaption></figure>

<p>And sometimes it is important to think about the extra details that you can capture by changing perspectives and taking the time to figure out the best approach.</p>






<figure >
  
  <a href="/wp-content/uploads/2016/08/AHC_7466.jpg" target="_blank" rel="noopener noreferrer">
    
    

    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2016/08/AHC_7466.jpg" alt="Opera House with sailboat" loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2016/08/AHC_7466_hu_41fb75ad4f33b6e2.jpg 680w, /wp-content/uploads/2016/08/AHC_7466.jpg 800w"
     data-src="/wp-content/uploads/2016/08/AHC_7466.jpg"
     src="data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDIBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAFUAgAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AL/l0eXVryqPKr2DzCr5dHl1a8qjyqAKvl0eXVryqPLoAq&#43;XR5dWfLqPy6AIfLqPy6teXR5VAFXy6PLq15dJ5dAFXy6j8urXl0eXQBV8uovLq95dR&#43;XQBs&#43;VR5VS0VncCLyqPLqWjZ70AReXUfl1Z8ujy6AKvl0eVVryqPKoGVfKo8onpUoI83ZUF74gstNP2dFDznj6VlUqmlOkNMRpPLq1Zo9za&#43;eeFNJMqwjMhAFae1D2RW8viojHUVxqSIwSEbnI4PaqElxcTqC77VxkqvFHtDMuyXEMBw0ig&#43;hqnLqtsPuhm&#43;gqitu8zqY4i3&#43;01WE0uZxHvkCc9hR7U0KPhzxdcXuqCK66txx0rvtygZJAFeAaXqM9neJMg&#43;ZT6V6rp8l/q1kJvm8pl9K4aVU6fZHRSXkEe394nzHHWpPtlmP&#43;W8f/AH1XMp4UkldmkEmMf3q5PxLpf9mzxi3aVn3fMm6tfamf1Y9V86LyvN8xfL9c1VOqWAPNzED/AL1eaJrcyRpaJDKYSMMM9D7Vk3lvetdMIIZHA53Cl7UPZHs2ieINNub24s7hkDIu9Wz1FaUMljqqMbJxgHaTXh0mn6kxguYsxSKu1sHrXTeE77UdLuJgSGV14U&#43;tZ&#43;1On2R1Otw3OiwySlzKW&#43;7tHSvPYpJp9SZ5WJcnODXYy6vrUmfMt4n9ATWZBYXV5qiPcwxQbm&#43;8lKnVD2R2Nq26ygjQ42KM1eurW3eINcAFVHPNeay6xq2neJZbIEtArYB9a2ZEurmKQyXsgEvG30rC&#43;pp7Ih1DWLJb4Q2UbeUoK7guaZbarZRsiSRyySAf3DU9n9n0GzJnzJk4Hy5NOj8V6K0mXQo/uldlKqcVWkMfxJawukf2eUM33V29aU6825f9BuP&#43;&#43;aoahq9hf63p8lvImI2&#43;aukXWtNZXZZ4sj3p&#43;1D2R5Z/bdshbZp8S1pjx1exWAtbUCFfauP8s1JitfZUw9rUOnHjrWTDsa5JWqNz4luLxlMyhiO571jY4qPvR7KmHtahsNrk7FfKiSPb6DrVmLxXex/J5SflWEM0nzUeypi9rUOhXxPMH3CFRU8fiq6HIiQVzHz0fvKPq1Mftah1B8X3nPyio4vFlyz5kDEjoc8Cub/eVFmQVl7KmHtahu3et3U9955bLf3qtjxXeCNUChivrXOeb&#43;7qLzDWnsqYe1qnUHxdds6mSJCF7GnSeKRLy9lB/wB81yuc96MutHsqYva1C/c3ZnujPHGkX&#43;ytMTUZY1KYFU81Fnmn7KmBaj4&#43;/Rv3vwOKTa2PmIqPzWjX7orQC1/wGoiAnzGovN/i3/hS4Mn8VAEh5GUao&#43;aTy/L/AI6Ely5X&#43;GgCUHZUmRs&#43;/VdN5J&#43;XiiQon8P60wJf89aaSMdaj8zeOhqM7fU0gJf4PlpJMAc1HHLj5fvUjyjOGX86yAX5T9yjOzqaT7nKfdozn&#43;GgBfM3/dFJ5oHVaTzWHybRTJCny80ASAFW25OKjmJQjFSn/WVDc9RQAqv&#43;8BwKt&#43;bzt2iqS/fFWf46AElY7KSDg0kn3KWHqKALVxJ5EXygVBGomUseDUl9/qhTLX/VGtQKzTur7B0qfy8t1qnJ/rvxq8Ov4VkMryMUBAqGImaT5qkn71Fa/wCsNBoWdo8uoySDjtU38FQn75oMhqvuOCKldEEedtV0&#43;9VmT/VUDP/Z"
     data-sizes="auto"
     width="800" alt="Opera House with sailboat"
     loading="lazy" />



  </a><figcaption>I had to wait a few minutes for the sailboat to get into a spot that made it look right.</figcaption></figure>







<figure >
  
  <a href="/wp-content/uploads/2016/08/AHC_7480.jpg" target="_blank" rel="noopener noreferrer">
    
    

    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2016/08/AHC_7480.jpg" alt="Sometimes too much context is too distracting." loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2016/08/AHC_7480_hu_dda15c653940315d.jpg 680w, /wp-content/uploads/2016/08/AHC_7480.jpg 800w"
     data-src="/wp-content/uploads/2016/08/AHC_7480.jpg"
     src="data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDIBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAFUAgAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AKvlUeVV/wAqjyvavsD50oeVUZiNaflUhiFBmZnlVGYjWn5VJ5QoAzPKqMxGtPyfajyfagDL8qjyqv8Akn0o8n2rQCh5VHlVf8qjyqzAoeVR5VX/ACqPKoAoeVUXlVqeV7Unk&#43;1BodJ9lo&#43;y1qeT7UfZqy9qBlm14qP7NWx9loNrR7UDGNrUX2atk2tJ9l4o9qBjmH2qLyfatn7LSfZR6Ue1Ax/J9qPJ9q1Da0hthR7UDH8r2o8qtT7NR9lo9qBl&#43;VR5Van2Wj7LQBl&#43;VR5Van2Wj7LQBBc&#43;ONLtNR&#43;zyOAi9SOanj8b6PIm8OcfSvJpprGYljbsT65p8d1ZpF5fkvj/AHq8G2MPUthz2K08T6VfzKkVwhb34rQa8tROsZnQs/3VBrwuKSyhbcqSqfUNVq01tbW8inEkreW3AJrb2mJ/kMvZ0j28ooPJApFiR5NgYfnXm9x8Q7eaHBgYSeu6slfFatL5sk84OexrX2lQPZUz1i8eCxIEvy56U6SFUhEuRg815teeN7a7t0SVpWZPunFSxeObd7NY5zIzLWftKpp7KkdrJdp0QBqif7SeY/L59TXBN45ijkIS3DJ&#43;VWh8QLRLQJ9kLP8AWuj2lQ5vZHXu9zHy8at/u0sV7BI22T5DXCp46Ron8yMq2flwar3niaC4h/d5V/XPNP2oeyPTlEDPsWQFqAI9xXeuR1Ga8gg8UXkDyuspEmMLk9KrReIr&#43;J5JvPcyv15o9rUNfZHslxNDAF81wNxwKiW4tX3bZQNvB5ryN/GGpyZ8xQ&#43;Og9Kqza/dMrYaQMxzwaPa1A9kXP7Ihf5UnHze9SSeHWRFxKDuGVq9f6fpltqUVjHcHIH3s810FlaxSBFJIVB8ua&#43;e/tOrTPT&#43;q0zjz4W1AReYvzLWRc2VzbEh0/KvUS7OzK0o8lOy15v4h1c2&#43;pPGgGxTx3zXTSzOowqYKn0MwBgfnRqfjzW2pnd6VVfXN748s4NaWnw3F3aMyqAGbAYdR7V0vHHN9WGm1uPK3mNlC8ZqERzllAOS1dbqmoJp&#43;gQwzQjzeASf51ySajbLqqyxsQmORiub69UNfq1MWRZIceYMZpGGRkVp2Op6fdTs14wZ1OETHGKli0xNSWeW3YR7ckIa6qWO/wCfhlVw3/PswqOf9qo5GMUpV&#43;3FSb0I&#43;9Xac1mGx&#43;uaMkUBgnfd&#43;NSBA3egCMSntQZCOtSm2/uvUUkTjowagD1FPDWlb/tMgZ3H8e6sPXNXFlzpz7gPlYZrO1nxcIbia0tgVQ8Vlrq6w6asckSnecsx618r7LufQHRafre&#43;HbNG26Xg4qnqHha3uoZJUSYSdcnnNMtpUurq1mt4tkCLlsdzXRSasBaNIkZ4/hz1rPWm9DM860/QlF6y3fmRqh6kV02oWlrY2LvZXhAIBK4q1Ffwyl2mTcp/hxmp7S40maXbJbuV9xxWlSqL2Rh22pNf2QWZVlZflGRk1XstEK3DXDxhk/ulcV6Rpmm6XuaSKKJPqMUajc2WnReY3lmPuBWftX0D2R5YdH868d4wqfN69K0IrG4sI5DI/LL8uD1rQudQiluJJI4FSLswHWqM16LiMxsjZ/hataVWpcDmXlTzDuBzmtGytbe8xm5VPVTxWbdWxjlJfOPWoNmDlHr31V0POdI6ebRbdyFtLhWfuM1iXCSWkjRsMMPQ1VW4mhlyGNPllkY&#43;Y3O6n7QXsxRcyDqzVJ9sT3Wqsj4HSoutHtQ9kWUk83Uy0gDc967DVNItbnRFu1Xy3VRwvQ1xkH/H&#43;frXodz/AMiqf92vEqbnpUiLRLRY7BCGP0qTVpxb2smyMcLUmj/8g6Oq2u/8e03&#43;7WPU1Of02&#43;mlJG7FW5nmhO5ZT&#43;VZekfeNad392ipuZjIdVvXkKmdsexpk1zPcjbJKxH1qrbf641Mv3vzrQ0E0y7kY&#43;W&#43;GUNjmp79mg1GJUPyt2qjpf8Arj/v1d1b/kJQU&#43;pmOuAksTq6A1ztxEqKSnFdHL916wLv7prqpGVUo&#43;c1L5z7PvVFTv8AlnXacxMreanzVLJCqIpFQw/dqzN/q0oA/9k="
     data-sizes="auto"
     width="800" alt="Sometimes too much context is too distracting."
     loading="lazy" />



  </a><figcaption>Sometimes too much context is too distracting and makes it hard to know what you&rsquo;re supposed to look at.</figcaption></figure>

<p>But when you take the time to look at things from different angles, perspectives, and positions sometimes you get to discover something you didn’t know to ask about.</p>






<figure class="figure-center">
  
  <a href="/wp-content/uploads/2016/08/NappingSeal.jpg" target="_blank" rel="noopener noreferrer">
    
    

    











<noscript>
  <img class="rcf-image" src="/wp-content/uploads/2016/08/NappingSeal.jpg" alt="A harbor seal napping in the sun at the bottom of a set of steps to the water." loading="lazy" />
</noscript>

<img class="rcf-image lazyload show-if-js"
     data-srcset="/wp-content/uploads/2016/08/NappingSeal_hu_7a831635b2316265.jpg 680w, /wp-content/uploads/2016/08/NappingSeal_hu_ba45e08439c8dd1b.jpg 850w, /wp-content/uploads/2016/08/NappingSeal_hu_3b42a5535ec76c7e.jpg 1020w, /wp-content/uploads/2016/08/NappingSeal.jpg 1024w"
     data-src="/wp-content/uploads/2016/08/NappingSeal.jpg"
     src="data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDIBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAFEAgAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AJfO3sssMzbewJxUDLJ9sFxBdvG7cMBXGDUNUjfZ5haP0I4q3E2pRjzWj&#43;SvoadI8irVPSI/9LCMbiJpEHVjzVS5tNVlmJWQiP8A2TmuKtru6lkwtud5/iBrtNM1BtJ0p5b9zu6qpNZ&#43;y9mL2vtB1vp16G80h12/e3HitSDxBZ2sbW5nUSj&#43;EVyo8WrqE7Mm5Sp&#43;6D2&#43;lTPFYas6zLIsUy9GrhxOJOrDUiv4h8Y6pFcAWpEaY&#43;9WPp3i67s5HmudpdhncOpqzremXbHdCRImOSBmsKG3hQkSLulHt0rpw3s6tMyq&#43;0p1DtbbxsuoRBDCVm/hzWxBfalc2pJj2rjrnNcTpcIa8jIhy3v0r0NZzb2W0PEVK/MoNeZisL7Ood2Gq&#43;0pnGal4eubuVriAfO3Vs9aof8ACHXL7XkbbN9K6xdbjhR0SBk9BUtvqn7jzHIDe9c3tfZmvsjmLbw1qVipeUB/QZ61aTULuy/djTwo74rpZ5mkstyygs3dRWJGtwk/3WnPp0rT2vtA9kSozXEYMFkQ5&#43;8WrmfEXhm5uW&#43;0TzDYOqn&#43;EV1N3e&#43;XEC29ZOmyM1yurXupi0lgNqzxy9y2SK19kHtDqrvw7bNdb4gAG/hAyKiXQnjk2NxEe&#43;7j8qyLTxI1vD5bSv5nvUsGpq7/AGm5vH4PCA9a9enVqHkVPZmox0&#43;ygdo/9YvGdtcZqgv7zUAbiQmA9Owrr41mu/8ASoXiaFvvRv2q2xjEAika2cdlx0odWpUF7OnTOOt7BYpUe2kVSeCWPWunj8OzT24ZFwT1waakWi3SPFcxBJUPBXit2yntYbRVt7l9o7HmuLEo6sMzM0fRJre9MN9KTAenPIrRu/BmnFi9vJtLdzzUl3qds9rguD/eOMEVy&#43;peKo7K28u2JmJPXPSrp/ul7QdXX92bq6PbWRVmdiqjG4Ckvm06WDMyyIo/iHGa5GTW9VlgVnLpbt0YdKsprEi2WB5dw5&#43;6H6ms6vtKv7wKShTL0l7pcCqoWZ1/vEU&#43;58Q6SbdIYY8N/EMVSt9VWXEd3prI3qo4q9Pa6V5QcBSX64H3a4atM7adQqf8JHawJsUHPYVaTUpGgV3kID9h2rLPhS0muvtMN3kN0BqyugRtujkuc/3cNWQCS3cMSrNbHe3O4SVXkv7q/jjTyI4grZO48NV/TtB021nZri8z6R7qlu0017tIYDhB949TWtKqBy0sgaYzXIRPZRWbcXrTS4jVQg9a6HU/Dk91P50UyLu&#43;9G3GKzpvC2pQx/JEsn&#43;6c19F7SmeH7Mpvq1ykXkxzEL/ABbaSLXNiYlj3/7WcGqsumXasQ8TJ68VNBpuBibG/wDhpezD2hbg1e3aTzHSRx/dJrZ0yfUZJd1pDti&#43;8Sx4ArnH068tv3nkfJ2wK0LLV72KPyhlM8dK4aqqVDqpezNHxJ4mjtxFBEwkdvv8VDZNDc7EMUYMndhwK5vX7a6SRJ5EB3fxAVizaheo6hZiNnK4riqYf2h6VOoer31pHY6cqtdxru6IelV00mKSIPDcxyFV3HHQV5Pd6vfXjgXFw7BfU10eg&#43;JIrLTpYJGJdud2a09k7B7Q66G&#43;uobgFH&#43;VfvAjit2TV7OO0DMkQdhydteWv4lIvfMGfL9K0hrcl9YTGPYoA4c9R7Vl7MPaHWQX1hfOsk0626KcYPGah1a/0mwePy38wtwGR6p&#43;DNPstYieK8TzZhymTirJ&#43;Hl5JqjTyKnkBvlQGsqvsqYeyqGJPe3MoIgiC7TxKTzU2mw6hft5MOWuG4L&#43;lb2p&#43;F71kENtEscQ6t1JrT0uBdFhj2BvMb/WOR0rL6zSNfq1QzXvU1FWF3&#43;5kb&#43;PsajstH1lboNZXm5D935sisqLWbsWYhubeMoRwzDkVZ0jUpbS&#43;SXzS0f91Tivofq1RHh&#43;0pkl7Jf2ayxX0RaQtnIFZiuLyRdsZVx6816Bf6lY3FirSKCpHQjJrm45re0JNvDuz3Ip4ap7TcVX92Vrdrm3O4uHX&#43;5jIFdZoljHqqCe5so0VOjAY3VU8OLLf3TO0ASEdSV6129rEoj2KoVF7VyY/E&#43;z/hnVhaXtDN1DQrC&#43;g2z2qEYwuB0rzPxB8N&#43;XuNPf/gJr1&#43;46YFUJLfNeJ7arTPcVJHz5rngzUdLsY7143KN97jpXM8x819T3lvb3WltZXK5jbrxXjviLwiFvbmbT7ZmtlP3cV3UsV&#43;7OarS/eHnwlD4qdJzFwG4NOu7Fo2INu8Z9xVT7PN/dOK0uZ2O28M6tJZalazA8bgK94in8yJG/vDNfNejGY3cAKHaGBr3LSdejeJIZvlYADdXm1aR20jpCAR0qGWNChzEp/ClEwaPKnNRmWuU2PGI7NL4qTegr39q0rW302CQRfbFJ/vVzD3uIRFAmxf4jUunQrJPuYnFfc7nx&#43;x2pUQxN5U6yoPXtU2l6dNqd2irOjRfx47VV0Sxk1G4IRMwLw5rt9OsINPj8q2XA/ib1rlxWJWHp&#43;zOqlS9p&#43;8NK1tI7SNYYseWvf1q7zs&#43;SoYT/AHqs8V81Vdz26SsV&#43;T9&#43;kNSyD&#43;61IelZGxXIQn1pkkCYIEa4PXip0AJNBjNZmntDndR8PWF&#43;xEluob&#43;8ornrrwInJg2/7pFd8Y8VHjml7WqaWR5U/h&#43;4sZdskG3HcCrMXmL7Yr0mWNX/ANYqv&#43;FZtxolpMGwuxj6V008T3OerSMLTdbktSFkO5K6aGeO6j8xD8tc7c&#43;HpI/9Q26pdNs7&#43;zmbf/q&#43;9Z1fZ1Ape0PII/uGtex/1BrIj&#43;4a17H/AFBr7WB8pUPRPh//AMg27&#43;tdPDXMfD//AJBt39a6eGvDzL&#43;IerhP4Rbj71ab7q1Vj71ab7q15Uj0YiDpQ/3qB0of71ZmhFD/AK9qmk6ioYf9e1TSdRUgQvULfdqZ6hb7tQbkbdTTf4qc3U03&#43;KskUxg&#43;81DdGoH3mobo1CHE/9k="
     data-sizes="auto"
     width="1024" alt="A harbor seal napping in the sun at the bottom of a set of steps to the water."
     loading="lazy" />



  </a><figcaption>This little guy and an older buddy spend lots of time in the sun on these steps behind the opera house – they are well known locally, but I had no idea they were there until we were walking around.</figcaption></figure>

<p>For me the best moments are those gems you find when you take the time to explore ideas and view points and discover something totally new. Nothing beats travel to help you remember to change your perspective now and again.</p>
]]></content:encoded> </item> </channel>
</rss>
