<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.5">Jekyll</generator><link href="https://jescholl.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://jescholl.com/" rel="alternate" type="text/html" /><updated>2025-11-27T09:41:16-08:00</updated><id>https://jescholl.com/feed.xml</id><title type="html">JESCHOLL</title><subtitle>A blog about networking, computers, programming, finance, all the things that interest me.</subtitle><author><name>Jason Scholl</name></author><entry><title type="html">Custom Jekyll plugins on github-pages</title><link href="https://jescholl.com/automation/using-custom-jekyll-plugins-on-github/" rel="alternate" type="text/html" title="Custom Jekyll plugins on github-pages" /><published>2018-01-24T00:00:00-08:00</published><updated>2018-01-24T00:00:00-08:00</updated><id>https://jescholl.com/automation/using-custom-jekyll-plugins-on-github</id><content type="html" xml:base="https://jescholl.com/automation/using-custom-jekyll-plugins-on-github/"><![CDATA[<p>Github-pages is fantastic, they provide free hosting for static sites, or Jekyll
sites that stick to the list of <a href="https://pages.github.com/versions/">whitelisted gems</a>.
Traditional wisdom is that if you want to use Jekyll with plugins Github doesn’t allow,
you need to host it on Amazon’s S3, or some other platform that isn’t as restrictive as github.</p>

<p>I am cheap, and don’t want to pay for hosting, so instead I chose to build my site
in Circleci and have CircleCI push the static files up to Github.  To do this, I needed to
create a branch (or it could be its own repo) to store the static files generated by Jekyll.
I chose to use <code class="language-plaintext highlighter-rouge">master</code> for static files, and <code class="language-plaintext highlighter-rouge">develop</code> for all the Jekyll code
because github’s user-pages must be on the <code class="language-plaintext highlighter-rouge">master</code> branch.</p>

<p>The first step is just to get your site building in CircleCI.</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># .circleci/config.yml</span>
<span class="na">version</span><span class="pi">:</span> <span class="m">2.0</span>

<span class="na">jobs</span><span class="pi">:</span>
  <span class="na">build</span><span class="pi">:</span>
    <span class="na">docker</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">image</span><span class="pi">:</span> <span class="s">circleci/ruby:2.4.3</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">checkout</span>
      <span class="pi">-</span> <span class="na">restore_cache</span><span class="pi">:</span>
          <span class="na">keys</span><span class="pi">:</span>
            <span class="pi">-</span> <span class="s">v1-bundle-\{\{ checksum "Gemfile.lock" \}\}</span>
      <span class="pi">-</span> <span class="na">run</span><span class="pi">:</span> <span class="s">bundle install --path vendor/bundle</span>
      <span class="pi">-</span> <span class="na">save_cache</span><span class="pi">:</span>
          <span class="na">key</span><span class="pi">:</span> <span class="s">v1-bundle-\{\{ checksum "Gemfile.lock" \}\}</span>
          <span class="na">paths</span><span class="pi">:</span>
            <span class="pi">-</span> <span class="s">vendor/bundle</span>
      <span class="pi">-</span> <span class="na">run</span><span class="pi">:</span>
          <span class="na">name</span><span class="pi">:</span> <span class="s">Install Prerequisites</span>
          <span class="na">command</span><span class="pi">:</span> <span class="s2">"</span><span class="s">sudo</span><span class="nv"> </span><span class="s">apt-get</span><span class="nv"> </span><span class="s">update;</span><span class="nv"> </span><span class="s">sudo</span><span class="nv"> </span><span class="s">apt-get</span><span class="nv"> </span><span class="s">install</span><span class="nv"> </span><span class="s">-y</span><span class="nv"> </span><span class="s">rsync"</span>
      <span class="pi">-</span> <span class="na">run</span><span class="pi">:</span> 
          <span class="na">name</span><span class="pi">:</span> <span class="s">Build Site</span>
          <span class="na">command</span><span class="pi">:</span> <span class="s">JEKYLL_ENV=production bundle exec jekyll build</span>
      <span class="pi">-</span> <span class="na">store_artifacts</span><span class="pi">:</span>
          <span class="na">path</span><span class="pi">:</span> <span class="s">_site</span>
          <span class="na">destination</span><span class="pi">:</span> <span class="s">/</span>
      <span class="pi">-</span> <span class="na">run</span><span class="pi">:</span>
          <span class="na">name</span><span class="pi">:</span> <span class="s">Deploy</span>
          <span class="na">command</span><span class="pi">:</span> <span class="s">_scripts/deploy.sh</span>
</code></pre></div></div>

<p>This simple CircleCI 2.0 config will build a Jekyll site in ruby 2.4.3, store
the static files as build artifacts, cache the installed gems to speed up future
builds, and finally run a script to deploy it.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>
<span class="c"># _scripts/deploy.sh</span>

<span class="nv">DEPLOY_DIR</span><span class="o">=</span><span class="si">$(</span><span class="nb">mktemp</span> <span class="nt">-d</span><span class="si">)</span>
<span class="nv">BUILD_DIR</span><span class="o">=</span><span class="si">$(</span><span class="nb">readlink</span> <span class="nt">-f</span> <span class="s2">"./_site"</span><span class="si">)</span>

<span class="c"># clone target repo to a temp dir to ensure no name collisions</span>
git clone <span class="nv">$CIRCLE_REPOSITORY_URL</span> <span class="nv">$DEPLOY_DIR</span>
<span class="nb">cd</span> <span class="nv">$DEPLOY_DIR</span>

<span class="c"># verify clean repo</span>
git fetch origin
git checkout master

<span class="c"># configure git committer</span>
git config <span class="nt">--global</span> user.name CI
git config <span class="nt">--global</span> user.email ci@example.com

<span class="c">#copy compiled site from artifacts</span>
rsync <span class="nt">-a</span> <span class="nt">--delete</span> <span class="nt">--exclude</span><span class="o">=</span>.git <span class="nv">$BUILD_DIR</span>/ <span class="nb">.</span>

<span class="c"># commit changes</span>
git add <span class="nt">-A</span>
git commit <span class="nt">-m</span> <span class="s2">"Deployed in CI: </span><span class="nv">$CIRCLE_BUILD_URL</span><span class="s2">"</span>
git push origin master

<span class="c"># ping search engines with new sitemap</span>
curl <span class="s2">"http://www.google.com/webmasters/sitemaps/ping?sitemap=https://www.example.com/sitemap.xml"</span>
</code></pre></div></div>

<p>The script simply clones the repo, checks out the <code class="language-plaintext highlighter-rouge">master</code> branch, syncs it with
the output from the build step, and commits it with a link to the build on CircleCI.</p>

<p>After creating a checkout key in CircleCI with write access to your repo, you are
now free to use any gems you like and Github will host it for free.</p>

<p class="notice--info">As an extra bonus you can add extra features like spell check, HTML validation, or a
safety check to verify that you don’t accidentally add commits to the wrong branch.</p>]]></content><author><name>Jason Scholl</name></author><category term="automation" /><summary type="html"><![CDATA[How to use custom Jekyll plugins and still host your site on Github.]]></summary></entry><entry><title type="html">I’m in ops</title><link href="https://jescholl.com/general/im-in-ops/" rel="alternate" type="text/html" title="I’m in ops" /><published>2016-07-01T00:00:00-07:00</published><updated>2016-07-01T00:00:00-07:00</updated><id>https://jescholl.com/general/im-in-ops</id><content type="html" xml:base="https://jescholl.com/general/im-in-ops/"><![CDATA[<p>I just got back from <a href="https://www.monitorama.com">Monitorama</a> and was once again
reminded how terrible job titles are in the tech field.  At each of the social
gatherings I would set off to meet new people, and by far the most common
introduction was “Hello my name is …, and I’m in ops”.  I did meet several Site
Reliability Engineers, a few Developers, and a few others, but the vast majority
were “in ops”.</p>

<figure class=" ">
  
    
      <img src="/images/monitorama-2016.jpg" alt="Pips and Bounce after-party at Monitorama 2016" />
    
  
  
    <figcaption>Pips and Bounce after-party at Monitorama 2016
</figcaption>
  
</figure>

<p>As it happens, I too am “in ops”. I choose to introduce myself that way, likely
for the same reason as everyone else; because my real job title doesn’t come close
to describing what I do, and all the alternatives either don’t apply or don’t
make grammatical sense.</p>

<p>Officially my job title is Senior Linux Administrator, but for me that brings to mind a
bunch of scruffy neckbeards artisanally hand-crafting config files and shunning daylight.
Instead, I spend most of my days automating installs and config changes with <a href="https://chef.io">Chef</a>
and <a href="https://github.com/etch/etch">Etch</a>. I am also singularly responsible for our
network infrastructure and firewalls (Network Engineer/Administrator).  I often
need to write software to help test and troubleshoot the systems I’m building, and
occasionally even write the software the finished systems will run (Software Developer).
I spend a sizable amount of my time setting up, optimizing, and reacting to alerts
in our various monitoring systems (Site Reliability Engineer).  And when I’m not
doing any of those things I’m learning new programming/markup/query languages trying
to find the slow spots in our infrastructure so we can save a few milliseconds on
each web request (Data Scientist).</p>

<p>A few years ago the term <a href="https://theagileadmin.com/what-is-devops/">DevOps</a>
started getting popular as a way to describe how Developers and Operations can
work together using the same tools to be more efficient and build better products.
Some people have tried to use it as a job title such as DevOps Engineer, or DevOps
Administrator.  The problem with these sorts of titles is they just don’t make sense,
you might as well call yourself an Agile Engineer, or a Teamwork Administrator.</p>

<p>Operations Engineer isn’t bad, but that’s only one step away from “I’m in ops”,
and anyone outside the tech field would likely think it has something to do with
trains.  I guess for now I’ll just have to keep telling people “I’m in ops”, at least
until I find a better title I can steal.</p>]]></content><author><name>Jason Scholl</name></author><category term="general" /><summary type="html"><![CDATA[A discussion about job titles in tech and why no one likes them]]></summary></entry><entry><title type="html">Short Selling Houses</title><link href="https://jescholl.com/finance/short-selling-houses/" rel="alternate" type="text/html" title="Short Selling Houses" /><published>2016-05-10T00:00:00-07:00</published><updated>2016-05-10T00:00:00-07:00</updated><id>https://jescholl.com/finance/short-selling-houses</id><content type="html" xml:base="https://jescholl.com/finance/short-selling-houses/"><![CDATA[<p>Since the housing market in Portland (and my neighborhood especially) is really
hot right now I’ve been thinking a lot about home values and whether or not to sell.
One bit of advice I heard a few years ago that I’ve always been intrigued by was the
idea of selling your home in the summer, when home values are the highest, renting
for 6 months, then buying in the winter, when home values are the lowest. The idea is
somewhat similar to <a href="https://en.wikipedia.org/wiki/Short_(finance)">short selling</a>, 
in that profits are directly proportional to losses in the market.</p>

<p>To dig into this a little deeper, we need to start with some assumptions</p>

<ol>
  <li>
    <p>The home we buy must be of equal or greater value to the home we sell at all times.</p>

    <p>We’ll be looking at houses in the same city which should be rising and falling
at the same rate, and we want to make sure we’re not downgrading.</p>
  </li>
  <li>
    <p>Rent will not be less than the mortgage payment.</p>

    <p>Landlords usually have mortgages too, and we don’t want to downgrade <em>too</em>
much during the rental period.</p>
  </li>
</ol>

<p>Looking at home values over the last few years, you can clearly see a seasonal rise and fall in home values,
higher in the summer and lower in the winter.  This gives hope that it might really
be possible to make money by delaying buying after selling.</p>

<figure class=" ">
  
    
      <a href="https://www.trulia.com/real_estate/Portland-Oregon/market-trends/">
          <img src="/images/portland_home_values.png" alt="portland home values" />
      </a>
    
  
  
    <figcaption>Portland area pricing data taken from <a href="https://www.trulia.com">Trulia.com</a>
</figcaption>
  
</figure>

<p>We want the housing market to lose as much of its value as possible between selling and buying 6 months later.  To make any profit, home values must drop enough to cover selling costs, the increase in monthly housing costs, and the principal we would have put into our house during the rental period if we hadn’t sold.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">cost_of_renting</span> <span class="o">=</span> <span class="n">monthly_rent</span> <span class="o">*</span> <span class="n">months</span>
<span class="n">cost_of_owning</span>  <span class="o">=</span> <span class="p">(</span><span class="n">monthly_mortgage</span> <span class="o">-</span> <span class="n">monthly_principal_paid</span><span class="p">)</span> <span class="o">*</span> <span class="n">months</span>

<span class="n">revenue</span>         <span class="o">=</span> <span class="n">sell_price</span> <span class="o">+</span> <span class="n">cost_of_owning</span>
<span class="n">expenses</span>        <span class="o">=</span> <span class="n">buy_price</span> <span class="o">+</span> <span class="n">selling_costs</span> <span class="o">+</span> <span class="n">cost_of_renting</span>

<span class="c1"># profit        = revenue - expenses</span>
<span class="n">profit</span>          <span class="o">=</span> <span class="p">(</span><span class="n">sell_price</span> <span class="o">+</span> <span class="n">monthly_mortgage</span><span class="o">*</span><span class="n">months</span><span class="p">)</span> <span class="o">-</span> <span class="p">(</span><span class="n">buy_price</span> <span class="o">+</span> <span class="n">selling_costs</span> <span class="o">+</span> <span class="n">monthly_rent</span><span class="o">*</span><span class="n">months</span> <span class="o">-</span> <span class="n">monthly_principal_paid</span><span class="o">*</span><span class="n">months</span><span class="p">)</span>
</code></pre></div></div>

<p>Based on my completely unscientific practice of randomly looking at different
areas in Trulia, it seems like summer time generally accounts for almost all of
the yearly growth, and the winter generally loses about 10-20% of what the
summer gained.  Since we’re only concerned with losses, and since year-over-year
growth in my area last year was are around 20%, I’m going to use a <code class="language-plaintext highlighter-rouge">buy_price</code>
4% less than my <code class="language-plaintext highlighter-rouge">sell_price</code> (<code class="language-plaintext highlighter-rouge">20% * 20% = 4%</code>). To help our profits a little
more, I’ll also assume <code class="language-plaintext highlighter-rouge">monthly_rent</code> and <code class="language-plaintext highlighter-rouge">monthly_mortgage</code> are equal.  Finally,
selling a house in a reasonable amount of time usually requires a realtor, and
<a href="https://www.mortgagecalculator.biz/c/commissions.php">realtor commissions are usually about 6%</a>, so we’ll stick with that.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">sell_price</span>             <span class="o">=</span> <span class="mi">300_000</span>
<span class="n">buy_price</span>              <span class="o">=</span> <span class="mi">300_000</span> <span class="o">*</span> <span class="p">(</span><span class="mi">1</span> <span class="o">-</span> <span class="mf">0.04</span><span class="p">)</span> <span class="c1"># 288,000</span>
<span class="n">selling_costs</span>          <span class="o">=</span> <span class="mi">300_000</span> <span class="o">*</span> <span class="mf">0.06</span>       <span class="c1"># 18,000</span>

<span class="n">monthly_rent</span>           <span class="o">=</span> <span class="mi">1_500</span>
<span class="n">monthly_mortgage</span>       <span class="o">=</span> <span class="mi">1_500</span>
<span class="n">monthly_principal_paid</span> <span class="o">=</span> <span class="mi">300</span>

<span class="n">cost_of_renting</span>        <span class="o">=</span> <span class="mi">1_500</span><span class="o">*</span><span class="mi">6</span>              <span class="c1"># 9,000</span>
<span class="n">cost_of_owning</span>         <span class="o">=</span> <span class="p">(</span><span class="mi">1_500</span> <span class="o">-</span> <span class="mi">300</span><span class="p">)</span><span class="o">*</span><span class="mi">6</span>      <span class="c1"># 7,200</span>

<span class="n">profit</span> <span class="o">=</span> <span class="p">(</span><span class="mi">300_000</span> <span class="o">+</span> <span class="mi">7_200</span><span class="p">)</span> <span class="o">-</span> <span class="p">(</span><span class="mi">288_000</span> <span class="o">+</span> <span class="mi">18_000</span> <span class="o">+</span> <span class="mi">9_000</span><span class="p">)</span> <span class="c1"># -7,800</span>
</code></pre></div></div>

<p>That puts us $7,800 in the red for selling our hypothetical house in the summer and
buying one of equal value in the winter.  But there is still the income from selling
the house to consider.  Assuming 25% equity, that gives us $57,000 to invest elsewhere while we rent.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">selling_costs</span> <span class="o">=</span> <span class="mi">300_000</span> <span class="o">*</span> <span class="mf">0.06</span>         <span class="c1"># 18,000</span>
<span class="n">equity</span>        <span class="o">=</span> <span class="mi">300_000</span> <span class="o">*</span> <span class="mf">0.25</span>         <span class="c1"># 75,000</span>
<span class="n">revenue</span>       <span class="o">=</span> <span class="n">equity</span> <span class="o">-</span> <span class="n">selling_costs</span> <span class="c1"># 57,000</span>
</code></pre></div></div>

<p>Historically the stock market as a whole <a href="http://www.stockpickssystem.com/historical-rate-of-return/">averages 10.4% per year</a>,
and if we could count on that return we would make $2,890.70 in 6 months, though
the portfolio required to get that rate would be almost as likely to lose
that much in the 6 months we could invest it.  The better choice would be to invest
the majority of that money in bonds, <abbr title="Certificates of Deposit">CDs</abbr>, or money markets that are much safer but
unfortunately have much lower returns (0.5-1% currently), which only gets us $284
in 6 months (not counting brokerage fees).</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">future_value</span> <span class="o">=</span> <span class="n">present_value</span> <span class="o">*</span> <span class="p">(</span><span class="mi">1</span> <span class="o">+</span> <span class="n">rate</span><span class="p">)</span><span class="o">^</span><span class="n">time</span>
<span class="c1"># risky portfolio</span>
<span class="mi">57_000</span> <span class="o">*</span> <span class="p">(</span><span class="mi">1</span> <span class="o">+</span> <span class="o">.</span><span class="mi">104</span><span class="p">)</span><span class="o">^.</span><span class="mi">5</span> <span class="c1"># 59,890.70</span>

<span class="c1"># safer portfolio</span>
<span class="mi">57_000</span> <span class="o">*</span> <span class="p">(</span><span class="mi">1</span> <span class="o">+</span> <span class="o">.</span><span class="mo">01</span><span class="p">)</span><span class="o">^.</span><span class="mi">5</span> <span class="c1"># 57,284.29</span>
</code></pre></div></div>

<p>So, in a perfect world where we can sell at the absolute top of the market and
buy at the absolute bottom 6 months later, and find a suitable rental between for
the same price, the total profit (not counting moving expenses, storage, taxes,
brokerage fees, closing costs, title insurance, <abbr title="Home Owner's Association">HOA</abbr> fees, or anything else I’ve
forgotten) is $-7,515.71.</p>

<p>The biggest expense cutting into our profits from this example was the realtor
fees, as you can see from the graph below, as long as the market drop is less
than the realtor fees, its almost impossible to come out ahead.  While there
are ways to save money on realtor fees such as selling yourself or using an
online listing agent, short-selling houses just doesn’t seem like a practical
way to make money to me.</p>

<div id="graph0" class="text-center"></div>

<table class="graph_inputs">
<tr class="row1">
<td class="col1">
  
  <label for="graph0_home_value">Home Value</label>
  <input id="graph0_home_value" value="300000" />
  
  
</td><td class="col2">
  
  <label for="graph0_mortgage">Mortgage</label>
  <input id="graph0_mortgage" value="1500" />
  
  
</td><td class="col3">
  
  <label for="graph0_principal_per_month">Principal/Month</label>
  <input id="graph0_principal_per_month" value="300" />
  
  
</td><td class="col4">
  
  <label for="graph0_realtor_commission">Realtor Commission %</label>
  <input id="graph0_realtor_commission" value="6" />
  
  
</td></tr>
<tr class="row2"><td class="col1">
  
  <label for="graph0_rent">Rent</label>
  <input id="graph0_rent" value="1500" />
  
  
</td><td class="col2">
  
  <label for="graph0_loan_amount">Loan Amount</label>
  <input id="graph0_loan_amount" value="225000" />
  
  
</td><td class="col3">
  
  <label for="graph0_investment_apy">Investment APY</label>
  <input id="graph0_investment_apy" value="1" />
  
  
</td></tr>

</table>

<script type="text/javascript">
  function plot_graph0() {
    var graphdata = {"data":[{"fn":"(" + document.getElementById("graph0_home_value").value + " + (" + document.getElementById("graph0_mortgage").value + " - " + document.getElementById("graph0_principal_per_month").value + ") * 6) - (" + document.getElementById("graph0_home_value").value + " * (100 - x)/100 + " + document.getElementById("graph0_home_value").value + " * " + document.getElementById("graph0_realtor_commission").value + "/100 + " + document.getElementById("graph0_rent").value + " * 6) + ((" + document.getElementById("graph0_home_value").value + " - " + document.getElementById("graph0_loan_amount").value + ") - " + document.getElementById("graph0_home_value").value + "*" + document.getElementById("graph0_realtor_commission").value + "/100)*(nthRoot(1+" + document.getElementById("graph0_investment_apy").value + "/100, 2) - 1)"}],"yAxis":{"label":"Profit","domain":[-50000,100000]},"xAxis":{"label":"% Decrease during winter","domain":[-5,20]}};
    graphdata['target'] = "#graph0";
    functionPlot(graphdata);
  }
  plot_graph0();
</script>]]></content><author><name>Jason Scholl</name></author><category term="finance" /><summary type="html"><![CDATA[An exploration of the profitability of short selling houses.]]></summary></entry></feed>