Jekyll2021-04-12T22:50:41+00:00https://jacquelinepotts.com/feed.xmlJacqueline PottsJust a regular old blogDjango ORM for the Rails Developer Part 22019-11-16T15:07:10+00:002019-11-16T15:07:10+00:00https://jacquelinepotts.com/django-orm-for-the-rails-developer-part-two<p>Hello and welcome back! On today’s exciting edition of Django ORM for the Rails Developer, we will be taking a peek at some more complex and snazzy querying, topics include: querying using comparison evaluators, querying for objects created within a certain time period, using straight up SQL in the ORMs, and more!</p>
<p>Let’s get crackin’ and jump back into our blog</p>
<hr />
<h1 id="using-comparators-to-query-for-our-most-popular-and-least-popular-posts">Using Comparators to Query for our Most Popular and Least Popular Posts</h1>
<p>Remember our <code class="language-plaintext highlighter-rouge">Post</code> model from the previous Django ORM post? Let’s bring that puppy back here and let’s add a new attribute, <code class="language-plaintext highlighter-rouge">likes</code>, and for now, let’s say <code class="language-plaintext highlighter-rouge">likes</code> is an integer. A user that comes to our blog and reads a post can <code class="language-plaintext highlighter-rouge">like</code> said post if they enjoyed it, kind of like a +1.</p>
<p>First step, let’s grab our most popular posts from the database; give us all the posts that have at least 5 likes.
<br />
<br /></p>
<h2 id="rails---activerecord">Rails - ActiveRecord</h2>
<div class="language-irb highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">irb(main):001:0></span><span class="w"> </span><span class="no">Post</span><span class="p">.</span><span class="nf">where</span><span class="p">(</span><span class="s2">"likes >= ?"</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
<span class="err">
</span><span class="go">Post Load (1.1ms) SELECT "posts".* FROM "posts" WHERE (id >= 5)
</span><span class="p">=></span> <span class="o"><</span><span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Relation</span> <span class="p">[</span><span class="o"><</span><span class="no">Post</span> <span class="ss">id: </span><span class="s2">"3a260dc9-db70-4741-817b-7a69f465624f"</span><span class="p">,</span> <span class="ss">author: </span><span class="s2">"hello there"</span><span class="p">,</span> <span class="ss">likes: </span><span class="mi">5</span><span class="p">,</span> <span class="ss">created_at: </span><span class="s2">"2018-07-31 01:28:41"</span><span class="p">,</span> <span class="ss">updated_at: </span><span class="s2">"2018-07-31 01:30:23"</span><span class="o">></span><span class="p">]</span><span class="o">></span>
</code></pre></div></div>
<p>In English this translates to: ‘give me all the posts that have a value of <code class="language-plaintext highlighter-rouge">like</code> that is greater than or equal to 5’.</p>
<p><code class="language-plaintext highlighter-rouge">where</code> can take multiple different formats of conditions and here we are using a SQL string.
<br />
<br /></p>
<h2 id="wait-a-minute">Wait a minute</h2>
<p>Wait a minute, but what is this <code class="language-plaintext highlighter-rouge">'?'</code> thing doing in our SQL string? The <code class="language-plaintext highlighter-rouge">?</code> is called a placeholder and we use it as a means of protection against SQL injections. Since <code class="language-plaintext highlighter-rouge">where</code> can evaluate SQL, someone could <em>inject</em> some harmful SQL in this function that our database could execute.</p>
<p>For example a malicious person could inject something like</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="no">Post</span><span class="p">.</span><span class="nf">where</span><span class="p">(</span><span class="s2">"likes >= 5; DROP TABLE Users"</span><span class="p">)</span>
</code></pre></div></div>
<p>into our system. The placeholder allows us to protect against SQL we are not expecting.</p>
<p><br />
When in doubt, when using <code class="language-plaintext highlighter-rouge">where</code> with SQL strings use a placeholder!
<br />
Thats great, now if we wanted to only get <code class="language-plaintext highlighter-rouge">posts</code> that had more than 5 likes we could edit our above query pretty easily.</p>
<div class="language-irb highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">irb(main):001:0></span><span class="w"> </span><span class="no">Post</span><span class="p">.</span><span class="nf">where</span><span class="p">(</span><span class="s2">"likes > ?"</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
<span class="err">
</span><span class="go">Post Load (1.1ms) SELECT "posts".* FROM "posts" WHERE (id > 5) LIMIT $1 [["LIMIT", 11]]
</span><span class="p">=></span> <span class="o"><</span><span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Relation</span> <span class="p">[</span><span class="o"><</span><span class="no">Post</span> <span class="ss">id: </span><span class="s2">"3a260dc9-db70-4741-817b-7a69f465624f"</span><span class="p">,</span> <span class="ss">author: </span><span class="s2">"hello there"</span><span class="p">,</span> <span class="ss">likes: </span><span class="mi">6</span><span class="p">,</span> <span class="ss">created_at: </span><span class="s2">"2018-07-31 01:28:41"</span><span class="p">,</span> <span class="ss">updated_at: </span><span class="s2">"2018-07-31 01:30:23"</span><span class="o">></span><span class="p">]</span><span class="o">></span>
</code></pre></div></div>
<p>Boom!</p>
<p><br /></p>
<h2 id="django-orm">Django ORM</h2>
<p>Let’s try and do the same thing in Django; Gimme all posts who have at least 5 likes.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">In</span> <span class="p">[</span><span class="mi">1</span><span class="p">]:</span> <span class="kn">from</span> <span class="nn">posts.models</span> <span class="kn">import</span> <span class="n">Post</span>
<span class="n">In</span> <span class="p">[</span><span class="mi">2</span><span class="p">]:</span> <span class="n">Post</span><span class="p">.</span><span class="n">objects</span><span class="p">.</span><span class="nb">filter</span><span class="p">(</span><span class="n">likes__gte</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>
<span class="n">Out</span><span class="p">[</span><span class="mi">2</span><span class="p">]:</span> <span class="o"><</span><span class="n">QuerySet</span> <span class="p">[</span><span class="o"><</span><span class="n">Post</span><span class="p">:</span> <span class="n">author</span><span class="p">:</span> <span class="n">bloggin_4_life</span><span class="p">,</span> <span class="n">created</span><span class="p">:</span> <span class="mi">2018</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">28</span> <span class="mi">14</span><span class="p">:</span><span class="mi">32</span><span class="p">:</span><span class="mf">19.956328</span><span class="o">+</span><span class="mi">00</span><span class="p">:</span><span class="mi">00</span><span class="p">,</span> <span class="n">likes</span><span class="p">:</span> <span class="mi">5</span><span class="o">></span><span class="p">]</span><span class="o">></span>
</code></pre></div></div>
<p>Here, our <code class="language-plaintext highlighter-rouge">filter</code> friend is back and very similar to the above <code class="language-plaintext highlighter-rouge">where</code> method, <em>filter</em> for all objects that meet this criteria.</p>
<p>We pass in our interested attribute (<code class="language-plaintext highlighter-rouge">likes</code>) and can use Django’s double underscore syntax to evaluate some fun stuff (we will explore this more later), but for here <code class="language-plaintext highlighter-rouge">__gte</code> translates to <code class="language-plaintext highlighter-rouge">greater than equal to</code>. We also have <code class="language-plaintext highlighter-rouge">__gt</code> which translates to <code class="language-plaintext highlighter-rouge">greater than</code></p>
<p>Give me all the posts who have greater than 5 likes</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">In</span> <span class="p">[</span><span class="mi">1</span><span class="p">]:</span> <span class="kn">from</span> <span class="nn">posts.models</span> <span class="kn">import</span> <span class="n">Post</span>
<span class="n">In</span> <span class="p">[</span><span class="mi">2</span><span class="p">]:</span> <span class="n">Post</span><span class="p">.</span><span class="n">objects</span><span class="p">.</span><span class="nb">filter</span><span class="p">(</span><span class="n">likes__gt</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>
<span class="n">Out</span><span class="p">[</span><span class="mi">2</span><span class="p">]:</span> <span class="o"><</span><span class="n">QuerySet</span> <span class="p">[</span><span class="o"><</span><span class="n">Post</span><span class="p">:</span> <span class="n">author</span><span class="p">:</span> <span class="n">bloggin_4_life</span><span class="p">,</span> <span class="n">created</span><span class="p">:</span> <span class="mi">2018</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">28</span> <span class="mi">14</span><span class="p">:</span><span class="mi">32</span><span class="p">:</span><span class="mf">19.956328</span><span class="o">+</span><span class="mi">00</span><span class="p">:</span><span class="mi">00</span><span class="p">,</span> <span class="n">likes</span><span class="p">:</span> <span class="mi">7</span><span class="o">></span><span class="p">]</span><span class="o">></span>
</code></pre></div></div>
<p><br />
Easy Peasy 💻
<br />
<br /></p>
<hr />
<h2 id="rails---activerecord-1">Rails - ActiveRecord</h2>
<p>If we wanted to turn this around and get our least popular blog posts how do you think we would go about doing that?</p>
<div class="language-irb highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">irb(main):001:0></span><span class="w"> </span><span class="no">Post</span><span class="p">.</span><span class="nf">where</span><span class="p">(</span><span class="s2">"likes <= ?"</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
<span class="err">
</span><span class="go">Post Load (1.1ms) SELECT "posts".* FROM "posts" WHERE (id <= 5)
</span><span class="p">=></span> <span class="o"><</span><span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Relation</span> <span class="p">[</span><span class="o"><</span><span class="no">Post</span> <span class="ss">id: </span><span class="s2">"3a260dc9-db70-4741-817b-7a69f465624f"</span><span class="p">,</span> <span class="ss">author: </span><span class="s2">"hello there"</span><span class="p">,</span> <span class="ss">likes: </span><span class="mi">4</span><span class="p">,</span> <span class="ss">created_at: </span><span class="s2">"2018-07-31 01:28:41"</span><span class="p">,</span> <span class="ss">updated_at: </span><span class="s2">"2018-07-31 01:30:23"</span><span class="o">></span><span class="p">]</span><span class="o">></span>
</code></pre></div></div>
<p>Which will generate the following SQL</p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="nv">`posts`</span><span class="p">.</span><span class="o">*</span> <span class="k">FROM</span> <span class="nv">`posts`</span> <span class="k">WHERE</span> <span class="p">(</span><span class="nv">`posts`</span><span class="p">.</span><span class="nv">`id`</span> <span class="o"><=</span> <span class="mi">5</span><span class="p">)</span>
</code></pre></div></div>
<p>Give us all the posts that have 5 or less likes.</p>
<p><br />
If we wanted to get exclusively less than 5 we will do just as we did above to modify the comparator by removing the <code class="language-plaintext highlighter-rouge">=</code> from the query.</p>
<div class="language-irb highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">irb(main):001:0></span><span class="w"> </span><span class="no">Post</span><span class="p">.</span><span class="nf">where</span><span class="p">(</span><span class="s2">"likes < ?"</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
<span class="err">
</span><span class="go">Post Load (1.1ms) SELECT "posts".* FROM "posts" WHERE (id < 5)
</span><span class="p">=></span> <span class="o"><</span><span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Relation</span> <span class="p">[</span><span class="o"><</span><span class="no">Post</span> <span class="ss">id: </span><span class="s2">"3a260dc9-db70-4741-817b-7a69f465624f"</span><span class="p">,</span> <span class="ss">author: </span><span class="s2">"hello there"</span><span class="p">,</span> <span class="ss">likes: </span><span class="mi">4</span><span class="p">,</span> <span class="ss">created_at: </span><span class="s2">"2018-07-31 01:28:41"</span><span class="p">,</span> <span class="ss">updated_at: </span><span class="s2">"2018-07-31 01:30:23"</span><span class="o">></span><span class="p">]</span><span class="o">></span>
</code></pre></div></div>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="nv">`posts`</span><span class="p">.</span><span class="o">*</span> <span class="k">FROM</span> <span class="nv">`posts`</span> <span class="k">WHERE</span> <span class="p">(</span><span class="nv">`posts`</span><span class="p">.</span><span class="nv">`id`</span> <span class="o"><</span> <span class="mi">5</span><span class="p">)</span>
</code></pre></div></div>
<hr />
<h2 id="did-you-know">Did you know?</h2>
<p>Its time for a <strong>did you know?</strong> break!</p>
<p>Rails gives us the raw SQL used to execute our queries by default. Django does not give us this information by default, we will need to ask Django nicely to show us the raw SQL that will be executed by our query using the <code class="language-plaintext highlighter-rouge">query</code> function.</p>
<p>Note this function will only work on a Django QuerySet object.</p>
<p><br />
<strong>Output of a Regular old Django Query</strong></p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">In</span> <span class="p">[</span><span class="mi">1</span><span class="p">]:</span> <span class="kn">from</span> <span class="nn">posts.models</span> <span class="kn">import</span> <span class="n">Post</span>
<span class="n">In</span> <span class="p">[</span><span class="mi">2</span><span class="p">]:</span> <span class="n">Post</span><span class="p">.</span><span class="n">objects</span><span class="p">.</span><span class="nb">filter</span><span class="p">(</span><span class="n">likes__gte</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>
<span class="n">Out</span><span class="p">[</span><span class="mi">2</span><span class="p">]:</span> <span class="o"><</span><span class="n">QuerySet</span> <span class="p">[</span><span class="o"><</span><span class="n">Post</span><span class="p">:</span> <span class="n">author</span><span class="p">:</span> <span class="n">bloggin_4_life</span><span class="p">,</span> <span class="n">created</span><span class="p">:</span> <span class="mi">2018</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">28</span> <span class="mi">14</span><span class="p">:</span><span class="mi">32</span><span class="p">:</span><span class="mf">19.956328</span><span class="o">+</span><span class="mi">00</span><span class="p">:</span><span class="mi">00</span><span class="p">,</span> <span class="n">updated</span><span class="p">:</span> <span class="mi">2018</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">30</span> <span class="mi">19</span><span class="p">:</span><span class="mi">23</span><span class="p">:</span><span class="mf">19.956328</span><span class="o">+</span><span class="mi">00</span><span class="p">:</span><span class="mi">00</span><span class="p">,</span> <span class="n">likes</span><span class="p">:</span> <span class="mi">7</span><span class="o">></span><span class="p">]</span><span class="o">></span>
</code></pre></div></div>
<p><br /></p>
<p><strong>Print the output of <code class="language-plaintext highlighter-rouge">query</code> function on a Regular old Django QuerySet</strong></p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">In</span> <span class="p">[</span><span class="mi">1</span><span class="p">]:</span> <span class="kn">from</span> <span class="nn">posts.models</span> <span class="kn">import</span> <span class="n">Post</span>
<span class="n">In</span> <span class="p">[</span><span class="mi">2</span><span class="p">]:</span> <span class="n">popular_posts</span> <span class="o">=</span> <span class="n">Post</span><span class="p">.</span><span class="n">objects</span><span class="p">.</span><span class="nb">filter</span><span class="p">(</span><span class="n">likes__gte</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>
<span class="n">In</span> <span class="p">[</span><span class="mi">3</span><span class="p">]:</span> <span class="k">print</span><span class="p">(</span><span class="n">popular_posts</span><span class="p">.</span><span class="n">query</span><span class="p">)</span>
<span class="n">Out</span><span class="p">[</span><span class="mi">2</span><span class="p">]:</span> <span class="n">SELECT</span> <span class="n">post</span><span class="p">.</span><span class="nb">id</span><span class="p">,</span> <span class="n">post</span><span class="p">.</span><span class="n">created</span><span class="p">,</span> <span class="n">post</span><span class="p">.</span><span class="n">updated</span><span class="p">,</span> <span class="n">post</span><span class="p">.</span><span class="n">author</span><span class="p">,</span> <span class="n">post</span><span class="p">.</span><span class="n">likes</span> <span class="n">FROM</span> <span class="n">post</span> <span class="n">WHERE</span> <span class="n">post</span><span class="p">.</span><span class="n">likes</span> <span class="o">>=</span> <span class="mi">5</span>
</code></pre></div></div>
<p><br />
<br />
Alright, now get out there and write some queries!</p>jacquelinepottsHello and welcome back! On today’s exciting edition of Django ORM for the Rails Developer, we will be taking a peek at some more complex and snazzy querying, topics include: querying using comparison evaluators, querying for objects created within a certain time period, using straight up SQL in the ORMs, and more!Reducing Risks of Burnout in Yourself and Others2019-03-21T20:45:10+00:002019-03-21T20:45:10+00:00https://jacquelinepotts.com/reducing-burnout-in-yourself-and-others<p>Working with software is stressful and weird sometimes but does it need to be? Well sometimes, yes, but there are definitely ways to protect yourself and others from late night support calls, deploys-gone-wrong, and general on-the-job stress. Remember you are going to be a software engineer for a long time, take care of your mental health for the sake of the longevity of your career and reduce the risk of mental burnout or <strong>I will come over there and yell at you</strong>.</p>
<h1 id="what-is-burnout-anyway">What is burnout anyway?</h1>
<p>Burnout is not your friend.
<em>According to www.helpguide.org:</em></p>
<blockquote>
<p>Burnout is a state of emotional, physical, and mental exhaustion caused by excessive and prolonged stress. Symptoms of burnout include but are not limited to fatigue, insomnia, impared concentration, isolation, increased illness, anxiety, and depression.</p>
</blockquote>
<p>Burnout in engineers can often lead to sloppy, stressed, and buggy code with increased engineer sickness.
Engineers perform their best when they are feeling healthy and happy, let’s talk about some ways to keep yourself happy and healthy at home and on the job.</p>
<hr />
<h1 id="ways-to-protect-yourself-on-the-job">Ways to protect yourself on the job</h1>
<h2 id="enlist-the-help-of-friendly-robots">Enlist the help of friendly robots</h2>
<p>Set up alerting and dashboards for critical user flows such as user login, user registration, payment processing, anything else that is dire functionality to your application aka it would be a literal disaster if it was borked.</p>
<iframe src="https://giphy.com/embed/UQYtr98lNNrWw" width="480" height="204" frameborder="0" class="giphy-embed" allowfullscreen=""></iframe>
<p>These dashboards can alert you when your application exceeds a determined error threshold, when the throughput of traffic to your site increases at a certain rate, and more.</p>
<p>Letting robots monitor these gives us a few pros:</p>
<ol>
<li><strong>Peace of mind</strong> - you don’t need to sit and monitor systems yourself</li>
<li><strong>Historical data</strong> - did this issue happen before? I thought I fixed this, why is it back?</li>
<li><strong>MOAR CONTROL</strong></li>
</ol>
<p>Alerting is what you make of it, but to elaborate on point #3, we have more control in the feedback cycle for production issues. Instead of having your CEO call your cell phone at 2:30am with an issue, have your robots find the issue and contact you first. Directing the issue to the correct team allows the team with the most context to debug and asses the issue as soon as possible. The engineering team can asses if this is a true emergency or just a bug that affects 2% of your user-base that can be fixed in the next sprint. Use data to determine the level of urgency an issue requires.</p>
<p>You will also have more control on <em>what</em> data the alert contains - giving your team more focus and more chances for a quick recovery. This is especially helpful if your projects live across separate services.</p>
<p>It is really not fun for anyone to have user’s calling in and reporting issues to your customer service team, user’s upset and complaining on social media, or having a member of your executive team find bugs first. Reduce stress by creating an alerting system to monitor your systems and alert the proper people at the proper times.</p>
<h2 id="recognize-flaws-in-process-and-be-an-advocate-for-improvement">Recognize flaws in process and be an advocate for improvement</h2>
<p>Not everything is your responsibility, software fails when processes fail.
If a bug in some code you wrote makes it to production, there is probably an opportunity to improve the processes used by your team.</p>
<ul>
<li>Why wasn’t this bug caught by your test suite?</li>
<li>Why wasn’t this bug caught by code review?</li>
<li>Why wasn’t this bug caught by the running of CI/CD?</li>
<li>Why wasn’t this bug caught by acceptance testing on a staging environment?</li>
<li>Why wasn’t this bug caught by QA testing?</li>
</ul>
<p>Advocate for retrospectives to discuss improvements for process in a safe, nonjudgmental space.</p>
<h2 id="ask-for-help-">Ask for help 💙</h2>
<p>Asking for help is a completely natural part of the learning process. You are not invincible and never feel ashamed for leaning on others for help.</p>
<p>Buy a co-worker coffee and tell them how you’re feeling and ask if they have any advice for you. Meet a friend out for lunch and tell them how you’re feeling. Find a mentor or find an executive coach or find a therapist.</p>
<h2 id="make-your-workspace-as-gorgeous-as-you">Make your workspace as gorgeous as you</h2>
<p>Make your desk area a happy place that makes you feel good and your soul smile; you’re not-so-private oasis at the office. Cover your desk with pictures of friends, loved ones, dogs, squishy toys, stress toys AND LOTS OF PLANTS!</p>
<iframe src="https://giphy.com/embed/l0MYII7vx3jZTG3Oo" width="480" height="480" frameborder="0" class="giphy-embed" allowfullscreen=""></iframe>
<h2 id="take-breaks-please">Take breaks please</h2>
<p>Don’t forget to take regular breaks during your work day and try your best to separate eating meals from your computer. Developing software is such a brain intensive task, it is really easy to lose sight of your posture and physical signs of stress when you’re in the zone. Taking breaks will help alleviate some of those risk factors. Breaks will also give your brain some time to digest and process what the code you were just working on.</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">Reminder: ‘Going for a walk’ is a pro debugging technique.</p>— Kris Jenkins (@krisajenkins) <a href="https://twitter.com/krisajenkins/status/931190678503219200?ref_src=twsrc%5Etfw">November 16, 2017</a></blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>Take a lunch break away from your desk and computer.
Take walk breaks and bring a buddy!</p>
<p>Use tools, like <a href="https://en.wikipedia.org/wiki/Pomodoro_Technique">pomodoros</a>, to keep you accountable on taking breaks and help you maintain focus.</p>
<hr />
<h1 id="ways-to-protect-yourself-at-home">Ways to protect yourself at home</h1>
<h2 id="designated-self-care-days">Designated self-care days</h2>
<p>Schedule a day during the week where you take care of yourself and wellbeing. Do some of your favorite hobbies, take a bubble bath, get outside, go on an adventure, read a book, it’s up to you!</p>
<p>I used to get very stressed and triggered by the Sunday Scaries so I made Sunday my self-care day! It has been really helpful, now I can look forward to Sundays and just have a lovely day of horseback riding and cleaning up horse poop (it’s the best!).</p>
<iframe src="https://giphy.com/embed/nTuwEDB7lBYJy" width="480" height="360" frameborder="0" class="giphy-embed" allowfullscreen=""></iframe>
<h2 id="spend-some-time-with-the-love-of-your-life">Spend some time with the love of your life</h2>
<p>Spend time with people (or animals) whom you love most. Set up regurarly scheduled date nights with your partner, set up adventures with friends nights every Wednesday. The thing about stress is it tries to isolate you from those around you, fight that instinct.</p>
<p>For me, I spend Saturdays hiking with my #1, my dog Molly Dog and Fridays volunteering and the Colorado Horse Rescue. It’s not weird if your favorite people are animals, right? PS, please don’t tell my husband I said all these things.
<br />
<br /></p>
<div class="toright">
<img class="image" src="../assets/images/molly-the-dog.jpg" alt="Alt Text" />
<figcaption class="caption">The stunning Molly Dog</figcaption>
</div>
<p><br /></p>
<p><strong>Lean on those around you.</strong></p>
<h2 id="set-up-some-boundaries-for-yourself">Set up some boundaries for yourself</h2>
<p>Contrary to popular belief, software engineers are not robots. It is okay for you to set up some boundaries to give yourself time to rest and repair.</p>
<p>Set some goals for yourself, no slack or work email when I get home at night, no slack or email on the weekends. If you must work after work hours or on the weekend limit yourself. ‘Okay, I am only going to work and think about work this Saturday from 1:30pm - 3:00pm’.</p>
<hr />
<p><strong>TLDR;</strong>
<br />
🚨 Reminder Alert 🚨: taking care of yourself is not selfish. If you are ever having issues with stress please please please do not keep it to yourself. Your community is here for you and we want to help.</p>jacquelinepottsWorking with software is stressful and weird sometimes but does it need to be? Well sometimes, yes, but there are definitely ways to protect yourself and others from late night support calls, deploys-gone-wrong, and general on-the-job stress. Remember you are going to be a software engineer for a long time, take care of your mental health for the sake of the longevity of your career and reduce the risk of mental burnout or I will come over there and yell at you.Django ORM for the Rails Developer Part 12019-03-04T20:45:10+00:002019-03-04T20:45:10+00:00https://jacquelinepotts.com/django-orm-for-the-rails-developer-part-1<p>Querying with the Django ORM: how do we do it? What journeys lie ahead of us? Which queries are more efficient and put less load on a database? Coming from an ActiveRecord and Rails background, the transition and answers to these questions are still an ongoing journey. Below we will discuss some fun queries in Rails and how those might translate to Django; Django ORM for people who aren’t familiar with the Django ORM. Photographed above, meet our household’s #1, Django the cat.</p>
<p>For the purposes of this post, let’s say we are working on a blog. We will be working side by side with a Rails application with a PostgreSQL database and a Django application with a PostgreSQL database.</p>
<hr />
<h1 id="entering-the-console">Entering the Console</h1>
<p>Before we get started we will need to enter the console of our applications</p>
<p>To enter the Rails console we will be using the command</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bundle exec rails console
</code></pre></div></div>
<p>To enter the Django console we will be using the command</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./manage.py shell
</code></pre></div></div>
<p><br /></p>
<h1 id="querying-for-a-single-object">Querying for a Single Object</h1>
<p>One of the cornerstones of web development is the ability to read and return data from a database.</p>
<p>So let’s get to it, for our first task we want to return a single record in our database: we want to return one <code class="language-plaintext highlighter-rouge">post</code> that has an <code class="language-plaintext highlighter-rouge">id=1</code>.
<br />
<br /></p>
<h2 id="rails---activerecord">Rails - ActiveRecord</h2>
<p><strong><code class="language-plaintext highlighter-rouge">find</code></strong></p>
<div class="language-irb highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">irb(main):003:0></span><span class="w"> </span><span class="no">Post</span><span class="p">.</span><span class="nf">find</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="err">
</span><span class="go">[2019-03-04T00:01:56.094388 #4] DEBUG -- : Post Load (1.2ms) SELECT "posts".* FROM "posts" WHERE "posts"."id" = $1 LIMIT $2 [["id", "1"], ["LIMIT", 1]]
</span><span class="p">=></span> <span class="o"><</span><span class="c1">#Post id: "1", author: blogger-jim, live_at: "2018-12-11 16:00:34", created_at: "2018-12-11 04:13:54", updated_at: "2018-12-11 16:00:34", heading: "Just a regular old blog post"></span>
</code></pre></div></div>
<p>In the console, ActiveRecord will show us what <code class="language-plaintext highlighter-rouge">SQL</code> it has run to execute the given query.</p>
<p>Now if we query for a <code class="language-plaintext highlighter-rouge">post</code> with an <code class="language-plaintext highlighter-rouge">id=7</code> that does not exist in our database, ActiveRecord will let us know by alerting us with a handy <code class="language-plaintext highlighter-rouge">ActiveRecord::RecordNotFound</code> error:</p>
<div class="language-irb highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">irb(main):003:0></span><span class="w"> </span><span class="no">Post</span><span class="p">.</span><span class="nf">find</span><span class="p">(</span><span class="mi">7</span><span class="p">)</span>
<span class="err">
</span><span class="go">Post Load (0.8ms) SELECT "posts".* FROM "posts" WHERE "posts"."id" = $1 LIMIT $2 [["id", nil], ["LIMIT", 1]]
Traceback (most recent call last):
1: from (irb):1
</span><span class="err">
</span><span class="go">ActiveRecord::RecordNotFound (Couldnt find Post with 'id'=7)
</span></code></pre></div></div>
<p>Sound the alarm friends, there is no such object here!
<br />
<br /></p>
<h2 id="django-orm">Django ORM</h2>
<p><strong><code class="language-plaintext highlighter-rouge">get</code></strong></p>
<p>Now, let’s try the same thing in our Django blog, we want to return one <code class="language-plaintext highlighter-rouge">post</code> that has an <code class="language-plaintext highlighter-rouge">id=1</code>.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">In</span> <span class="p">[</span><span class="mi">1</span><span class="p">]:</span> <span class="kn">from</span> <span class="nn">posts.models</span> <span class="kn">import</span> <span class="n">Post</span>
<span class="n">In</span> <span class="p">[</span><span class="mi">2</span><span class="p">]:</span> <span class="n">Post</span><span class="p">.</span><span class="n">objects</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="n">pk</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="n">Out</span><span class="p">[</span><span class="mi">2</span><span class="p">]:</span> <span class="o"><</span><span class="n">Post</span><span class="p">:</span> <span class="n">Post</span> <span class="n">author</span><span class="p">:</span> <span class="n">blogger</span><span class="o">-</span><span class="n">jim</span><span class="p">,</span> <span class="n">created</span><span class="p">:</span> <span class="mi">2018</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">28</span> <span class="mi">14</span><span class="p">:</span><span class="mi">32</span><span class="p">:</span><span class="mf">19.956328</span><span class="o">+</span><span class="mi">00</span><span class="p">:</span><span class="mi">00</span><span class="o">></span>
</code></pre></div></div>
<p>Right off the bat, three things are sticking out to me in my Rails brain, we need to import models into the console?, <code class="language-plaintext highlighter-rouge">.objects</code>?, and what is a <code class="language-plaintext highlighter-rouge">pk</code>?</p>
<ol>
<li>
<p>What is this importing all about?
<br />
Unlike the Rails console that loads the the majority of the application upon loading, the Django shell requires us to <code class="language-plaintext highlighter-rouge">import</code> the models, functions, and anything else we want to interact with during our session in the shell.</p>
</li>
<li>
<p>What is this <code class="language-plaintext highlighter-rouge">.objects</code> deal?
<br />
TLDR; When using Django, <code class="language-plaintext highlighter-rouge">objects</code> is the <em>Manager</em> of the model, we won’t get into too much detail on managers now, but think of a manager as a class method.</p>
</li>
</ol>
<p>For our purposes, when you see the <code class="language-plaintext highlighter-rouge">.objects</code> call on the <code class="language-plaintext highlighter-rouge">Post</code> model, we are querying the instances of the objects within that class.</p>
<ol>
<li>What in tarnation is a <code class="language-plaintext highlighter-rouge">pk</code>?
<br />
<code class="language-plaintext highlighter-rouge">pk</code> is the object’s <strong>primary key</strong>,
aka the <code class="language-plaintext highlighter-rouge">id</code> of the object in Rails,
aka the database id for the object.</li>
</ol>
<p>In Django, the convention prefers the use of <code class="language-plaintext highlighter-rouge">pk</code> over <code class="language-plaintext highlighter-rouge">id</code>.</p>
<div class="breaker"></div>
<p>If we run the same query using looking for a <code class="language-plaintext highlighter-rouge">pk</code> that does not exist in our database, we will get an error similar to this:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">DoesNotExist</span> <span class="n">Traceback</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">)</span>
<span class="o"><</span><span class="n">ipython</span><span class="o">-</span><span class="nb">input</span><span class="o">-</span><span class="mi">2</span><span class="o">-</span><span class="n">eb4715ec5410</span><span class="o">></span> <span class="ow">in</span> <span class="o"><</span><span class="n">module</span><span class="o">></span>
<span class="o">----></span> <span class="mi">1</span> <span class="n">Post</span><span class="p">.</span><span class="n">objects</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="n">pk</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="o">~/</span><span class="p">.</span><span class="n">virtualenvs</span><span class="o">/</span><span class="n">django</span><span class="o">-</span><span class="n">api</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">python3</span><span class="p">.</span><span class="mi">6</span><span class="o">/</span><span class="n">site</span><span class="o">-</span><span class="n">packages</span><span class="o">/</span><span class="n">django</span><span class="o">/</span><span class="n">db</span><span class="o">/</span><span class="n">models</span><span class="o">/</span><span class="n">manager</span><span class="p">.</span><span class="n">py</span> <span class="ow">in</span> <span class="n">manager_method</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="mi">80</span> <span class="k">def</span> <span class="nf">create_method</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">method</span><span class="p">):</span>
<span class="mi">81</span> <span class="k">def</span> <span class="nf">manager_method</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="o">---></span> <span class="mi">82</span> <span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">get_queryset</span><span class="p">(),</span> <span class="n">name</span><span class="p">)(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="mi">83</span> <span class="n">manager_method</span><span class="p">.</span><span class="n">__name__</span> <span class="o">=</span> <span class="n">method</span><span class="p">.</span><span class="n">__name__</span>
<span class="mi">84</span> <span class="n">manager_method</span><span class="p">.</span><span class="n">__doc__</span> <span class="o">=</span> <span class="n">method</span><span class="p">.</span><span class="n">__doc__</span>
<span class="o">~/</span><span class="p">.</span><span class="n">virtualenvs</span><span class="o">/</span><span class="n">django</span><span class="o">-</span><span class="n">api</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">python3</span><span class="p">.</span><span class="mi">6</span><span class="o">/</span><span class="n">site</span><span class="o">-</span><span class="n">packages</span><span class="o">/</span><span class="n">django</span><span class="o">/</span><span class="n">db</span><span class="o">/</span><span class="n">models</span><span class="o">/</span><span class="n">query</span><span class="p">.</span><span class="n">py</span> <span class="ow">in</span> <span class="n">get</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="mi">397</span> <span class="k">raise</span> <span class="bp">self</span><span class="p">.</span><span class="n">model</span><span class="p">.</span><span class="n">DoesNotExist</span><span class="p">(</span>
<span class="mi">398</span> <span class="s">"%s matching query does not exist. %"</span>
<span class="o">--></span> <span class="mi">399</span> <span class="bp">self</span><span class="p">.</span><span class="n">model</span><span class="p">.</span><span class="n">_meta</span><span class="p">.</span><span class="n">object_name</span>
<span class="mi">400</span> <span class="p">)</span>
<span class="mi">401</span> <span class="k">raise</span> <span class="bp">self</span><span class="p">.</span><span class="n">model</span><span class="p">.</span><span class="n">MultipleObjectsReturned</span><span class="p">()</span>
<span class="n">DoesNotExist</span><span class="p">:</span> <span class="n">Post</span> <span class="n">matching</span> <span class="n">query</span> <span class="n">does</span> <span class="ow">not</span> <span class="n">exist</span><span class="p">.</span>
</code></pre></div></div>
<hr />
<h1 id="querying-for-a-single-object---without-raising-errors-and-exploding-everywhere">Querying for a Single Object - Without Raising Errors and Exploding Everywhere</h1>
<p>Now, our first few examples were all fine and dandy but there will be instances when if we don’t find a record in our database we don’t want an exception to be raised.
<br /></p>
<h2 id="rails---activerecord-1">Rails - ActiveRecord</h2>
<p><strong><code class="language-plaintext highlighter-rouge">where</code></strong></p>
<div class="language-irb highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">irb(main):004:0></span><span class="w"> </span><span class="no">Post</span><span class="p">.</span><span class="nf">where</span><span class="p">(</span><span class="ss">id: </span><span class="mi">1</span><span class="p">)</span>
<span class="go">[2019-03-04T00:07:53.498783 #4] DEBUG -- : Post Load (0.9ms) SELECT "posts".* FROM "posts" WHERE "posts"."id" = $1 LIMIT $2 [["id", "1"], ["LIMIT", 11]]
</span><span class="err">
</span><span class="p">=></span> <span class="o"><</span><span class="c1">#ActiveRecord::Relation [<#Post id: 1, author: blogger-jim, live_at: "2018-12-11 16:00:34", created_at: "2018-12-11 04:13:54", updated_at: "2018-12-11 16:00:34", heading: "Just a regular old blog post">]></span>
</code></pre></div></div>
<p>Something special to note here, take a look at the output we are getting from this query. When using the <code class="language-plaintext highlighter-rouge">where</code> clause, ActiveRecord will return an <code class="language-plaintext highlighter-rouge">ActiveRecord::Relation</code> object, which for the purposes of this blog post, is like a special ActiveRecord array.</p>
<p>Arrays, eh? So what happens if we write a <code class="language-plaintext highlighter-rouge">.where</code> query that returns nothing?</p>
<div class="language-irb highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">irb(main):007:0></span><span class="w"> </span><span class="no">Post</span><span class="p">.</span><span class="nf">where</span><span class="p">(</span><span class="ss">id: </span><span class="mi">100</span><span class="p">)</span>
<span class="go">[2019-03-04T00:14:49.323594 #4] DEBUG -- : Post Load (1.0ms) SELECT "posts".* FROM "posts" WHERE "posts"."id" IS NULL LIMIT $1 [["LIMIT", 11]]
</span><span class="err">
</span><span class="p">=></span> <span class="o"><</span><span class="c1">#ActiveRecord::Relation []></span>
</code></pre></div></div>
<p>Note we still get an <code class="language-plaintext highlighter-rouge">ActiveRecord::Relation</code> object back, but we can see here it returns an empty array if nothing on the database side matches this query. In our code, we will just need to handle an empty array and can skip the error parsing that the <code class="language-plaintext highlighter-rouge">.find</code> queries will get you.</p>
<p>Unlike with <code class="language-plaintext highlighter-rouge">.find</code>, using <code class="language-plaintext highlighter-rouge">where</code> means we get to query by all sorts of attributes not just <code class="language-plaintext highlighter-rouge">id</code>:</p>
<div class="language-irb highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">irb(main):004:0></span><span class="w"> </span><span class="no">Post</span><span class="p">.</span><span class="nf">where</span><span class="p">(</span><span class="ss">author: </span><span class="s2">"blogger-jim"</span><span class="p">)</span>
<span class="go">[2019-03-04T00:07:53.498783] DEBUG -- : Post Load (0.9ms) SELECT "posts".* FROM "posts" WHERE "posts"."author" = $1 LIMIT $2 [["author", "blogger-jim"], ["LIMIT", 11]]
</span><span class="err">
</span><span class="p">=></span> <span class="o"><</span><span class="c1">#ActiveRecord::Relation [<#Post id: 1, author: "blogger-jim", live_at: "2018-12-11 16:00:34", created_at: "2018-12-11 04:13:54", updated_at: "2018-12-11 16:00:34", heading: "Just Breathe">]></span>
</code></pre></div></div>
<p><code class="language-plaintext highlighter-rouge">where</code> may also return multiple objects from the database, while our find friend will only ever return a single object.
<br />
<br /></p>
<h2 id="django-orm-1">Django ORM</h2>
<p><strong><code class="language-plaintext highlighter-rouge">filter</code></strong></p>
<p>To mimic the behavior we get with <code class="language-plaintext highlighter-rouge">.where</code> in Rails, we can use the <code class="language-plaintext highlighter-rouge">.filter</code> function in the Django ORM.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">In</span> <span class="p">[</span><span class="mi">1</span><span class="p">]:</span> <span class="kn">from</span> <span class="nn">posts.models</span> <span class="kn">import</span> <span class="o">*</span>
<span class="n">In</span> <span class="p">[</span><span class="mi">2</span><span class="p">]:</span> <span class="n">Post</span><span class="p">.</span><span class="n">objects</span><span class="p">.</span><span class="nb">filter</span><span class="p">(</span><span class="n">pk</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="n">Out</span><span class="p">[</span><span class="mi">2</span><span class="p">]:</span> <span class="o"><</span><span class="n">QuerySet</span> <span class="p">[</span><span class="o"><</span><span class="n">Post</span><span class="p">:</span> <span class="n">Post</span> <span class="n">author</span><span class="p">:</span> <span class="n">blogger</span><span class="o">-</span><span class="n">jim</span><span class="p">,</span> <span class="n">created</span><span class="p">:</span> <span class="mi">2018</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">28</span> <span class="mi">14</span><span class="p">:</span><span class="mi">32</span><span class="p">:</span><span class="mf">19.956328</span><span class="o">+</span><span class="mi">00</span><span class="p">:</span><span class="mi">00</span><span class="o">></span><span class="p">]</span><span class="o">></span>
</code></pre></div></div>
<p>Check it out! Similar to the <code class="language-plaintext highlighter-rouge">where</code> method, <code class="language-plaintext highlighter-rouge">filter</code> will return a special type of object, in Django it is called a <code class="language-plaintext highlighter-rouge">QuerySet</code> and again, for the purposes of this post, we can just treat this as an array of objects.</p>
<p>And just like <code class="language-plaintext highlighter-rouge">.where</code>, by using <code class="language-plaintext highlighter-rouge">.filter</code> in Django we can query by different attributes and not just by primary key.</p>
<p>If we run a <code class="language-plaintext highlighter-rouge">.filter</code> query that doesn’t return any results, we will get an empty <code class="language-plaintext highlighter-rouge">QuerySet</code> back:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">In</span> <span class="p">[</span><span class="mi">4</span><span class="p">]:</span> <span class="n">Post</span><span class="p">.</span><span class="n">objects</span><span class="p">.</span><span class="nb">filter</span><span class="p">(</span><span class="n">pk</span><span class="o">=</span><span class="mi">500</span><span class="p">)</span>
<span class="n">Out</span><span class="p">[</span><span class="mi">4</span><span class="p">]:</span> <span class="o"><</span><span class="n">QuerySet</span> <span class="p">[]</span><span class="o">></span>
</code></pre></div></div>
<div class="breaker"></div>
<p>You, my friend, are well on your way to becoming an ex-rails-django-querying master! Stay tuned for more complicated querying in Django and discussions around query optimizations.</p>jacquelinepottsQuerying with the Django ORM: how do we do it? What journeys lie ahead of us? Which queries are more efficient and put less load on a database? Coming from an ActiveRecord and Rails background, the transition and answers to these questions are still an ongoing journey. Below we will discuss some fun queries in Rails and how those might translate to Django; Django ORM for people who aren’t familiar with the Django ORM. Photographed above, meet our household’s #1, Django the cat.Adventures with Git History and File Tree Structure2019-02-21T00:25:10+00:002019-02-21T00:25:10+00:00https://jacquelinepotts.com/adventures-with-git-history<p>Git! It’s everyone’s favorite version control system and rightfully so, it is a pretty
powerful tool. Sometimes git can be a little boring and not present the easiest format of data for us creative human-types to understand.
We will be exploring some tools to jazz up your source control to lean some cool data about
your favorite code bases and developers of the past and present.</p>
<h2 id="file-tree-structure-and-architecture">File Tree Structure and Architecture</h2>
<p>Looking at a codebase in your favorite editor might give us a good understanding of the file structure but not much else. It would be great to get a deeper look into the not-so-obvious
dependencies <em>between</em> classes, files, and even directories, the real meat and veg of the operation. One data visualization tool that could help us our here is <a href="http://www.redotheweb.com/CodeFlower/"><strong>Code Flower</strong></a>
<br />
<br /></p>
<div class="toright">
<img class="image" src="../assets/images/code-flower.png" alt="Alt Text" />
<figcaption class="caption">File tree visualization of a Ruby on Rails API</figcaption>
</div>
<p><br /></p>
<p>We can see links and dependencies between files and directories as depicted by the gray lines.
The more gray lines a file blob has, the more relationships it has to other areas of the codebase.
By hovering over the circles, we can see the file names too and lines of code (<code class="language-plaintext highlighter-rouge">loc</code>) count. Note the example of everyone’s favorite <code class="language-plaintext highlighter-rouge">schema.rb</code> file above.</p>
<p>Another cool feature of this tool is we get a beautiful display of file <em>sizes</em>. Libraries and external packages are expectedly larger but internal files that are out of proportion with their
neighboring file friends might be good candidates for a revisit and refactor.</p>
<p>Visit the source code to get some drop dead gorgeous flowers of your favorite projects here:
<a href="https://github.com/fzaninotto/CodeFlower">Code Flower</a></p>
<h2 id="git-and-developer-history">Git and Developer History</h2>
<p><strong>Getting a better understanding of the who, what, where, and why of a codebase.</strong>
Let’s take <code class="language-plaintext highlighter-rouge">git blame</code> to a whole new level with a neat little tool called <a href="https://gource.io/">Gource</a>, an animated source control visualization tool.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/NjUuAuBcoqs" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
<p>Here we get an actual video of the history of the commits and commit authors who contributed to the project with some fun facts like when the code was written, what areas of the codebase the developer worked on, and the magnitude of their ownership.</p>
<p>A tool like Gource is especially helpful getting a high level and quick introduction to a new code base and the developers you’re about to work with.</p>jacquelinepottsGit! It’s everyone’s favorite version control system and rightfully so, it is a pretty powerful tool. Sometimes git can be a little boring and not present the easiest format of data for us creative human-types to understand. We will be exploring some tools to jazz up your source control to lean some cool data about your favorite code bases and developers of the past and present.Engineering Power Couple, Tips for working with your S.O.2018-07-27T00:25:10+00:002018-07-27T00:25:10+00:00https://jacquelinepotts.com/engineering-power-couple<p><strong>Work with your significant other they said! It’ll be fun they said!</strong></p>
<p>Actually, when I first starting telling friends and family that my fiance and I were about to be software engineers at the same company most thought we were nuts. Most opinions were in the <code class="language-plaintext highlighter-rouge">“how could you live and work and commute with the same person every day?”</code>, <code class="language-plaintext highlighter-rouge">“I could never do that with my partner”</code>, <code class="language-plaintext highlighter-rouge">“you two are insane”</code> realm, but despite the rhetoric, my partner of 10 years and I decided to both accept the engineering positions at our current company. I’ll be honest, I was a little nervous at first, I had some moments of anticipatory anxiety and some <code class="language-plaintext highlighter-rouge">“could this be the beginning of the end”</code> type thoughts were in the back of my mind but my fiance Scott had the utmost confidence in our ability to be successful both personally and professionally. One year later, we are still happily living, commuting, working and building a deeper relationship together.</p>
<p>Surprisingly, the biggest challenge working together wasn’t the working together part, it was separating work from home. In fact, at the office we rocked it, we both have the same workaholic personality and we both love Ruby more than anything. Since we experienced the same victories, the same hardships, and the same frustrations it was natural to confide in each other and talk about work all day, all night, and during every time in-between. It is not sexy to talk about pull requests while trying to have a romantic dinner out. Work life and work stress was seeping into every aspect of our home life and our relationship and we both knew if we did not set some boundaries we would not get out of this rut.</p>
<p>As avid agile nerds, we did what came naturally to us - and we had a retrospective. Thankfully we have a huge white board at home and we were able to mark down some thoughts as to what was working well for us, what needed some attention, and what was downright wrong. As with any retro, we both understood and agreed this was a safe space, full of empathy and understanding, where we could provide each other constructive feedback with the intent of learning and growth. Instead of reflecting on process or engineering and product communication we reflected on how things were going in the relationship, pretty cute, right? We left our retrospective with some action items and plans to help us prioritize our relationship a little bit more. Here are some things that worked for us and helped us become better partners at home and at work.</p>
<p><strong>Regularly Scheduled Date Nights.</strong>
Every Wednesday is date night for us, no excuses. It’s actually really fun having a date night on hump day and always gives us something to look forward to on the apex of the work week. Just having a routine of doing something fun and for each other every week helped give us the opportunity to turn our work-brains off and focus on us. First rule of date night? No phones, put those puppies away. If you’re worried about missing messaging on Slack or late-night emails from your manager don’t fret. Everyone deserves time to unplug, even on a Wednesday night and think of all the messages you’ll have when you check your phone the next morning - you’ll be feeling like the most popular gal at the office, a win win!
Second rule of date night - don’t talk about work. This was a hard one for us, especially when one of us has had a hard day at the office, as much as we wanted to be supportive of one another we needed some boundaries. We also found that without work stories, what could we possibly talk about? Probably nothing, right? To help alleviate those long pauses we decided to change it up. Instead of date night just consisting of the standard classic dinner and drinks at a restaurant we tried some different activities; going to art museums, hiking to the lighthouse on Roosevelt Island, getting cheap tickets to Broadway musicals, and just galavanting around New York City. Making memories, taking great selfies, and doing something off the beaten path.</p>
<p><strong>Shared Hobbies Outside of Work.</strong>
We’ve recently discovered the game <a href="https://www.ingress.com/">Ingress</a>. It’s great! You should check it out. It gets us outside, walking and biking around NYC together. Added bonuses, much exercise and we get to engage with members of our community and yell at kids who take over our portals (Just kidding we are very friendly and kind).
Have I forgot to mention we are dog parents? Our proudest achievement, Molly Dog, and the two humans love to go hiking on the weekends. There are some great trails about an hours drive away from NYC.</p>
<p><strong>Limit Slack and Email time when at home.</strong>
We try our best to have our home environment be a relaxing and low stress place with some boundaries in place to give us some mental space. Scott is a little bit more important than I as he is in a lead position, but we try to not surf our slack channels to any great extent at home. I set a stricter boundary for myself where I will only give my Slack and email a quick check at 10pm on work nights and try not to look at it any other times. It is a work in progress and challenging at times especially since we work at a startup but we are getting better at not taking our work home with us every night.</p>
<p><strong>Be Kind, Always.</strong>
Long story short, we always remember our relationship is what’s most important, everything else is second. We are stronger as a team and it is important to not let differences of opinions at work get in the way of our personal life.</p>
<hr />
<p>TLDR; Even if you’re not working with your significant other, writing good software is all about collaboration and trust. It can only be beneficial to yourself and others to practice kindness, empathy, patience, and understanding everyday. Pass it on + cheers.</p>jacquelinepottsWork with your significant other they said! It’ll be fun they said!