<?xml version="1.0" encoding="UTF-8" standalone="no"?><!--Generated by Site-Server v@build.version@ (http://www.squarespace.com) on Fri, 03 Apr 2026 21:08:51 GMT
--><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:media="http://www.rssboard.org/media-rss" xmlns:wfw="http://wellformedweb.org/CommentAPI/" version="2.0"><channel><title>Project Idealism</title><link>https://www.projectidealism.com/</link><lastBuildDate>Mon, 23 Oct 2017 12:35:57 +0000</lastBuildDate><language>en-US</language><generator>Site-Server v@build.version@ (http://www.squarespace.com)</generator><description/><itunes:explicit>yes</itunes:explicit><copyright>Copyright © 2009 | Ideal Project Group LLC </copyright><itunes:image href="http://idealprojectgroup.com/Podcast_Cover.jpg"/><itunes:keywords>Ideal,Project,Group,Project,Idealism,Business,Project,Management,Technology</itunes:keywords><itunes:summary>The concept behind this show is "What can a project manager learn from X?"&#13;
&#13;
"X" can be anything from a chef, to a professor, to a firefighter.  The idea is that project managers and other professionals can learn a lot from these amazing individuals, the things they are creating, and the problems they are solving. These people can teach us a lot about the projects we are managing, the businesses we are running and ultimately help us manage the things we're working on more effectively.</itunes:summary><itunes:subtitle>the Ideal Project Group podcast</itunes:subtitle><itunes:category text="Business"><itunes:category text="Management &amp; Marketing"/></itunes:category><itunes:category text="Technology"/><itunes:author>Ideal Project Group, LLC</itunes:author><itunes:owner><itunes:email>andrew@idealprojectgroup.com</itunes:email><itunes:name>Ideal Project Group, LLC</itunes:name></itunes:owner><item><title>How to Create a Background Text Fade-In Effect on Your Website</title><category>Engineering</category><pubDate>Fri, 10 Nov 2017 14:36:00 +0000</pubDate><link>https://www.projectidealism.com/posts/2017/11/10/how-to-create-a-background-text-fade-in-effect-on-your-website</link><guid isPermaLink="false">50d01cefe4b000726e548760:51ab864fe4b0db4a25537edb:59ede22d914e6b8d4a089efa</guid><description><![CDATA[<p>While we were building the Minneapolis Yoga Conference website, we had a neat idea. We wanted text to start off blurred in the background, slowly become visible while you scroll down the page, and finally become readable when you reached the bottom. We thought it looked similar to other parallax effects out there, but it didn't quite fit the definition.</p><p>A background text fade-in effect looks like this.</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1508762364245-NYIIADQZ0EPP24RSNRI5/image-asset.gif" data-image-dimensions="460x882" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1508762364245-NYIIADQZ0EPP24RSNRI5/image-asset.gif?format=1000w" width="460" height="882" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1508762364245-NYIIADQZ0EPP24RSNRI5/image-asset.gif?format=100w 100w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1508762364245-NYIIADQZ0EPP24RSNRI5/image-asset.gif?format=300w 300w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1508762364245-NYIIADQZ0EPP24RSNRI5/image-asset.gif?format=500w 500w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1508762364245-NYIIADQZ0EPP24RSNRI5/image-asset.gif?format=750w 750w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1508762364245-NYIIADQZ0EPP24RSNRI5/image-asset.gif?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1508762364245-NYIIADQZ0EPP24RSNRI5/image-asset.gif?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1508762364245-NYIIADQZ0EPP24RSNRI5/image-asset.gif?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
          
          <figcaption class="image-caption-wrapper">
            <p>As you scroll down the page, the background text becomes more visible. Once you reach the bottom, you can finally read through the content.</p>
          </figcaption>
        
      
        </figure>
      

    
  


  





  <p>The text behind the photos starts as an absolute positioned element behind the foreground. Once you scroll to the images, the text becomes fixed. When you've finally scrolled to the end of the images, the text falls into the normal flow of the page, a static position.</p><p>Here's how you can do this.</p><h2>1. Start with this template</h2><p>We want to separate the foreground and background layers. Constructing them as separate div elements helps us do that. We also declare which background layer will be attached to the foreground.</p>
























  
    <pre><code class="language-markup">&lt;div class="background-container">
  &lt;div class="foreground-layer" data-background-layer="background">
    &lt;div>
      &lt;img src="http://via.placeholder.com/350x350" width="350" height="350">
      &lt;h5>Image 1&lt;/h5>
    &lt;/div>
    &lt;div>
      &lt;img src="http://via.placeholder.com/350x350" width="350" height="350">
      &lt;h5>Image 2&lt;/h5>
    &lt;/div>
    &lt;div>
      &lt;img src="http://via.placeholder.com/350x350" width="350" height="350">
      &lt;h5>Image 3&lt;/h5>
    &lt;/div>
    &lt;div>
      &lt;img src="http://via.placeholder.com/350x350" width="350" height="350">
      &lt;h5>Image 4&lt;/h5>
    &lt;/div>
    &lt;div>
      &lt;img src="http://via.placeholder.com/350x350" width="350" height="350">
      &lt;h5>Image 5&lt;/h5>
    &lt;/div>
  &lt;/div>
  &lt;div class="background-layer" id="background">
    &lt;p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur dictum id nulla quis gravida. Donec et velit sapien. Quisque augue eros, porttitor vel finibus et, consequat ac ante. Morbi eleifend diam vitae purus mattis interdum. Aliquam vitae orci ante. Maecenas non odio urna. Nullam lobortis turpis eget sem accumsan, ac laoreet turpis ullamcorper. Donec quis quam erat. Nam vulputate metus a nisi placerat, a ullamcorper nisi semper. Nulla facilisi. Ut molestie tempus egestas. Nunc lacinia libero sit amet eleifend pellentesque. Etiam sit amet lorem quam. Suspendisse potenti.
    &lt;/p>

    &lt;p>
      Fusce nunc nisl, ullamcorper vel congue vel, aliquet ut purus. Praesent laoreet ipsum porta sem dictum, at malesuada tortor ullamcorper. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce vel dui at nulla gravida gravida sit amet quis dui. Cras nec leo metus. Phasellus dignissim, nunc id interdum rutrum, enim turpis pharetra dolor, vel vehicula justo nulla vel quam. Vivamus dapibus dolor id nunc dapibus, id aliquet eros euismod.
    &lt;/p>

    &lt;p>
      Sed ac tincidunt tortor, sagittis hendrerit massa. Sed volutpat, dui eu ornare mattis, urna enim tincidunt tellus, eu hendrerit lectus ipsum vitae libero. Suspendisse potenti. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Maecenas rutrum, ex ut ultricies ornare, mauris lorem ornare libero, vitae malesuada tortor arcu quis purus. Sed felis odio, facilisis ac egestas in, malesuada nec lacus. Quisque metus erat, aliquam et sollicitudin et, consectetur nec est. Nullam eget nisl quis lectus tempor faucibus. Vestibulum auctor purus id orci dapibus, vitae ullamcorper erat dapibus. Maecenas egestas vitae nisi quis sollicitudin. Cras odio purus, fermentum et hendrerit ac, ultricies a dui. Pellentesque dictum massa faucibus, rutrum eros vitae, facilisis tellus. Morbi vulputate, metus et accumsan interdum, sem eros ultrices dolor, non tristique lacus libero sit amet massa. Donec mollis sapien augue, at ornare libero dictum non. Curabitur in ante venenatis, egestas ante id, sagittis dui.
    &lt;/p>
  &lt;/div>
&lt;/div>

&lt;div>
  &lt;img src="http://via.placeholder.com/350x350" width="350" height="350">
  &lt;h5>Filler Image&lt;/h5>
&lt;/div>
&lt;div>
  &lt;img src="http://via.placeholder.com/350x350" width="350" height="350">
  &lt;h5>Filler Image&lt;/h5>
&lt;/div>
&lt;div>
  &lt;img src="http://via.placeholder.com/350x350" width="350" height="350">
  &lt;h5>Filler Image&lt;/h5>
&lt;/div></code>
</pre>
  




  <h2>2. Put the background layer behind the foreground layer</h2><p>The starter template doesn't have anything special to it. The background layer begins on the page where the foreground layer ends. The page flows normally. We need the background layer to appear behind the foreground layer.</p>
























  
    <pre><code class="language-css">.background-container {
  position: relative;
}

.background-layer {
  position: absolute;
  top: 0;
  left: 0;
}</code></pre>
  




  <p>We do this by using absolute positioning on the background layer. The background layer will be absolute positioned relative to the background container. If you have a bunch of content above the background container section, doing this makes sure the background text starts in the right position.</p><h2>3. Blur the background text</h2><p>Without doing something with the background text, the foreground will be hard to read. We chose to blur the background text and make it semi-transparent.</p>
























  
    <pre><code class="language-css">.background-container {
  position: relative;
}

.background-layer {
  position: absolute;
  top: 0;
  left: 0;
  filter: blur(3px);
  opacity: 0.1;
}</code></pre>
  




  <p>Your eyes can see something there, but it's not distracting you from the content in the foreground. Be careful with this part. You don't want to let this effect cause problems for people using your website. If the foreground is hard to read, something is wrong.</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1508947614963-KC80CDPSK7GU9D1ZAZPW/image-asset.png" data-image-dimensions="862x1754" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1508947614963-KC80CDPSK7GU9D1ZAZPW/image-asset.png?format=1000w" width="862" height="1754" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1508947614963-KC80CDPSK7GU9D1ZAZPW/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1508947614963-KC80CDPSK7GU9D1ZAZPW/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1508947614963-KC80CDPSK7GU9D1ZAZPW/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1508947614963-KC80CDPSK7GU9D1ZAZPW/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1508947614963-KC80CDPSK7GU9D1ZAZPW/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1508947614963-KC80CDPSK7GU9D1ZAZPW/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1508947614963-KC80CDPSK7GU9D1ZAZPW/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
          
          <figcaption class="image-caption-wrapper">
            <p>This is what it looks like on the Minneapolis Yoga Conference website. Although it's blurred and barely visible, you can see the text behind the images.</p>
          </figcaption>
        
      
        </figure>
      

    
  


  





  <h2>4. Use JavaScript to listen to scroll events</h2><p>At this point, we want to setup some JavaScript to listen to scroll events. In our case, we still use jQuery so we continued to use it here. If you don't use jQuery, you could just as easily use window.addEventListener and listen for the scroll event.</p><p>Now, the end goal is this:</p><ul data-rte-list="default"><li><p>When you scroll down the page, the background text decreases its blur effect and increases its opacity.</p></li><li><p>When you scroll up the page, the background text increases its blur effect and decreases its opacity.</p></li></ul><p>Before we actually do that, we need to do some calculations. We need to know the following:</p><ul data-rte-list="default"><li><p>How far down the page have we scrolled?</p></li><li><p>When does the foreground element begin? When does it end?</p></li><li><p>How far have we scrolled within the foreground element?</p></li></ul><p>Like we mentioned in the introduction to this post, we want the background to start as an absolute positioned element. Once we are scrolling inside the foreground, the background should be fixed. Finally, when we scroll past the foreground, the background should flow normally within the page so we can start reading the text.</p>
























  
    <pre><code class="language-javascript">$(window).on("scroll",
  function(event) {
    // How far have we scrolled down the page?
    var scrollDepth = $(this).scrollTop()
    var $foreground = $("[data-background-layer]")
    var $background = $( '#' + $foreground.data("background-layer") )
    // We need to calculate the height of the foreground layer.
    // This will allow us to transition the background layer
    // from blurred and transparent to in-focus and opaque as we
    // near the bottom of the foreground.
    var foregroundHeight = $foreground.height()
    // The background layer starts as an absolute positioned element,
    // sitting below the foreground layer.
    // When we start scrolling, we'll need to change the background layer
    // to a fixed position.
    //
    // When should we change the background layer to a fixed position?
    var startPosition = $foreground.offset().top
    // When we are done scrolling through the foreground, we need
    // to change the background layer to a static position. This will
    // allow the background to flow with the page as normal, sitting
    // directly below the foreground layer.
    //
    // When should we change the background layer to a static position?
    var endPosition = startPosition + foregroundHeight
    // This is how far we've scrolled relative to the foreground layer.
    var currentPosition = scrollDepth - startPosition
    // We want to use our currentPosition to slowly decrease the blur
    // value and increase the opacity value.
    var initialFilterValue = 3
    var filterValue = initialFilterValue - currentPosition / foregroundHeight * 3
    var initialOpacityValue = 0.1
    var opacityValue = initialOpacityValue + currentPosition / foregroundHeight * 0.9
})</code></pre>
  




  <h2>5. Update the position, blur, and opacity values based on scroll depth</h2><p>We use the values we calculated in step four to update the position of the background text element. When we are scrolling within the foreground, the background should have a fixed position. Once we reach the end of the foreground, we change the background to a static position. This allows the background to "fall into" the normal flow of the page.</p><p>Using the calculations above, all you need to do is add this to the end of your scroll event handler.</p><p>We handle the position changes of the background element. Also, we use the blur and opacity values we calculated to update these updates as you scroll up or down.</p>
























  
    <pre><code class="language-javascript">if (scrollDepth >= endPosition) {
  // We've reached the end of the foreground. The background should now
  // flow as normal below the foreground.
  $background.css({ position: "static", filter: "none", opacity: "1" })
} else if (scrollDepth >= startPosition) {
  // We are now scrolling within the foreground. We use the values
  // we calculated previously.
  $background.css({ position: "fixed", filter: "blur("+filterValue+"px)", opacity: opacityValue })
} else {
  // We are above the foreground somewhere. We reset the background
  // to its initial values.
  $background.css({ position: "absolute", filter: "blur("+initialFilterValue+"px)", opacity: initialOpacityValue })
}</code></pre>
  




  <h2>6. Make a couple small updates to make things smooth</h2><p>At this point, things may be a little jumpy and may not work exactly as we described. You may notice the background element doesn't smoothly transition once you scroll past the foreground.</p><p>To fix this, you can give a margin-bottom to the foreground element. This margin will be equal to the height of the background element. We do this so the background element has room on the page to flow into once we change the position to static.</p>
























  
    <pre><code class="language-javascript">if (scrollDepth >= endPosition) {
  $foreground.css({ "margin-bottom": "" })
} else {
  $foreground.css({ "margin-bottom": $background.height() })
}</code></pre>
  




  <p>Finally, you'll likely want to make a few updates to your stylesheet. The final styles should look something like this.</p>
























  
    <pre><code class="language-css">.background-container {
  position: relative;
}

.foreground-layer {
  position: relative;
  z-index: 2;
}

.background-layer {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 1;
  filter: blur(3px);
  opacity: 0.1;
}</code></pre>
  




  <p>Basically, we want to define our intentions here. The background layer should be in a layer below the foreground. Giving the background a z-index of 1 and the foreground a z-index of 2 accomplishes this.</p><h2>Wrapping Up</h2><p>In the end, I think we'll use this effect sparingly. It certainly has its place. We don't want to distract people from what's important, like signing up for a mailing list or buying a product. However, this background text fade-in effect was something we were happy with.</p><p>Our goal was for people to scroll through the entire list of presenters and read what's below. Hiding the content below the presenters seemed like a good way to do that. As the content comes into view, people will be more likely to continue scrolling down the page.</p><p>Do you like this effect? Is it too much? Let us know in the comments.</p>]]></description><media:content height="788" isDefault="true" medium="image" type="image/png" url="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1509712547234-6V7RTY9KOMHZPMK08IK1/Screen+Shot+2017-11-03+at+8.34.54+AM.png?format=1500w" width="1500"><media:title type="plain">How to Create a Background Text Fade-In Effect on Your Website</media:title></media:content><dc:creator>andrew@idealprojectgroup.com (Ideal Project Group, LLC)</dc:creator></item><item><title>How we built the Minneapolis Yoga Conference website</title><category>Engineering</category><pubDate>Fri, 13 Oct 2017 13:11:00 +0000</pubDate><link>https://www.projectidealism.com/posts/2017/9/25/how-they-built-the-minneapolis-yoga-conference-website</link><guid isPermaLink="false">50d01cefe4b000726e548760:51ab864fe4b0db4a25537edb:59c965794c326dc16098397d</guid><description><![CDATA[<p>We built a website for the <a href="https://tulasoftware.com/myc2018">Minneapolis Yoga Conference</a> taking place in March 2018. The website recently launched and we want to tell you how we built it.</p><p>Last year, the Minneapolis Yoga Conference website was made on Squarespace. Squarespace is easy for non-developers, but you can't always get everything just the way you want it. It's tough to fully customize unless you engage a developer who knows the platform. In the end, you might be stuck with a theme that looks ok, but isn't quite what you want.</p><p>Taking some of the positives of Squarespace, we knew we wanted to build something custom while still allowing non-developers a decent experience. Ultimately, that means non-developers should be able to edit content and they should be able to use tools they're familiar with.</p><p>To sum it up, a developer shouldn't be required to change a description of a class or a picture of a presenter.</p><p>We also wanted to build with the tools and frameworks we use every day. We use Rails and Bootstrap every day. So that's what we used here.</p><p>There are a few things we'd like to share with you. Before we built anything, we organized a style guide. Then, we enabled content editing with simple text files. Finally, we want to share how we learned to build horizontal touch scrolling for mobile devices.</p><h2>Style Guide</h2><p>If I had to choose one thing which contributed to the success of the project, the style guide would be my first choice. When you start a website, it's like a puzzle box with no pieces inside. Your designer might give you a picture of what the puzzle looks like when it's finished; but how do you get there? You could start building the pieces as you go, but what if you build the wrong ones?</p><p>That's where the style guide helps. By sticking your focus on the style guide, you build most, if not all of the pieces beforehand. Eventually, when you start the puzzle, you have a picture of what it should look like and all the pieces required to do so.</p><p>To give you an idea, here's what our style guide looks like:</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1506456564732-0JD5BX8AF0KCTLRML2C8/Minneapolis+Yoga+Conference+Style+Guide" data-image-dimensions="2500x6479" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1506456564732-0JD5BX8AF0KCTLRML2C8/Minneapolis+Yoga+Conference+Style+Guide?format=1000w" width="2500" height="6479" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1506456564732-0JD5BX8AF0KCTLRML2C8/Minneapolis+Yoga+Conference+Style+Guide?format=100w 100w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1506456564732-0JD5BX8AF0KCTLRML2C8/Minneapolis+Yoga+Conference+Style+Guide?format=300w 300w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1506456564732-0JD5BX8AF0KCTLRML2C8/Minneapolis+Yoga+Conference+Style+Guide?format=500w 500w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1506456564732-0JD5BX8AF0KCTLRML2C8/Minneapolis+Yoga+Conference+Style+Guide?format=750w 750w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1506456564732-0JD5BX8AF0KCTLRML2C8/Minneapolis+Yoga+Conference+Style+Guide?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1506456564732-0JD5BX8AF0KCTLRML2C8/Minneapolis+Yoga+Conference+Style+Guide?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1506456564732-0JD5BX8AF0KCTLRML2C8/Minneapolis+Yoga+Conference+Style+Guide?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
          
          <figcaption class="image-caption-wrapper">
            <p>Before we started building the Minneapolis Yoga Conference website, we translated the design into a style guide. These components were the pieces we needed to finish the puzzle.&nbsp;</p>
          </figcaption>
        
      
        </figure>
      

    
  


  





  <p>It's not fancy, but it gave us a starting point to put things together.</p><p>As you can see, the style guide sort've follows the layout of the website; but it's a bit different. Nothing is functional. There's no javascript here. It's simply a breakdown of components we'll be using to build the website.</p><p>Each of these components is self contained. They aren't changed by their parent. An MYC Navigation Bar element looks the same regardless of where it's placed in the DOM. If you have a naming conflict in your stylesheets, you'll see it immediately on your style guide.</p><p>Is this style guide perfect? No. There are ways to take this much further. We aren't listing out colors and font sizes here, but that's something you could do. You could add descriptions to each component with declarations on when and where to use them.</p><p>Using a style guide has the added benefit of giving you a starting point for content you wish to add in the future. Is there a component you could re-use or modify slightly? Having all of your pieces in one box will help.</p><p>As an application gets larger, it's tough to remember all the different pieces you may be using. A style guide can be a quick reference to the various components used in your application.</p><h2>Storing content in flat files</h2><p>This website has a significant amount of content. That content will also change over time. Also, we don't always have control over when we receive that content.</p><p>As we were building it, we were still collecting bio and headshot information from instructors. We also knew we'd be getting new studio partners as the conference neared. We needed to do something so a developer was unnecessary when those content updates were required.</p><p>To help us with that, we stored content in YML files and rendered the content dynamically. Essentially, the website has a primitive database which can be updated easily with a text editor.</p><p>Here's what one of those files looks like:</p>
























  
    <pre><code class="language-yaml">- name: Jon Snow
  headshot: "john.png"
  bio_pic: "john-bio.jpg"
  bio: >
    Jon Snow is the son of Eddard Stark, Lord of Winterfell. He has five half-siblings: Robb, Sansa, Arya, Bran, and Rickon Stark. Unaware of the identity of his mother, Jon was raised at Winterfell. At the age of fourteen, he joins the Night's Watch, where he earns the nickname Lord Snow. Jon is one of the major POV characters in A Song of Ice and Fire. In the television adaptation Game of Thrones, Jon is portrayed by Kit Harington. Source: http://awoiaf.westeros.org/index.php/Jon_Snow
  facebook: https://www.facebook.com/GameOfThrones
  instagram: https://www.instagram.com/gameofthrones
  website: http://www.hbo.com/game-of-thrones</code>
</pre>
  




  <p>These files are accompanied by a simple Ruby class resembling an ActiveRecord model. We did this so we could write code as if we were accessing the database. In the future, we may find it useful to put the content in a different place. By doing it this way, we won't need to change the templates responsible for rendering the content.</p>
























  
    <pre><code class="language-ruby">class Myc::Presenter
  def self.all
    @all ||= YAML.load_file(Rails.root.join("config", "myc", "presenters.yml"))
  end
end</code>
</pre>
  




  <p>This allows us to use the following in our templates:</p>
























  
    <pre><code class="language-markup"><% Myc::Presenter.all.each do |presenter| %>
  &lta class="blurb presenter">
    &ltdiv class="blurb-image">
      &ltdiv class="blurb-image-inner">
        <%= image_tag "myc/presenters/#{presenter["headshot"]}", size: "150x150", alt: "Presenter: #{presenter["name"]} Headshot" %>
      &lt/div>
    &lt/div>
  &lt/a>
<% end %></code>
</pre>
  




  <p>This gave us a distinct advantage. Once we programmed the content to pull from the flat files, a non-developer could handle content additions and updates. In other words, a developer could focus on pushing the implementation forward. They weren't distracted by an update to a headshot or bio.</p><p>The main reason non-developers could handle these content updates was GitHub. This was a lucky side effect of using GitHub for all of our projects.</p><p>Using the GitHub web interface, a non-developer was able to upload headshots and edit files; all inside a new pull request. When the pull request was ready, the new content was merged and the site updated without the help of a developer. This was helpful because of the effort involved with image production (cropping, optimization, etc.) and gathering content from many different people.&nbsp;The website was updated much faster this way.</p><p>Obviously this is just one approach to making content updates accessible to more people. We could have opted for a database based approach with a web interface. I'm sure you could use something like ActiveAdmin to achieve that.</p><p>However, we wanted something quick and dirty. We didn't want to spend a bunch of time learning some other system. We were able to quickly experiment with this method and determine it was going to work for us.</p><h2>Horizontal Touch Menu</h2><p>One of the trends on the mobile web is horizontal scrolling. Touch scrolling horizontally is a natural gesture.</p><p>You can see examples of horizontal touch scrolling in use on the websites and apps of Apple, Amazon, Facebook, Basecamp, and many others.</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1506456681481-6VJI0CAKHOY2R9ALDOGE/Minneapolis+Yoga+Conference%3A+Horizontal+Touch+Scrolling" data-image-dimensions="930x560" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1506456681481-6VJI0CAKHOY2R9ALDOGE/Minneapolis+Yoga+Conference%3A+Horizontal+Touch+Scrolling?format=1000w" width="930" height="560" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1506456681481-6VJI0CAKHOY2R9ALDOGE/Minneapolis+Yoga+Conference%3A+Horizontal+Touch+Scrolling?format=100w 100w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1506456681481-6VJI0CAKHOY2R9ALDOGE/Minneapolis+Yoga+Conference%3A+Horizontal+Touch+Scrolling?format=300w 300w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1506456681481-6VJI0CAKHOY2R9ALDOGE/Minneapolis+Yoga+Conference%3A+Horizontal+Touch+Scrolling?format=500w 500w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1506456681481-6VJI0CAKHOY2R9ALDOGE/Minneapolis+Yoga+Conference%3A+Horizontal+Touch+Scrolling?format=750w 750w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1506456681481-6VJI0CAKHOY2R9ALDOGE/Minneapolis+Yoga+Conference%3A+Horizontal+Touch+Scrolling?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1506456681481-6VJI0CAKHOY2R9ALDOGE/Minneapolis+Yoga+Conference%3A+Horizontal+Touch+Scrolling?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1506456681481-6VJI0CAKHOY2R9ALDOGE/Minneapolis+Yoga+Conference%3A+Horizontal+Touch+Scrolling?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
          
          <figcaption class="image-caption-wrapper">
            <p>This is what our horizontal scrolling looks like on mobile. A person can swipe left and right to access more information.&nbsp;We fade out the left and right sides to indicate there's something more to see.</p>
          </figcaption>
        
      
        </figure>
      

    
  


  





  <p>The key to all of this is a non-standard CSS rule called <strong><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-overflow-scrolling">-webkit-overflow-scrolling</a></strong>. However, you still need a few more things to get this right.</p><p>We start with a set of three elements. In our case, we chose to use a div for the container, a nav to indicate navigation, and a ul to house the menu elements. Something like this should work.</p>
























  
    <pre><code class="language-markup">&lt;div class="touch-container">
  &lt;nav class="nav">
    &lt;ul class="nav-ites">
      &lt;li>Home&lt;/li>
      &lt;li>Blog&lt;/li>
      &lt;li>About&lt;/li>
      &lt;li>Contact&lt;/li>
    &lt;/ul>
  &lt;/nav>
&lt;/div></code></pre>
  




  <p>You'll want to start by giving your ul element a list-style of none and the li elements a display of inline-block. For the purposes of this demo, we'll also increase the font-size and padding for the li elements. This will help us demonstrate horizontal touch scrolling.</p>
























  
    <pre><code class="language-markup">&lt;style>
  .nav-items {
    list-style: none;
    padding: 0;
  }
  .nav-items > li {
    display: inline-block;
    font-size: 24px;
    padding: 12px 24px;
  }
&lt;/style></code></pre>
  




  <p>Next, on the ul element, set overflow-x to auto and overflow-y to hidden. This will allow the browser to use a scrollbar if things overflow in the x direction. If anything overflows in the y direction, it will be hidden.</p>
























  
    <pre><code class="language-markup">&lt;style>
  .nav-items {
    list-style: none;
    padding: 0;
    overflow-x: auto;
    overflow-y: hidden;
    white-space: nowrap;
  }
  .nav-items > li {
    display: inline-block;
    font-size: 24px;
    padding: 12px 24px;
  }
&lt;/style></code></pre>
  




  <p>At this point, you can add -webkit-overflow-scrolling: touch; to your ul element. Congratulations. You now have a working version of a horizontal touch scrolling navigation. You could stop here, but there's one last trick that will make things look a bit nicer. You don't want that ugly scroll bar showing up when people swipe to the left and right.</p><p>The container div is responsible for hiding the horizontal scroll bar. Without it, a horizontal scroll bar will show when a person is interacting with your navigation. If you don’t care about that, you could get away with not using a container div. In our case, we wanted to hide the scroll bar. This container div works together with the ul to hide the scroll bar. To hide the scrollbar, you’ll be doing two things:</p><ul><li>Setting a height and changing the overflow to hidden on the container div.</li><li>Giving the ul element a bottom padding (pushing the scroll bar out of view).</li></ul><p>Once you've done all that, your CSS should look like this.</p>
























  
    <pre><code class="language-markup">&lt;style>
  .touch-container {
    overflow: hidden;
    height: 68px;
  }
  .nav-items {
    list-style: none;
    padding: 0;
    overflow-x: auto;
    overflow-y: hidden;
    white-space: nowrap;
    -webkit-overflow-scrolling: touch;
  }
  .nav-items > li {
    display: inline-block;
    font-size: 24px;
    padding: 12px 24px;
    padding-bottom: 50px;
  }
&lt;/style></code></pre>
  




  <h2>Wrapping Up</h2><p>When all was said and done, we were satisfied with how things turned out. When we started the Minneapolis Yoga Conference website, we looked for ways to make progress more efficient. Coming from Squarespace, we had an opportunity to do things our way.</p><p>In the future, we'll continue to use style guides to help with development. We also want to continue exploring ways to bring non-developers closer to the release cycle. This may mean different things at different times. In the case of this website, it was quicker content updates. On a different project, it may mean something else.</p><p>Finally, if you haven't noticed horizontal touch scrolling before, I'm sure you will now. It's starting to be used in many different places. If you find a neat use of it, let us know in the comments below.</p>]]></description><media:content height="630" isDefault="true" medium="image" type="image/png" url="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1507733762973-VLU76P29VC5O4U6UC3QN/social.png?format=1500w" width="1200"><media:title type="plain">How we built the Minneapolis Yoga Conference website</media:title></media:content><dc:creator>andrew@idealprojectgroup.com (Ideal Project Group, LLC)</dc:creator></item><item><title>Beginner Web Developer Series: Debugging (for web developers)</title><category>Engineering</category><pubDate>Wed, 16 Dec 2015 19:38:36 +0000</pubDate><link>https://www.projectidealism.com/posts/2015/12/16/debugging-for-web-developers</link><guid isPermaLink="false">50d01cefe4b000726e548760:51ab864fe4b0db4a25537edb:552c23fce4b005f6ac4d16aa</guid><description><![CDATA[<p><em>This is part one of five in my Beginner Web Developer series. It's a series of posts targeted toward people who want to be web developers. These people could be high school or college students as well as people looking for a new career. The series is not focused on writing code, but rather,&nbsp;the countless other things you must do as a web developer.</em></p><p>If you know how to debug a web application, you'll add a ton of value to your team and to your company. Simply knowing how to use the developer tools in your web browser will get you a long way. Even if you're only responsible for QA (quality assurance), being able to investigate what's happening with an application is a great skill.</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450291533309-4TL6MCVVX8ZRTU845KFR/image-asset.jpeg" data-image-dimensions="1024x680" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450291533309-4TL6MCVVX8ZRTU845KFR/image-asset.jpeg?format=1000w" width="1024" height="680" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450291533309-4TL6MCVVX8ZRTU845KFR/image-asset.jpeg?format=100w 100w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450291533309-4TL6MCVVX8ZRTU845KFR/image-asset.jpeg?format=300w 300w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450291533309-4TL6MCVVX8ZRTU845KFR/image-asset.jpeg?format=500w 500w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450291533309-4TL6MCVVX8ZRTU845KFR/image-asset.jpeg?format=750w 750w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450291533309-4TL6MCVVX8ZRTU845KFR/image-asset.jpeg?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450291533309-4TL6MCVVX8ZRTU845KFR/image-asset.jpeg?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450291533309-4TL6MCVVX8ZRTU845KFR/image-asset.jpeg?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
          
          <figcaption class="image-caption-wrapper">
            <p>Image Credit:&nbsp;Michael Himbeault (http://flic.kr/p/7NFTF6)</p>
          </figcaption>
        
      
        </figure>
      

    
  


  





  <p>You don't learn how to debug overnight. It's a way of thinking developed year after year. After awhile, you'll develop intuitions about bugs to help you solve them quickly. This will help you work faster and move on to other important things.&nbsp;Simply put, if you put in the effort to debug, you'll improve as a web developer.</p>























<hr />


  <h2>Interpreting bug reports</h2><p>Whether it comes from a customer or a colleague, you'll have to field a lot of bug reports as a web developer. Knowing how to interpret these bug reports is a key skill you should be growing over time. Asking the right questions is key to success.</p><p>You'll be receiving bug reports from non-technical people. Remember, they don't know everything about your application, so they're trying their best to explain their problem. Also, they might rely on your application for day to day operations and the bug they're reporting is making their day rather frustrating. As frustrated as they may be, you should stay calm.</p><p>Since most people will be non-technical, you'll often need to politely ask for clarification. What browser are they using? What page were they on? What were the exact steps performed before this happened? Some of these questions may sound simple on the surface, but they'll be difficult to answer. Remember, non-technical means the person isn't a developer. They aren't trying to trick you - if you need more clarification, ask again. Even better, <a href="http://projectidealism.com/posts/2014/1/17/better-communication-annotating-your-screenshots">ask for a screenshot</a>.</p><p>Gathering this information can be tough for both you and the customer providing it. You must learn how to bridge this communication gap. Try to refer to things in terms they'll understand. Keep note of the way you communicate to figure out what works and what doesn't. Screen-sharing and/or screen recordings can be a great tool when used correctly.</p><p>Once you think you have enough information,&nbsp;reproduce it yourself. Keep track of the steps you took to reproduce it.&nbsp;Once it's fixed, you can use those steps to double check your work.</p><p>If you can't reproduce, it could be a problem that only exists on a certain browser. CSS and JavaScript can easily behave somewhat differently on each browser. Use Google to search for similar issues.</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450291837159-67VHXBQ7A9ITORVQ7X6O/Screen+Shot+2015-12-16+at+1.48.12+PM.png" data-image-dimensions="634x438" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450291837159-67VHXBQ7A9ITORVQ7X6O/Screen+Shot+2015-12-16+at+1.48.12+PM.png?format=1000w" width="634" height="438" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450291837159-67VHXBQ7A9ITORVQ7X6O/Screen+Shot+2015-12-16+at+1.48.12+PM.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450291837159-67VHXBQ7A9ITORVQ7X6O/Screen+Shot+2015-12-16+at+1.48.12+PM.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450291837159-67VHXBQ7A9ITORVQ7X6O/Screen+Shot+2015-12-16+at+1.48.12+PM.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450291837159-67VHXBQ7A9ITORVQ7X6O/Screen+Shot+2015-12-16+at+1.48.12+PM.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450291837159-67VHXBQ7A9ITORVQ7X6O/Screen+Shot+2015-12-16+at+1.48.12+PM.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450291837159-67VHXBQ7A9ITORVQ7X6O/Screen+Shot+2015-12-16+at+1.48.12+PM.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450291837159-67VHXBQ7A9ITORVQ7X6O/Screen+Shot+2015-12-16+at+1.48.12+PM.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p>If you still can't reproduce the issue, check your copy and any error messages you might see. Maybe the customer is getting confused. Your company may need to tweak the way things are worded on a page. Although these aren't bugs in the software sense, these are bugs within the user experience. These can be especially frustrating. The customer wants to do something (like reset their password), and the application is telling them they can't.&nbsp;<em>Did you know?&nbsp;</em><em>According to the Gartner Group, <a href="http://www.gartner.com/newsroom/id/1426813">between 20% to 50% of all help desk calls are for password resets</a>.</em></p><p>After you've properly interpreted the bug report and reproduced the issue, you're ready to work toward a fix. Even if you aren't assigned to implement the actual fix, performing the next few steps will prove invaluable to the person eventually assigned to the problem.</p><h2>Checking for recent code changes</h2><p>The easiest place to look is the latest release. Find the most recent deployment to production and start looking through what changed (if you use GitHub, you can <a href="https://help.github.com/articles/comparing-commits-across-time/">perform a diff</a> to see changes).&nbsp;Take a look at the developer responsible for most of the changes and ask them about the issue. They'll be most familiar with the code and chances are the code will still be fresh in their mind.</p><p>Remember, you aren't trying to assign blame. You're trying to investigate the issue.&nbsp;Pulling in the right people is key. The right person should have an idea of where to look.</p><p>If you're on your own and the release was large, your best bet is to look through each commit. If you're not yet familiar with version control, a commit is a set of changes to the code. It's like a before and after photo.</p><p>If the release was small, you'll likely want to look at everything at once. If your team uses <a href="https://help.github.com/articles/using-pull-requests/">pull requests</a> (a group of commits with a related discussion), check that. Use the pull request to see all changes made since the last release.</p><h2>Building a timeline</h2><p>Not all bugs are new. While it's important to first look at the most recent changes to the application, you may have some bugs that have existed for some time. These issues are usually not critical, but still result in undesired behavior. Either way, it's still important to be able to identify these elder bugs.</p><p>Since you're likely using version control, you should be pulling up the commit history of the application in question. Your best tool will be talking with other developers and looking at the history of changes. If you know the general section of code which is causing the problem, you can look at the history of changes to that section. GitHub has a tutorial about <a href="https://help.github.com/articles/differences-between-commit-views/">seeing the difference between files</a>.</p><p>Once you figure out when the bug was introduced, your first reaction shouldn't be to tell the developer responsible for it. Try to figure out the exact date and time when this change hit production. You should be able to determine when it was released and what particular release it was introduced with. Keeping a history of deployments to production is considered a best practice in the industry.</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450293088455-BJ9ZILVHPW6U11K1SXOP/image-asset.jpeg" data-image-dimensions="573x457" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450293088455-BJ9ZILVHPW6U11K1SXOP/image-asset.jpeg?format=1000w" width="573" height="457" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450293088455-BJ9ZILVHPW6U11K1SXOP/image-asset.jpeg?format=100w 100w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450293088455-BJ9ZILVHPW6U11K1SXOP/image-asset.jpeg?format=300w 300w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450293088455-BJ9ZILVHPW6U11K1SXOP/image-asset.jpeg?format=500w 500w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450293088455-BJ9ZILVHPW6U11K1SXOP/image-asset.jpeg?format=750w 750w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450293088455-BJ9ZILVHPW6U11K1SXOP/image-asset.jpeg?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450293088455-BJ9ZILVHPW6U11K1SXOP/image-asset.jpeg?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450293088455-BJ9ZILVHPW6U11K1SXOP/image-asset.jpeg?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p>A timeline of a bug is important for many different reasons. It's particularly important to understand the impact of the issue. If it's existed in production for over a year, chances are there isn't much impact. If an issue is high impact, it effects a lot of people and your customer service team will be bombarded with incoming tickets from concerned (and some pissed off)&nbsp;customers.</p><p>If the issue isn't high impact, you should understand the value of a fix. It may not be that important to your company and you should classify it as such. However, changing gears is important. If an issue is determined to be high impact, you should react as such.</p><h2>Proposing a solution</h2><p>Understand the impact. Do you need to perform emergency maintenance? Do you need to forward this to every developer so they can stop what they're doing and work on it immediately? If so, you don't want to release a quick fix only to see the issue grow or to see an entirely new issue pop up. Most often, taking the time to properly fix a high impact issue is much more important than the speed in which you fix it.&nbsp;In the typically long timeline of an application, one bug is nothing but a blip on the radar.</p><p>Try not to take on extra pressure while fixing a high impact issue. While you don't want to spend days patching up a critical bug, you don't want to allow someone to drive you to make more mistakes. If you don't feel comfortable in what you're doing, say it. It's your responsibility to admit what you don't know.</p><p>If you get assigned to fix the issue, use your ability to reproduce it. Only change what's absolutely necessary. You don't want to introduce new and unrelated issues. You also don't want to work on other features, tweaks, or anything else. Stay focused on the issue and only that issue. After you implement a fix, follow the same steps you used to reproduce the issue. If the issue remains, your fix wasn't a fix.</p><h2>Why did this happen?</h2><p>After fixing the issue, reflect.</p><p>Try to understand the bug. Was it a typo? Was it an honest mistake or a misspelling? Is it something that should have been caught in a code review? Was the logic in the code completely wrong?&nbsp;Is there a test you could write that would've caught this issue before it hit production?&nbsp;Sometimes you might ask, how did this ever happen?</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450292710184-BMDM0597JHNHRLJ61ZPW/image-asset.jpeg" data-image-dimensions="500x414" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450292710184-BMDM0597JHNHRLJ61ZPW/image-asset.jpeg?format=1000w" width="500" height="414" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450292710184-BMDM0597JHNHRLJ61ZPW/image-asset.jpeg?format=100w 100w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450292710184-BMDM0597JHNHRLJ61ZPW/image-asset.jpeg?format=300w 300w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450292710184-BMDM0597JHNHRLJ61ZPW/image-asset.jpeg?format=500w 500w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450292710184-BMDM0597JHNHRLJ61ZPW/image-asset.jpeg?format=750w 750w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450292710184-BMDM0597JHNHRLJ61ZPW/image-asset.jpeg?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450292710184-BMDM0597JHNHRLJ61ZPW/image-asset.jpeg?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1450292710184-BMDM0597JHNHRLJ61ZPW/image-asset.jpeg?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p>It's ok to ask these questions as long as you don't make it personal. Reflecting on a bug isn't a shaming session. It's a chance to learn and improve what you do in the future. You may not have all the answers - feel free to encourage the other developers on your team to discuss it.</p><p>If you're the developer responsible for the bug, take full responsibility for it. Don't try to pass it off on others. No matter what,&nbsp;stand up for yourself if need be. If other people on your team are criticizing you, listen but remind them you're only human. The best thing you can do is focus on getting better. The good thing about mistakes is we learn from them. Chances are, the bug will stick with you and you won't make the same mistake in the future.</p><p>If you're not responsible for the issue and simply reviewing it with your team, don't shame the responsible party. Empty criticism doesn't help anyone. Be helpful.&nbsp;Help them get better. When they get better, your team gets better.</p><h2>Bonus: Developer tools (Chrome)</h2><p>For sake of simplicity, we'll stick to Chrome and its phenomenal suite of developer tools. Here are some of the things you can do:</p><ul><li>Why is this link a certain color? (Inspecting CSS)</li><li>Does this text look better if it's slightly larger? (Tweaking CSS)</li><li>Why is this button not doing what it's supposed to do? (Checking for JavasScript errors)</li></ul><p>If you're using Google Chrome, right-click anywhere on a web page and click Inspect Element. This will open the developer tools (which look something like the below image).</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1429285713136-KLBP95IZYLPWJHU2U7ON/google-chrome-developer-tools.png" data-image-dimensions="904x252" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1429285713136-KLBP95IZYLPWJHU2U7ON/google-chrome-developer-tools.png?format=1000w" width="904" height="252" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1429285713136-KLBP95IZYLPWJHU2U7ON/google-chrome-developer-tools.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1429285713136-KLBP95IZYLPWJHU2U7ON/google-chrome-developer-tools.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1429285713136-KLBP95IZYLPWJHU2U7ON/google-chrome-developer-tools.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1429285713136-KLBP95IZYLPWJHU2U7ON/google-chrome-developer-tools.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1429285713136-KLBP95IZYLPWJHU2U7ON/google-chrome-developer-tools.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1429285713136-KLBP95IZYLPWJHU2U7ON/google-chrome-developer-tools.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1429285713136-KLBP95IZYLPWJHU2U7ON/google-chrome-developer-tools.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p>When I started writing this, my intention was to write this section on my own. I had a vision of a section of animated gifs and some text. Then, Dev Tips Daily popped up in my Twitter feed. I don't think I could do a much better job, so I'm linking to my favorite ones.</p><p>Learn how to <a href="https://umaar.com/dev-tips/7-dom-search-by-selector/">search by CSS class</a>. <a href="https://umaar.com/dev-tips/17-quick-edit-element/">Quickly change an HTML element</a>. <a href="https://umaar.com/dev-tips/11-copy-response/">Copy the response of something on the network tab</a>. If you want to become a power user of these developer tools, I encourage you to signup for their daily email. You'll surely learn something new every day.</p><h3>Resources</h3><ul><li><a href="https://umaar.com/dev-tips/">Dev Tips Daily</a></li><li><a href="https://developer.chrome.com/devtools">Chrome DevTools Overview</a></li><li><a href="http://simpleprogrammer.com/2011/06/17/the-debugger-mindset/">The Debugger Mindset</a></li><li><a href="http://programmers.stackexchange.com/questions/10735/how-to-most-effectively-debug-code">How to most effectively debug code?</a></li><li><a href="http://www.makinggoodsoftware.com/2009/06/14/7-steps-to-fix-an-error/">7 steps to fix an error</a></li></ul>























<hr />


  <p><em>Need help integrating the systems you use? <a href="http://idealprojectgroup.com/">Get in touch with us.</a></em></p>]]></description><dc:creator>andrew@idealprojectgroup.com (Ideal Project Group, LLC)</dc:creator></item><item><title>Announcing the colorizable gem</title><category>Engineering</category><pubDate>Tue, 24 Nov 2015 14:54:00 +0000</pubDate><link>https://www.projectidealism.com/posts/2015/11/24/announcing-the-colorizable-gem</link><guid isPermaLink="false">50d01cefe4b000726e548760:51ab864fe4b0db4a25537edb:565476ede4b036d0d6e109a6</guid><description><![CDATA[<p>We were working on a project recently where we needed to store colors and convert those colors to different formats (<a href="http://blog.tulasoftware.com/posts/2014/9/3/introducing-studio-branded-iphone-apps-and-student-access-on-ios">we build custom iPhone apps</a> for studios that use Tula Software). Rather than jump right in and write our own code for this, we looked around a found a great gem called <a href="https://github.com/halostatue/color">color</a>.</p><p>We were further inspired by one of my favorite gems, <a href="https://github.com/RubyMoney/money-rails">money-rails</a>, which allows you to simply mark an attribute as "money" and it does all the work for you (formatting, currency, converting to dollars if stored as cents).</p><p>We threw together a similar gem called <a href="https://github.com/idealprojectgroup/colorizable">colorizable</a>. Colorizable gives you all the power of the color gem, turned on with a simple "colorize" statement.</p>]]></description><dc:creator>andrew@idealprojectgroup.com (Ideal Project Group, LLC)</dc:creator></item><item><title>Is this thing on?</title><pubDate>Sat, 07 Nov 2015 20:32:27 +0000</pubDate><link>https://www.projectidealism.com/posts/2015/11/7/is-this-thing-on</link><guid isPermaLink="false">50d01cefe4b000726e548760:51ab864fe4b0db4a25537edb:563e5bb6e4b0d1f51d0a4ed6</guid><description><![CDATA[<p>One of the things I've noticed is that once you're on a roll with writing it's much easier to keep it going. Likewise, take an extended hiatus and next thing you know it's been 6 months since your last post.</p><p>I've been writing very regularly on <a target="_blank" href="http://blog.tulasoftware.com">the Tula blog</a>, but haven't been writing here as much as I'd like. Time to change that, so here's a post to unclog the tubes.</p><p>More better to follow soon.</p>]]></description><dc:creator>andrew@idealprojectgroup.com (Ideal Project Group, LLC)</dc:creator></item><item><title>If you're a small team with no sysops guy, PaaS will save your SaaS</title><category>Engineering</category><pubDate>Mon, 09 Feb 2015 14:58:00 +0000</pubDate><link>https://www.projectidealism.com/posts/2015/2/5/if-youre-a-small-team-with-no-sysops-guy-paas-will-save-your-saas</link><guid isPermaLink="false">50d01cefe4b000726e548760:51ab864fe4b0db4a25537edb:54d3dd63e4b04682afeb9bfe</guid><description><![CDATA[<p>We've recognized it time and time again.</p><p>Just this past week, the <a href="https://www.qualys.com/research/security-advisories/GHOST-CVE-2015-0235.txt">GHOST</a>&nbsp;issue&nbsp;(glibc gethostbyname buffer overflow) popped up. Many people all over the world were scrambling to patch their servers. Large companies and small companies alike, they all had to deal with it one way or another.</p><p>As usual with anything like this, we looked to Engine Yard for an update. Our app servers and database servers are hosted on Amazon EC2 and Engine Yard is a PaaS that sits on top of it. Engine Yard provided their customers with a timely update about the issue and how they planned to solve it.</p><p>They've gained our trust over time, so we simply stopped worrying about it and waited until they released their patch. Once they released their patch, we followed their detailed instructions and applied the patch on our own schedule. As with something as far reaching as GHOST, it wasn't super easy, but we made it through and we're now the proud owners of patched servers and relaxed minds.</p><p>With our servers hosted on vanilla EC2 and without a talented, dedicated sysops guy, this situation would have been a nightmare for us. Instead of shipping&nbsp;new improvements to our product, we would've been at a full stop investigating, experimenting, testing, etc. etc. We don't consider ourselves experts when it comes to managing servers. While most of our engineers have plenty of experience with Linux, we don't want to mess around with sysops.</p><p>We want to focus on what we do best - releasing software.</p><p>Do we always want to be afraid of Chef recipes, server updates, automated provisioning and the like? Certainly not. However, at this point, we don't want to rely on it as a core competency.</p><p>By not hosting your product on a PaaS, you're designating sysops as a core competency of your engineering team. If you don't, you'll pay the price.</p><p>One day, you might pay the price in security. You won't have anyone watching out for security issues and your servers will go unpatched, open to abuse.</p><p>Next time, you might lose a week or two on scaling. You won't have a proper, load-balanced cluster. Your servers will be on fire. Your engineering team will be firefighting for days. They'll have to learn Chef, haproxy, and countless other things they haven't been spending time with.</p><p>You'll most definitely be paying the price during your day-to-day operations. Your deploys will cause downtime. Deploys will be frowned upon.&nbsp;<span>Your engineering won't be happy. They'll have to stay late to deploy something that should've been deployed as soon as it was ready.</span></p><p><span>Companies that manage everything from deployments to automated scaling are saying, "Hey, sysops is important to us. It's a core competency of our business. We get huge value from it." If you're trying to imitate them and you don't have anyone focused on sysops, you're not ready. Companies like Facebook get huge value from their data centers. They need them. If you're not ready to hire someone with a specific focus on the subject, you don't.</span></p><p><span>The argument for small businesses and PaaS is a numbers game - in a good way. You might think it's more expensive at first, but it's not. Here's an easy list of things we receive from Engine Yard:</span></p><ul dir="ltr"><li>Someone to talk to when a weird problem pops up</li><li>Someone to be on the lookout for security patches</li><li>Someone to ask about scaling</li><li>Someone to alert us about server maintenance on EC2</li><li>Someone to improve our server configuration</li></ul><p>That's just the short list. When you start to think about the amount of value you get from a PaaS, it's enormous. It's far cheaper than what you would be paying someone&nbsp;in annual salary to be your sysops guy.</p>]]></description><dc:creator>andrew@idealprojectgroup.com (Ideal Project Group, LLC)</dc:creator></item><item><title>Spring cleaning your code base</title><category>Engineering</category><pubDate>Mon, 02 Feb 2015 15:51:00 +0000</pubDate><link>https://www.projectidealism.com/posts/2015/1/27/spring-cleaning-your-code-base</link><guid isPermaLink="false">50d01cefe4b000726e548760:51ab864fe4b0db4a25537edb:54c85cade4b0723be33445f7</guid><description><![CDATA[<p>Code rots over time. While you're busy adding new features to your app, you might be forgetting to throw out the old.&nbsp;This is a friendly reminder to sweep out the garage and get rid of the things you don't need.</p><p>You don't have to scour through every line of code to get results. Here are some areas you may be able to score a quick win.</p><p><strong>Move any third-party assets in `app/assets` to `vendor/assets`.</strong>&nbsp;Putting third-party assets in your `app/assets` directory is generally a mistake, and that's ok. Clean up and put them where they belong and you'll be fine.</p><p><strong>Remove any CSS files and/or rules&nbsp;no longer being used.</strong>&nbsp;The level of detail you achieve here depends on how much time you want to spend. Removing unused CSS may be as simple as removing some files you're no longer using. If you want to dive into removing rules, there's a great tool for that called <a href="https://github.com/aanand/deadweight">deadweight</a>.</p><p><strong>Remove old JavaScript files.</strong>&nbsp;This is usually easy and difficult. You'll probably find at least one library or plugin no longer in use. Just remove it - that's the easy part. If you have a bunch of your own custom JavaScript i.e. a Backbone application, you may need to comb through it a bit more to find out which parts are not in use.</p><p><strong>Get rid of legacy models/database tables.</strong>&nbsp;A few legacy models may have leaked into your code base early on in the life of your app (when you're under rapid development). That's ok. Figure out what they are and get rid of them. Write a migration to remove the table, too.</p><p><strong>Find any unused partials.</strong>&nbsp;If you're refactoring quite a bit, you might forget to remove some unused partials. Check out this <a href="https://github.com/vinibaggio/discover-unused-partials">gem to remove unused partials</a>.</p>]]></description><dc:creator>andrew@idealprojectgroup.com (Ideal Project Group, LLC)</dc:creator></item><item><title>Three ways you can bend the ransack gem to your liking</title><category>Engineering</category><pubDate>Wed, 28 Jan 2015 19:08:00 +0000</pubDate><link>https://www.projectidealism.com/posts/2015/1/12/three-ways-you-can-bend-the-ransack-gem-to-your-liking</link><guid isPermaLink="false">50d01cefe4b000726e548760:51ab864fe4b0db4a25537edb:54b4414be4b0f9ef835e5139</guid><description><![CDATA[<p>In <a href="https://tulasoftware.com">the world's best yoga studio software for independent yoga studios</a>, we have a page which lists all people in your studio. It's super basic: it only shows their name and role at the studio along with some actions you can take i.e. edit, delete. We haven't improved it much along the way.</p><p>I wanted to change that. TULA, in its essence, is a yoga centric CRM + billing system. Armed with inspiration from <a href="https://intercom.io">Intercom</a> and their brilliant list of people, I set out to improve our people page.</p><p>We've had requests from our customers like "show me all the students who haven't been to class since X date" and "show me all the students who have joined the studio since Y date". These are great questions to ask and TULA should give you the answers. It's as simple as that.</p><p>To give them this, I did some investigation and found a great gem called ransack (if you haven't already, check out the <a href="https://github.com/activerecord-hackery/ransack">ransack GitHub page</a>). I quickly became satisfied with ransack as the basis of this new page. However, there were a few things I was constantly fighting with.</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1422471911029-9GL0YDH0JARZ4WJ6AC1C/image-asset.png" data-image-dimensions="1000x937" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1422471911029-9GL0YDH0JARZ4WJ6AC1C/image-asset.png?format=1000w" width="1000" height="937" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1422471911029-9GL0YDH0JARZ4WJ6AC1C/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1422471911029-9GL0YDH0JARZ4WJ6AC1C/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1422471911029-9GL0YDH0JARZ4WJ6AC1C/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1422471911029-9GL0YDH0JARZ4WJ6AC1C/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1422471911029-9GL0YDH0JARZ4WJ6AC1C/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1422471911029-9GL0YDH0JARZ4WJ6AC1C/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1422471911029-9GL0YDH0JARZ4WJ6AC1C/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <h2 id="yui_3_17_2_1_1422471864389_16867">Ransackers derived from column aliases</h2><p>This frustrated me for some time. I had a query like this:</p>



























  <p>I wanted to use their role, last attendance date, last purchase date, and join date as sortable columns in the table. However, it wasn't working out of the box until I realized I could simply pass an Arel node (<a href="https://github.com/activerecord-hackery/ransack/issues/479">thanks to this GitHub issue</a>) of the column alias to a ransacker.</p>



























  <h2>Default sort order</h2><p>You can also use ransack to <a href="https://github.com/activerecord-hackery/ransack/wiki/Sorting-in-the-Controller">set a default sort order</a> for when your users first visit the page.</p>



























  <h2>Nulls last with ransackers</h2><p>When you start sorting by column, you'll quickly notice null values getting in your way of the important data. For example, if you're sorting by the last time a user has made a purchase, you'll most likely want to see an order like this: about an hour ago, three hours ago, one week ago, etc. You wouldn't want to see an order like this: never, never, never, never, ... , about an hour ago, etc. The important data is getting buried by the nulls.</p><p>Ransack doesn't support this by default. However, there's a workaround (read more about how to <a href="https://github.com/activerecord-hackery/ransack/issues/443">add nulls last to ransack</a>).</p><p>The workaround is great; however, it doesn't immediately work when you're using ransackers which return an instance of `Arel::Nodes::InfixOperation` or similar. You'll see a generated&nbsp;query similar to&nbsp;the following:</p>



























  <p>Obviously, this isn't valid SQL. This is actually due to the `full_name` ransacker defined above and in this case, the default sort order set to `full_name`.&nbsp;However,&nbsp;<span>`Arel::Nodes::InfixOperation` responds to `to_sql`, so you can test for this case and transform it into valid SQL for the query. The code below will show you how:</span></p>



























  <p id="yui_3_17_2_5_1421170697272_9173"><span id="yui_3_17_2_5_1421170697272_9172">Ransack is powerful, and we're just scratching the surface of its power. If you think I missed anything important, just mention me on Twitter or add a comment below.</span></p>]]></description><dc:creator>andrew@idealprojectgroup.com (Ideal Project Group, LLC)</dc:creator></item><item><title>Poker, business, and the optimal decision</title><category>Business</category><pubDate>Mon, 26 Jan 2015 15:12:15 +0000</pubDate><link>https://www.projectidealism.com/posts/2015/1/12/poker-business-and-the-optimal-decision</link><guid isPermaLink="false">50d01cefe4b000726e548760:51ab864fe4b0db4a25537edb:54b445e2e4b0ef6f89fa2279</guid><description><![CDATA[<p>When you reach a certain level of any topic, you realize how deep the rabbit hole goes. That's why the term professional, when used the right way, is so prestigious. When it comes to poker, the same is true. It's a deep game and most variants of pokers haven't achieved GTO (<a href="http://en.wikipedia.org/wiki/Game_theory">game theory</a> optimal).</p><p>Sure, there's a generally agreed upon way to play most games of poker. Most often, aggression is the key to victory. But, most people think it's all about the numbers or the cards you're dealt; however,&nbsp;it couldn't be further from the truth.</p><p>Variables you must&nbsp;consider:</p><ul><li>The number of chips you have (money in the bank)</li><li>The number of people still in the hand&nbsp;<span>(people still in the game)</span></li><li>The person on your left</li><li>Your opponent's aggression</li><li>Your opponent's lack of aggression (most incumbents)</li><li>The number of chips in the pot</li><li>The number of chips on the table (the size of the market)</li><li>The person on your right</li><li>Your opponent's range of cards (their people)</li><li>Your cards (your people)</li><li>The list goes on and on...</li></ul><p>You use all of these variables to make a decision. You should always ask yourself: What's the&nbsp;optimal decision?&nbsp;If you don't make the optimal decision, you might get lucky and still win. However, you're definitely more likely to lose.</p><p>If you do make the optimal decision, you're slightly more likely to win - but you could still lose. That's the catch.</p><p>Just like poker, business follows along. You can make all the right decisions, and you can still get unlucky. On the other hand, you can make a bad decision with luck on your side.</p><p>The best we can do is make&nbsp;optimal decisions. The optimal decision is the one which gives us the greatest chance to win.</p><p>And like business, poker is a long-term game. Over the short-term, any victory or loss is almost certainly due to a high amount of luck (variance). However, when you stretch your decisions over many years, the person making the most optimal decisions reduces the amount of luck effecting his results.</p><p>An example of this in business is&nbsp;<a href="http://www.investopedia.com/terms/e/economicmoat.asp">the moat</a>. Over many years, a company makes optimal decisions, creating many different mechanisms by which they keep their competitive advantage. Compare this to the company just starting out with one product. They need some luck to stay alive.</p><p>Even though we can try, it's impossible to always find the optimal decision. Your opponent may be great at altering his play to trick you into a less than optimal decision.</p><p>Sometimes the optimal decision is to just go with it. The same is true for business. Sometimes you just don't know what to do. That's ok. Make the decision and be ok with it. The important part is to reflect and study that decision. Knowing what you know after the fact, was it the optimal decision? If yes, you were lucky. If no, figure out why. Armed with that knowledge, you should be able to move toward more optimal decisions in the future.</p>]]></description><dc:creator>andrew@idealprojectgroup.com (Ideal Project Group, LLC)</dc:creator></item><item><title>Product Market Dance</title><category>Business</category><pubDate>Thu, 15 Jan 2015 21:59:54 +0000</pubDate><link>https://www.projectidealism.com/posts/2015/1/14/product-market-dance</link><guid isPermaLink="false">50d01cefe4b000726e548760:51ab864fe4b0db4a25537edb:54b74812e4b0d16cf9f59223</guid><description><![CDATA[<p>I've never really liked the phrase 'product-market-fit'. It's never felt right to me, in the same way the phrase 'passive income' doesn't feel right. They both imply that that you get to a point of stillness at which everything stops and you're 'done'.</p><p>But that's not how the economy works, and it's certainly not how technology companies and software work.&nbsp;</p><p>Today's product/market fit might&nbsp;be tomorrow's myspace.&nbsp;The market is constantly shifting and evolving, and so too are the products that serve them. It's wise to remain focused, but not at the expense of missing an entire market shift that kills your company.&nbsp;</p><p>Markets are alive, we have new devices and new pieces of hardware&nbsp;at our disposal and&nbsp;with more coming. Not only this, people's expectations change. Like the changing beat of a song as it reaches a climax and comes back down again, so too does the market, and your customers fluctuate.</p><p>Today's Minimum Viable Product is tomorrow's starting point. Interestingly, today's failure can be tomorrow's success too, because there is such a thing as being too early.</p><p>Here's another secret: within markets there are different songs playing. Our biggest competitor to Tula is a half-a-billion dollar company in what they call the 'health, beauty and wellness' category.</p><p>That's one song I suppose.&nbsp;Another? Independent Yoga Studios.</p><p>There are many songs playing in every market.&nbsp;</p><p>There's no such thing as product/market fit unless you're talking about a short time horizon.</p><p>For anything longer, it's a dance.</p><p> </p>]]></description><dc:creator>andrew@idealprojectgroup.com (Ideal Project Group, LLC)</dc:creator></item><item><title>Venture Ethics</title><category>Business</category><pubDate>Tue, 13 Jan 2015 13:41:44 +0000</pubDate><link>https://www.projectidealism.com/posts/2015/1/12/venture-ethics</link><guid isPermaLink="false">50d01cefe4b000726e548760:51ab864fe4b0db4a25537edb:54b4896fe4b09ecf418f8a5a</guid><description><![CDATA[<p><a target="_blank" href="http://fredwilson.com">Fred Wilson</a>, the well known technology investor and all around inspirational guy, wrote a blog post yesterday titled <a target="_blank" href="http://avc.com/2015/01/ethics-and-morals/">Ethics and Morals</a>. In it, he wrote about a Venture Capitalist who turned down an investment opportunity with a company, and shortly thereafter provided an angel round for his son in a competing business.</p><p>There are more details, and <a target="_blank" href="http://avc.com/2015/01/ethics-and-morals/">the entire post</a> is worth a read.</p><p>But one of the things with the post is he didn’t actually name the name of this venture capitalist. And that’s fine I suppose, but it prompted me to ask this:</p>
























  
    <blockquote lang="en" class="twitter-tweet"><p><a href="https://twitter.com/fredwilson">@fredwilson</a> longtime fan, but isn&#39;t this pattern of VCs/Angels knowing about abusive investors &amp; not naming names borderline unethical?</p>&mdash; Andrew Wicklander (@andrewwicklandr) <a href="https://twitter.com/andrewwicklandr/status/554306132374999040">January 11, 2015</a></blockquote> 
  




  <p><br />I asked the question because this isn't the first time I've heard an investor call another investor out in public, without actually calling them out.</p><p>I recall Dave McClure calling out investors for blocking early stage investors from participating in follow on rounds (another thing Fred Wilson's written well about <a target="_blank" href="http://avc.com/2014/03/the-pro-rata-participation-right/">here</a>), for example.&nbsp;</p>
























  
    <blockquote lang="en" class="twitter-tweet"><p>really fucking tired of bigger investors pressuring founders not to let prior investors get pro-rata. expect us to not send stuff your way.</p>&mdash; Dave McClure (@davemcclure) <a href="https://twitter.com/davemcclure/status/500360823500312576">August 15, 2014</a></blockquote> 
  




  <p>There too - no names.</p><p>What I'd like to argue is that these public announcements, in and of themselves are problematic for entrepreneurs, are counterproductive to the&nbsp;investor's&nbsp;goals of attracting the best entrepreneurial talent, and underscore the very reason why people like me don't trust investors.&nbsp;</p><p>To be clear, I don't mean this in the "I don't trust them personally" kind of way. My guess is they're both probably pretty awesome, their firms are the best in the biz, etc. I think they're the 'good guys' is my point.&nbsp;</p><p>And also, <a target="_blank" href="http://avc.com/2010/06/being-present/">Fred does yoga</a>!</p><p>What I mean is, I don't trust their industry, and these non-outing outings help explain why.</p><p>To be good it seems to me investors&nbsp;have to simultaneously compete with each other, and collaborate with each other. This is so much grey for someone like me I can barely take it. And I don't mean this in a positive way about myself, I just mean it just sounds so damn hard.</p><p>But all I see when I read these non-outing outings is the fact that it's more important to protect the investor to investor relationship than it is to warn entrepreneurs about the shady investor.</p><p>And look, I get it.</p><p>I actually changed my mind in the process of writing this post about whether it was 'right' or 'wrong' not to mention names. We've had numerous investors reach out to us about <a href="http://tulasoftware.com">Tula</a>, while proudly including the fact that they invest in our main competitors. And all I can think to myself is: someone who wants to invest in us might be reaching out to our newest competitor in three years?</p><p>But I don't want to call these people out either.</p><p>What I initially thought was irritation that these investors&nbsp;weren't naming names is actually touching something deeper.&nbsp;How these dots connect for me now, is they&nbsp;highlight&nbsp;very clearly that there is an investment world, and there is an entrepreneurial world and in between there is a chasm of trust.</p><p>It makes me sad when&nbsp;investors I like and follow and admire are contributing to making this chasm larger instead of smaller, especially when&nbsp;they are each <em>usually</em> doing the latter.</p><p>But the fact of the matter&nbsp;is that they both&nbsp;have&nbsp;had a situation where they've&nbsp;fired shots across the bow at other investors, using a dog whistle instead of a bull horn, while&nbsp;on just about every other industry related topic they are talking openly and&nbsp;in public.</p><p>I think it's great that we're talking about ethics, but let's be clear, these are venture ethics, which still leave some open questions for the entrepreneur.</p><p> </p>]]></description><dc:creator>andrew@idealprojectgroup.com (Ideal Project Group, LLC)</dc:creator></item><item><title>We don't want to be anonymous, we want to be known for the first time again</title><pubDate>Sun, 11 Jan 2015 23:13:59 +0000</pubDate><link>https://www.projectidealism.com/posts/2015/1/11/we-dont-want-to-be-anonymous-we-want-to-be-known-for-the-first-time-again</link><guid isPermaLink="false">50d01cefe4b000726e548760:51ab864fe4b0db4a25537edb:54b2f08fe4b0425d528d728f</guid><description><![CDATA[<p>&nbsp;</p><p>I think sometimes about what kind of effect the internet will have on us, and in particular our children,&nbsp;as it becomes harder and harder to move away from our pasts.</p><p>I don't mean this in a 'running away from our past' dramatic kind of way. I mean it more in the spirit of, when we graduate from grade school, and then high school, then college and maybe a job or two, we end up&nbsp;sort of refining&nbsp;ourselves along the way.</p><p>When you go to university, it's sort of&nbsp;nice to meet someone who didn't know you when you had your most embarrassing high-school moment. When you take that first Director level&nbsp;job, it can be welcome&nbsp;if your new reports haven't&nbsp;seen you pass out at the Christmas party because you can't handle your whiskey.</p><p>Not that I would know anything about that.</p><p>The idea&nbsp;is that as we move through life, as we naturally transition from one period&nbsp;to the next, we bring some of ourselves forward with us, and we leave other&nbsp;parts behind.&nbsp;We learn and grow and mature and hopefully, who we are at 40 is a better version of who we are when we're 20.&nbsp;</p><p>What happens though when it becomes hard, or impossible, to leave our more&nbsp;unrefined selves behind?&nbsp;</p><p>There's a concept in psychology&nbsp;called the "<a target="_blank" href="http://en.wikipedia.org/wiki/Looking_glass_self">Looking glass self</a>" that says our self perception is based at least in part on how others perceive us. <span>This notion i</span><span>s&nbsp;so powerful</span><span>&nbsp;that people can</span><span>&nbsp;have important breakthroughs with issues such as addiction,&nbsp;</span><span>simply by seeing a new person in their lives perceiving the in a positive way.</span></p><p>If you think about it, this makes sense sort of intuitively. If you were suddenly treated like a movie star, allowed into all the greatest clubs for free, fashion designers sending you clothes for nothing and&nbsp;you had people hounding you for autographs - you'd probably have at least some shift in your sense of self. Likewise, if everyone started being very mean to you, telling you were worthless over and over again, this too would have an obvious impact.</p><p>But what happens when people's perception of us&nbsp;is based on 10 years of a Facebook timeline and 8 years of a web log? Is this simply our reputation, something that everyone in every generation before us has worked with?</p><p>Or does this always available history&nbsp;have an influence on how we're perceived? And if so, then doesn't this mean we'll perceive our own selves differently than we otherwise might have? And what happens when we're comparing our real world selves to other people's Instagram filters?</p><p>What is this doing to our perception of self?</p><p>There was a&nbsp;trend in 2014 with anonymous apps such as <a target="_blank" href="https://www.secret.ly">Secret</a> and <a target="_blank" href="http://whisper.sh">Whisper</a>&nbsp;seeing massive user growth, and for many there's a strong&nbsp;belief&nbsp;that many people have&nbsp;a craving for an anonymous presence on the internet.&nbsp;But I don't think anonymity is the thing we want.&nbsp;Anonymity is the thing we want so we can get the actual thing we want -&nbsp;which is to be know by someone else for the first time again.&nbsp;</p><p>Anonymity is just a pre-requisite for that.</p><p>The always on, always searchable, history always available nature of the internet is amazing and important and a regular thrill. But as with everything, there are trade-offs, and the internet has made it&nbsp;significantly more difficult to be known for the first time again.</p><p>I've become of the mind that anonymous apps aren't trying help us be evil or wicked or dangerous, or even anonymous, though surely there are some that use it for that. &nbsp;Instead, I think they're&nbsp;trying to help us scratch the oldest of itches: to provide a way for&nbsp;new people to&nbsp;perceive us, so that we can have more inputs so as&nbsp;to build&nbsp;our own self-perception.&nbsp;A few of us want to be anonymous, but most of us want to be known.</p><p>If we can be know by someone for the fist time again, then even better.</p><p> </p>]]></description><dc:creator>andrew@idealprojectgroup.com (Ideal Project Group, LLC)</dc:creator></item><item><title>The most important metrics are impossible to measure</title><category>Business</category><pubDate>Thu, 08 Jan 2015 03:03:24 +0000</pubDate><link>https://www.projectidealism.com/posts/2015/1/7/the-most-important-metrics-are-impossible-to-measure</link><guid isPermaLink="false">50d01cefe4b000726e548760:51ab864fe4b0db4a25537edb:54adec31e4b0342c02baf094</guid><description><![CDATA[<p>The most important metrics are impossible to measure.</p><p>Of course, this doesn't mean nothing should be measured. And it certainly doesn't mean we can't gather important insights by measuring the things that can be measured. Avoiding&nbsp;the important work of measuring the measurable is neglect indeed.</p><p>But the very most important things, they cannot be measured.</p><p>How do you measure delight?&nbsp;How do you measure the number of people that signed up because of the one rabid fan that can't stop talking about you?</p><p>In a world where everyone is inundated with everything, how do you measure the impact of a billboard that sparks&nbsp;brand recognition while listening to&nbsp;a podcast sponsorship which&nbsp;reminds you to google something which causes you to click on an&nbsp;ad?</p><p>The truth is that now more than ever, insights are what matters.</p><p>Deep domain knowledge, the ability to weave things together&nbsp;and an ability to create solutions to problems that other people don't know exist are valuable precisely because they require insight.</p><p>The other thing to keep in mind is that 'not measuring' something doesn't mean 'neglect'. It means approaching something from a different&nbsp;angle. Maybe it means instead of doing a survey of customers about a feature, you have two in-depth conversations with your longest customers.</p><p>In a world where more things are becoming more measurable, I think it's wise to take a step back and think about the&nbsp;that which cannot be measured, and think about the&nbsp;kinds of inspiration they can provide.</p>]]></description><dc:creator>andrew@idealprojectgroup.com (Ideal Project Group, LLC)</dc:creator></item><item><title>Oh no, it worked!</title><category>Business</category><pubDate>Sun, 04 Jan 2015 22:20:55 +0000</pubDate><link>https://www.projectidealism.com/posts/2015/1/4/oh-no-it-worked</link><guid isPermaLink="false">50d01cefe4b000726e548760:51ab864fe4b0db4a25537edb:54a9b962e4b0fbd5ffc5ecd8</guid><description><![CDATA[<p>The only thing scarier than failing is succeeding. (Note that I said scarier, not worse.)&nbsp;Because every success takes you to the next level. There's no finish line,&nbsp;the stakes just keep getting higher.</p><p>Now that it worked, now what? There are real people counting on you now. Your investors expect a return now. Your employees are buying houses.</p><p>You're not experimenting, you're executing.&nbsp;</p><p>If you go down, real businesses stop.&nbsp;</p><p>You matter.</p><p>Now what?</p><p>This is the idea that pays&nbsp;for the bad ones. This is the&nbsp;one that justifies your philosophy. And it's success will enable more success, or so you think.</p><p>It worked.&nbsp;</p><p>But it's not done.</p><p>Now what?</p>]]></description><dc:creator>andrew@idealprojectgroup.com (Ideal Project Group, LLC)</dc:creator></item><item><title>The tools I use every day as a web developer</title><category>Engineering</category><pubDate>Tue, 30 Dec 2014 16:06:10 +0000</pubDate><link>https://www.projectidealism.com/posts/2014/12/29/the-tools-i-use-every-day-as-a-web-developer</link><guid isPermaLink="false">50d01cefe4b000726e548760:51ab864fe4b0db4a25537edb:54a213a4e4b07419f398efea</guid><description><![CDATA[<p>As web developers, we use so many different tools everyday. We can easily forget about everything we depend on. In the spirit of the new year, I want to take a moment to recognize all of the great products and projects which help me be the best developer I can be.</p><p>There's a saying out there, "You're only as good as your tools." <a href="http://www.timrosenblatt.com/blog/2009/10/20/youre-only-as-good-as-your-tools/">(1)</a> <a href="http://renaissanceronin.wordpress.com/2014/05/17/youre-only-as-good-as-your-tools/">(2)</a>&nbsp;This rings true in many different professions and in life. Tools that make you better at what you do are generally a great investment - typically risk free.</p><p>Here are my favorites. I use these every day, if not, every week.</p><ul><li><a href="https://github.com/sstephenson/rbenv">rbenv</a> (Ruby version manager): if you don't use it, start using it today</li><li><a href="https://github.com/ddollar/foreman">foreman</a> (process control): start your Rails process, workers, etc. with one command</li><li>Google &amp; StackOverflow: the world's largest documentation cache</li><li>tmux &amp; <a href="https://github.com/tmuxinator/tmuxinator">tmuxinator</a>: Check out my <a href="http://projectidealism.com/posts/2013/9/20/my-tmux-configuration-with-tmuxinator">sample configuration for tmuxinator</a></li><li><a href="http://git-scm.com/">git</a> &amp; GitHub</li><li>Sublime Text 3 and countless plugins (<a href="https://packagecontrol.io/">PackageControl</a>,&nbsp;<a href="https://packagecontrol.io/packages/Better%20CoffeeScript">BetterCoffescript</a>, <a href="https://packagecontrol.io/packages/Git">Git</a>, <a href="https://packagecontrol.io/packages/GitGutter">GitGutter</a>, <a href="https://packagecontrol.io/packages/Pretty%20JSON">Pretty JSON</a>, <a href="https://packagecontrol.io/packages/TrailingSpaces">TrailingSpaces</a>, <a href="https://github.com/SublimeColors/Solarized">Solarized</a>)</li><li><a href="http://www.vim.org/">vim</a></li><li>Rubygems</li><li>ssh: connecting to remote servers and setting up ssh tunnels</li><li>scp: copy files securely to servers via ssh</li><li><a href="http://support.apple.com/en-us/HT201361">OS X screenshot shortcuts</a> &amp; annotations</li><li>Chrome developer tools: take time to learn the power in your browser</li><li><a href="https://github.com/charliesome/better_errors">better_errors</a> gem: replaces the stardard Rails error page with a live REPL</li><li><a href="https://github.com/nixme/jazz_hands">jazz_hands</a> gem: give yourself a greatly improved Rails console</li><li><a href="https://github.com/burke/zeus">zeus</a> gem: preload your Rails app to <a href="http://robots.thoughtbot.com/improving-rails-boot-time-with-zeus">improve boot time</a> for console, rspec, etc.</li><li>bundler gem</li><li>rspec gem (testing framework)</li><li><a href="https://semaphoreapp.com/">Semaphore</a> (continuous integration): runs your specs so you don't have to.</li><li><a href="https://codeclimate.com">Code Climate</a> (automated code reviews): alerts you of problems as you push new code</li><li>Trello</li><li><a href="https://plug.dj">plug.dj</a> (turntable.fm replacement): Set it and forget it user-curated radio</li></ul>]]></description><dc:creator>andrew@idealprojectgroup.com (Ideal Project Group, LLC)</dc:creator></item><item><title>The mind as a lever</title><category>Business</category><pubDate>Fri, 19 Dec 2014 21:39:09 +0000</pubDate><link>https://www.projectidealism.com/posts/2014/12/19/the-mind-as-a-lever</link><guid isPermaLink="false">50d01cefe4b000726e548760:51ab864fe4b0db4a25537edb:54949aefe4b0446312e96d4e</guid><description><![CDATA[<p>I was having to talk with a good friend of mine last night about business, the things we work on and when we work on them.</p><p>We started on the topic because he was explaining how he's been waking up early lately, and as a result it's easier for him to work on the things he thinks are the most important, and that they get his freshest mind with less interruption.</p><p>Beyond this,&nbsp;what we started realizing, and&nbsp;we we were using&nbsp;<a href="http://tuasoftware.com/">Tula</a>&nbsp;and&nbsp;it's&nbsp;growth as&nbsp;an example,&nbsp;is that in order to accomplish something important and significant,&nbsp;you do need to believe that you can do it. But our minds&nbsp;require ourselves to provide a certain amount of evidence that something can be achieved before we can truly believe that some other step can be achieved.</p><p>This&nbsp;was a fascinating conversation to me because the implication is that if&nbsp;you can truly believe something is possible,&nbsp;then you are probably more able to achieve those things. Then, once you are able to achieve an&nbsp;initial set of 'things',&nbsp;the sooner that you can believe greatness is possible, which in turn makes it more &nbsp;likely that greatness happens. This process&nbsp;creates&nbsp;a positive&nbsp;feedback loop because as you start seeing more evidence to the potential greatness, it&nbsp;in turn makes the realization of said greatness more likely.</p><p>But there were&nbsp;two things that kept running through my head that I'm still thinking about about and somewhat&nbsp;troubled by. The first is thinking about the mind as a sort of lever,&nbsp;and that there is a certain amount of training we can do to our brains. In the same way that you can change the fulcrum on a diving board to get a different spring, so too can our thoughts can have an impact on what we are able to achieve.</p><p>But just like you can move&nbsp;the fulcrum&nbsp;on a diving&nbsp;board so much that you actually miss the bounce, we can also be&nbsp;delusional.&nbsp;The problem is&nbsp;that it's not so&nbsp;easy to differentiate between big ambitions and delusions of grandeur, especially when it's all happening in our own brains.</p><p>So it seems to me if the mind is a lever, the most important thing we can do is figure out where to place the fulcrum.</p>]]></description><dc:creator>andrew@idealprojectgroup.com (Ideal Project Group, LLC)</dc:creator></item><item><title>Podcast Episode 18: Regularly Scheduled Momentum</title><category>Podcast</category><pubDate>Wed, 05 Nov 2014 06:47:44 +0000</pubDate><link>https://www.projectidealism.com/posts/2014/11/5/podcast-episode-18-regularly-scheduled-momentum</link><guid isPermaLink="false">50d01cefe4b000726e548760:51ab864fe4b0db4a25537edb:5459c49de4b067efa38e61ba</guid><description><![CDATA[<p>In our newest episode of the podcast I'm joined by <a href="http://natekontny.com">Nate Kontny</a>, the new CEO of Highrise. Nate and I talk about business, software, writing and a host of other topics including the future of <a href="http://highrisehq.com">Highrise</a>.</p><p>Nate's a very talented software developer, a superb writer, has founded multiple companies, worked on the Obama for America campaign and is now running the newest company to spin out of <a href="http://basecamp.com">Basecamp</a>. It's interesting to hear Nate's story, how dots connect and how he's ultimately found himself in a situation he had in some ways been setting an intention towards.</p><p>Thanks to Nate for joining me again, and as always you can listen to the show below, or <a target="_blank" href="https://itunes.apple.com/us/podcast/project-idealism/id346503002?mt=2">by subscribing in iTunes</a>.</p>
























  
    <iframe scrolling="no" seamless src="https://simplecast.fm/e/5442?style=light" width="100%" frameborder="0" height="36px"></iframe>
  




  <p>Show notes:</p><ul dir="ltr"><li><a href="https://signalvnoise.com/posts/3770-big-news-for-highrise">Big news for Highrise</a></li><li><a href="http://ninjasandrobots.com/a-new-high">A New High</a></li></ul>]]></description><dc:creator>andrew@idealprojectgroup.com (Ideal Project Group, LLC)</dc:creator></item><item><title>Engineering is the easy part except when it's not</title><category>Engineering</category><pubDate>Mon, 15 Sep 2014 21:48:00 +0000</pubDate><link>https://www.projectidealism.com/posts/2014/9/4/engineering-is-the-easy-part-except-when-its-not</link><guid isPermaLink="false">50d01cefe4b000726e548760:51ab864fe4b0db4a25537edb:5408b897e4b04e723752195a</guid><description><![CDATA[<p>I've been hearing it a lot lately. Maybe you've been hearing it, too. "Engineering is the easy part," they say.</p><p>Try telling that to Twitter in early 2007 when they faced massive growth and <a href="http://www.slideshare.net/Blaine/scaling-twitter">intense scaling issues</a>. I don't think you'd find many engineers at Twitter telling you how easy it is to manage 600 requests per second and 180 Rails instances backed by 1 database server.</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1410217403364-6L2ZE6CKAJRJU4JTDRIY/image-asset.jpeg" data-image-dimensions="640x428" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1410217403364-6L2ZE6CKAJRJU4JTDRIY/image-asset.jpeg?format=1000w" width="640" height="428" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1410217403364-6L2ZE6CKAJRJU4JTDRIY/image-asset.jpeg?format=100w 100w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1410217403364-6L2ZE6CKAJRJU4JTDRIY/image-asset.jpeg?format=300w 300w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1410217403364-6L2ZE6CKAJRJU4JTDRIY/image-asset.jpeg?format=500w 500w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1410217403364-6L2ZE6CKAJRJU4JTDRIY/image-asset.jpeg?format=750w 750w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1410217403364-6L2ZE6CKAJRJU4JTDRIY/image-asset.jpeg?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1410217403364-6L2ZE6CKAJRJU4JTDRIY/image-asset.jpeg?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1410217403364-6L2ZE6CKAJRJU4JTDRIY/image-asset.jpeg?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p>The point is: engineering is hard. <a href="http://projectidealism.com/posts/2014/6/4/everything-is-hard">Everything is hard</a>.</p><p>Ok, maybe I'm exaggerating a bit here. There is one case where "engineering is the easy part."</p><p>Let's say you have an idea. You want to build that idea into a weekend project. You've probably heard of this happening quite a bit. How many "I built this in a weekend while watching every episode of House of Cards" blog posts have you read over the years? Building a project in a weekend is easy. You shouldn't be focused on perfection. Most everything works the way it should, but it definitely isn't refined. If you overcome your lizard brain, you can ship it and see what people think.</p><p>Let's say a few people like what you've built. You have users! They start using the app as any good user should do. Guess what? They find bugs. Now, you've got to fix them (if you want your users to continue liking what you've built). Better yet, it's not just one bug. This bug, that bug. You have to prioritize bugs. You can't fix them all at once - even if each user cares passionately about the bug they reported.</p><p>Still easy?</p><p>BUT! Remember, you took some shortcuts so you can finish your project in a weekend? You have a choice to make. You can put a band-aid on it and simply patch it up, or you can do some refactoring for the future to make sure it doesn't happen again. You might even want to write a test for it - you know, because <a href="http://projectidealism.com/posts/2014/1/28/the-right-way-to-think-about-tdd">TDD 4 lyfe.</a></p><p>Now you've fixed those bugs and your users are happy again. Slowly, they're telling their friends and you start to get some SEO juice with Google. But, guess what? You're not done yet. These new users want new features. Surprise, surprise - your weekend project can't do everything a user might want. Better yet, you're in the same situation as the bugs. Just like all the bugs, every user has a feature they need.</p><p>You have another engineering decision to make. How does this new feature integrate into the code you've already written? You'll need to plan for the future. There will always be new features. You don't want to screw yourself over in six months. Granted, some features are pretty easy and you've done them before, but there's always a slight variation. There might even be a library out there to help you, but once again, you'll likely have to alter its behavior - even if it's just a little bit.</p><p>Still easy?</p><p>Your weekend project is starting to turn into an actual product. You have a faithful group of early adopters. They're always looking out for you and sharing what they're thinking. You've been able to keep them happy through bug fixes and new features. You still have bugs and you have a giant backlog of new features; however, you've been able to navigate successfully until this point. Your app is still fast, but not quite as fast as when you first started. Your app works - there are some bugs, but for the most part people can use your app with success.&nbsp;For the most part, people are happy.</p><p>You're starting to grow faster now. People are paying attention. Remember Twitter? You might start feeling their pain. Not many apps have massive scaling pains like Twitter, but most apps go through periods where you have to adjust. Your weekend project was built and tested with one user, you. Now, you might have hundreds, maybe thousands, of people using your app on a daily basis. This is entirely different than one user. New problems will popup because your app is serving more than just one user.</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1410817517303-6YO1P30VN6755J2T11OB/image-asset.jpeg" data-image-dimensions="435x465" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1410817517303-6YO1P30VN6755J2T11OB/image-asset.jpeg?format=1000w" width="435" height="465" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1410817517303-6YO1P30VN6755J2T11OB/image-asset.jpeg?format=100w 100w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1410817517303-6YO1P30VN6755J2T11OB/image-asset.jpeg?format=300w 300w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1410817517303-6YO1P30VN6755J2T11OB/image-asset.jpeg?format=500w 500w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1410817517303-6YO1P30VN6755J2T11OB/image-asset.jpeg?format=750w 750w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1410817517303-6YO1P30VN6755J2T11OB/image-asset.jpeg?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1410817517303-6YO1P30VN6755J2T11OB/image-asset.jpeg?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/50d01cefe4b000726e548760/1410817517303-6YO1P30VN6755J2T11OB/image-asset.jpeg?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
          
          <figcaption class="image-caption-wrapper">
            <p>Source:&nbsp;<a href="http://i.imgur.com/te0y7.jpg">http://i.imgur.com/te0y7.jpg</a></p>
          </figcaption>
        
      
        </figure>
      

    
  


  





  <p>These are great problems to have, but they definitely aren't easy.</p><p><strong>Engineering is the easy part only applies to companies that stop at Version 1.0.</strong> How many companies do you know that stop there? None. The engineering team gets you to Version 20.0. Through bug fixes, new features, scaling, migrations, architecture, data centers, etc., your engineering team is there every step of the way.</p><p>It took Twitter months of hard work to straighten out their scaling issues. It most certainly wasn't easy. They failed - quite a bit, but they didn't give up. Through months of pain, they eventually came up with solution after to solution to fix the fail whale. Their solutions were most definitely not easy. Keep in mind - they did all of this while people were still using Twitter. Downtime is just unacceptable in this day and age.</p><p>On the flip side, I had the opportunity to observe what happens when you have an engineering team that runs into major problems when upgrading a product. Now, I'm positive this team had the best of intentions and I'm positive they were trying as hard as they could to avoid these issues. I'm also positive they'll learn from these mistakes. However, they failed massively, and they know it.</p><p>Engineers are responsible for many different things. If you don't do one of those things right, it can snowball into other problems.</p><p>Communication is key. As an engineer, writing code is a small part of the job. In practice, most engineers write code for a fraction of their day. Instead of writing code, they're communicating with project managers to estimate time to production. They're talking with the designer about ways to work a new design into the existing product. They're thinking about what's next and how they'll manage the next database update required for that upcoming feature in three months. They're worrying about how their code base isn't as stable and well-tested as they had hoped for.</p><p>Most importantly, all of this isn't easy - not by a long shot. This is hard stuff. Don't buy into the link-bait. Engineering is not easy. Just like customer support, project management, and product ownership - engineering is a key part of your organization. If you think you can just throw bodies at an engineering problem, you're wrong.</p><p>Those bodies might be able to solve the problem at hand. They might get you somewhere and help you raise funding. However, those bodies certainly aren't worried too much about the future. They aren't setting you up for long-term success. You'll pay dearly for it later on.</p><p>Engineering isn't easy if you're doing it right. Engineering should be invested for the long-term. When you finally get there, you'll have an engineering team fully invested in your organization. Your engineering team will be a valuable asset full of talented people that know every tool, piece of software, and server your company has in its possession.</p><p>Don't say engineering is the easy part. It's not.</p><p><em>Thanks to <a href="http://andrewwicklandr">@andrewwicklandr</a> and <a href="https://twitter.com/alexlaprade">@alexlaprade</a> for reviewing this and providing some ideas for making it better.</em></p>]]></description><dc:creator>andrew@idealprojectgroup.com (Ideal Project Group, LLC)</dc:creator></item><item><title>Minimizing distractions: No phone during the work day.</title><pubDate>Wed, 10 Sep 2014 16:34:40 +0000</pubDate><link>https://www.projectidealism.com/posts/2014/9/10/minimizing-distractions-no-phone-during-the-work-day</link><guid isPermaLink="false">50d01cefe4b000726e548760:51ab864fe4b0db4a25537edb:54106195e4b0da480523f594</guid><description><![CDATA[<p>I've decided to try something new. After reading <a href="http://www.amazon.com/In-Real-Life-Identity-Digital/dp/1455584290">In Real Life</a> by Nev Schulman, the host of Catfish on MTV, I've been inspired.</p><p>It's time to kill my phone.</p><p>Not forever, but just enough to reduce daily distractions. I started today. My phone is far out of reach - in another room - so I'm not tempted by anything. It's no longer begging for my attention. I even went so far as to uninstall all social media apps and disconnect my email accounts.</p><p><a href="https://medium.com/@jakek/the-distraction-free-iphone-or-why-im-happier-since-i-disabled-safari-80f8d525b0d8">Here's someone else who has tried the distraction free phone with great success.</a>&nbsp;Jake, the author of that post, was also an inspiration for me to try this.</p><p>Instead of picking up my phone whenever I have a spare minute or being intrigued by a notification, I hope to stare at the wall. I hope to stand up and stretch more often. I'll be able to think and reflect instead of reading something I saw on Twitter, browsing Reddit, or scouring Hacker News.</p><p>It's the equivalent of distraction <a href="http://sethgodin.typepad.com/seths_blog/2005/03/dont_shave_that.html">yak shaving</a>.</p><p>My phone constantly tempts me. There's not a moment that goes by without some type of notification. It might be an email, an app telling me to do something, or a calendar notification. There is always another inbox to check.</p><p>So, I've asked myself, why do I need my phone during the day? I never talk on it. Hopefully, by doing this, I'll better schedule my time with friends and family. I won't be responding to texts during the day. I won't be planning my evenings during the day. Instead, I'll have to improve my actual meaningful communication.</p><p>I want to try this out for two weeks and see what happens. Stay tuned for a follow-up.</p>]]></description><dc:creator>andrew@idealprojectgroup.com (Ideal Project Group, LLC)</dc:creator></item><item><title>A new definition for SaaS</title><category>Business</category><pubDate>Thu, 07 Aug 2014 07:05:31 +0000</pubDate><link>https://www.projectidealism.com/posts/2014/8/7/a-new-definition-for-saas</link><guid isPermaLink="false">50d01cefe4b000726e548760:51ab864fe4b0db4a25537edb:53e321e5e4b090352c2ca485</guid><description><![CDATA[<p>The Software as a Service model, in large part because of it's name, has incorrectly led a lot of people to believe there's a fantasy universe that exists where they can light up some code, sit back, and collect some of that elusive passive income.</p><p>It's a ridiculous notion that needs to be shot in the face.</p><p>I know people questioning promising businesses because they're worried about the fact that there are humans involved with the running of the business. It's becoming an epidemic in the software industry that people think the goal is to reach some finish line where they can sit back and collect cash and have nothing running their company but a few servers.</p><p>It's insanity.</p><p>Moving forward, to me, my company and anyone that works with us, SaaS stands for Software and amazing Service. They cannot and they should not be separated.</p><p>Amazing service is server uptime. It's rapid fixes to bugs. It's responding to customer requests quickly. It's building new features that you know your customers want, it's experimenting, it's trying things, breaking things and trying again.&nbsp;</p><p>Too many people in our industry have built once solid products that have become stale (not simple, stale) and have not advanced with the web in the way they should have. The worst culprits are bootstrappers who got a taste of victory and instead of working their asses off while they were gaining momentum had the delusional thought that they could sit back and collect monthly payments forever.</p><p>And then they learned about a thing called churn.</p><p>If you're not willing to get into the services business, don't bother getting in the software business.</p><p>The SaaS model only works for companies that understand that the software can only provide so much service.</p><p> </p>]]></description><dc:creator>andrew@idealprojectgroup.com (Ideal Project Group, LLC)</dc:creator></item></channel></rss>