Blog

Learn | Document | Teach
  1. Best of Beats 1 Week 1

    Tuesday | July 07 2015 | 09:41 AM

    Apple Music has now been available for one week and Beats 1 has 168 hours of content under its belt. Apple Music definitely isn’t perfect, but it’s solving my problem of having to switch between various music applications to play certain songs. Beats 1 is also proving to be very helpful because it gives me something to listen to when I’m sick of all my music.

    Since starting to listen to Beats 1, I’ve added to my music library quite a bit. I’ve also started getting into something I said I would get back into with Spotify and never did. Somewhere along the timeline of my life where CDs were the mainstream medium and CD burners existed, playlists were an integral part of my life. I was making a new one at least every week for new music in the car. Once my iPod/iPhone started to take over that area, I switched to relying on a smart playlist sorted by date added. When I made the switch to Spotify, I was really only doing it for music I didn’t. Most of my playlists were just albums I wanted to listen to.

    This is my first shared playlist, inspired by the first week of Beats 1. The playlist is divided into three sections. The first half is music that was played that I would consider more edgy in terms of radio, the second half is mainstream music that I like that they played, and the middle is kind of a combination of those two categories plus some older music. Feel free to check it out below and remember that the link will open iTunes/Music.

    Best of Beats 1 Week 1 Playlist

    If you like what Beats 1 plays, but can’t listen to it often, an Australian developer named Callum Jones created the handle @Beats1Plays where every track played gets tweeted out. If you don’t want to take the time to scour through that list of tweets, you can also check out the radio DJ’s connect pages. I’ve linked to the main three below, but you can check out beats1radio.com to find out who’s currently on deck.

    Zane Lowe
    Ebro on Beats 1
    Julie Adenuga on Beats 1

    Unfortunately, a global radio station also runs into issues of licensing. There were two songs that I actually had at the forefront of my playlist, but they were unavailable to stream. I’ve seen numerous articles mention that unavailable songs would appear grayed out for users, but I’m guessing this is only if something is available on Apple Music for one country, but not another. So, I’ve gone ahead and included SoundCloud links to those songs below so you can still check them out.

    House Every Weekend (Original Mix) - David Zowie
    King - Years & Years

    Happy listening!

  2. What WordPress Taught Me About Jekyll

    Invalid DateTime

    When I first decided to put add a blog to my website, I ran straight to WordPress.org and jumped through all the necessary hoops I needed to get it up and running. WordPress is an amazing tool, but my needs were much too simplistic. Soon I started thinking that the full-featured tool was actually getting in the way of me putting out content.

    Eventually (I think via Hacker News) I stumbled across Jekyll. I started configuring my development environment, configuring my domain, and redesigning my website to my liking. Blog posts came out pretty steadily and easily at first while I was adding features and making changes to my website, but eventually I ran out of content.

    Recently, I’ve been doing some WordPress work and it inspired me to take on a WordPress project of my own, but this time around I really wanted to get it right. My first stop (after having been there for the original work multiple times) was the WordPress Codex.

    I’ve always thought that the first post in a blog is awkward (I even mention how difficult it is to get started in that linked post). I think that most of this difficulty and awkwardness came about because I didn’t really do any planning at the beginning. Since this is a personal site, I thought I would just post about whatever I felt like. You can do that, but it can be really overwhelming to come up with content when you don’t have any focus.

    The WordPress Codex has an entry called, “First Steps With WordPress” and it has a section called, “Planning Session” that walks you through six important questions to help you frame your blog a bit more. I’ll post the questions here, but I definitely recommend clicking through for the rest of the planning exercise.

    1. What am I going to do with this?
    2. Who is going to read this?
    3. What kinds of information will I be posting?
    4. Why am I doing this?
    5. Who am I doing this for?
    6. How often am I going to be posting and adding information?

    I’d also write everything out on paper like they suggest. I kept crossing things out or going back to reword bullet points as I went along. I’m hoping that this planning can get me back on track with regular posting now that I have a much clearer idea of what I would like to write about.

    It’s funny how we always end up coming full circle, even in technology.

  3. Post Read Times and Jekyll

    Invalid DateTime

    It’s safe to say that the folks at Medium have done a superb job designing their platform and many people across the Internet are looking to borrow bits and pieces of their look. Aside from the Parallax-esque effect on their hero image, the other small detail that caught my attention was their reading length estimates on every article. In the future it could make way for a feature where you put in how much time you have and they’ll curate a single article or a list of articles worth reading in that timeframe.

    Thinking about the implementation, it didn’t seem terribly difficult to get a rough estimation based on the number of words in a post and the average number of words per minute a person can read.

    The solution I came up with runs on an entire page when called. It looks for elements where class="post". It then looks for an element inside of that one where class="post-content". After computing a reading estimation on the content it then looks for an element inside the post element where class="post-length". I purposely set it up this way so that I could execute the same script on both my blog’s index pages and any individual pages.

    Example HTML:

    <div class="post">
        <h3>Post's Title</h3>
        <div class="post-length">
            By YOUR-NAME-HERE
        </div>
        <div class="post-content">
            Write your blog post here...
        </div>
    </div>
    

    I chose not to execute this function until after the page has loaded because I wanted the page to load faster rather than display the reading time sooner, so as a placeholder I just author the article to myself in the post-length section. This also works well as a fallback if the user has opted to disable JavaScript.

    footer.html

    {% if page.active == 'blog' %}
        <script src="/js/reading-time.js"></script>
    {% endif %}
    

    Because I use Jekyll I setup a variable that I could set for anything that is a blog post or a series of blog posts (I didn’t want this function attempting to execute on every page). If you’d like understand how it’s setup check out the source code for this site.

    reading-time.js

    function writeReadingTime() {
        var wordsPerMinute = 180;
    
        var posts = document.getElementsByClassName('post');
        for(var i = 0; i < posts.length; i++) {
            var postContent = posts[i].getElementsByClassName('post-content')[0].innerHTML;
    
            // Remove HTML tags from post to an appropriate reading time
            var noHTML = postContent.replace(/(<([^>]+)>)/ig,"");
            var numberOfWords = noHTML.split(" ").length;
            var timeInMinutes = numberOfWords / wordsPerMinute;
            timeInMinutes = Math.ceil(timeInMinutes);
    
            if(timeInMinutes == 1)
                posts[i].getElementsByClassName('post-length')[0].innerHTML = '<i class="fa fa-clock-o"></i> 1 minute in length';
            else
                posts[i].getElementsByClassName('post-length')[0].innerHTML = '<i class="fa fa-clock-o"></i> ' + timeInMinutes + ' minutes in length';
        }
    }
    

    For this page’s icon set I went with Font Awesome. If you’re using something different just correct lines 15 and 17 in the above function to what you need them to be.

    Criticisms

    If I were to improve upon this initial implementation I would refine the estimation algorithm. Using jQuery it looks like I could efficiently remove the <code> snippets so that they weren’t factoring into the reading time as someone will take longer reading through code snippets. Also, I’d probably abandon JavaScript all together for this and find a way to write it up with Liquid so that it wouldn’t have to be computed by the user’s device.

    Hopefully this article took you exactly 4 minutes to read.

  4. GitHub's Atom.io Impression

    Invalid DateTime

    This week’s post is on Atom [Editor]. I thought it would be appropriate because it is now open source. Atom is marketed as, “the text editor that the folks at GitHub have always wanted” and now it’s slowly making it’s way into my everyday work.

    I spend a large majority of my day in Spring Tool Suite so I don’t feel like I’m able to leverage Atom as well as I would like to, but it’s been my go to for working on this site, my daily-programmer project, as well as at a Faux Game Jam I participated in with my friends two months ago.

    Benefits

    • Git integration color codes files in the tree view and the number of changed lines in the status bar at the bottom.
    • The editor is so modular that it can be built to be exactly what you need if you have the time to do so (The defaults are also pretty great, I’ve only changed a couple settings).

    What’s Missing

    • I need to find an xmllint package as that’s the one thing I do use a text editor for regularly and I’d prefer to only have to keep one text editor in my dock. [Coming Soon]
    • Stability, particularly around editing single text files as it will sometimes try to make a directory like ~/Desktop into a project folder and try to remember what files you had open and how the window was configured last time you had that “project” open.
    • Cross compatibility. Although this isn’t an issue for me, Atom is currently only for OS X. However, the open source page mentions Linux and Windows coming in time.

    Quick Tips

    • cmd-shift-p - Toggle Command Pallet

      • Every command can be found by using this text field.
    • cmd-p - Open files

      • Open a file in the project without using the mouse.
    • ctrl-shift-m - Toggle Markdown Preview

      • Very useful, but Atom renders some markdown different from Jekyll’s interpreter so you’ll still want to carefully skim the page in your browser.
    • cmd-\ - Toggle Tree View

      • Saves screen real estate or easily provides you a great way to glance at your entire project.
    • cmd-] - Indent

      • If you select multiple lines this will indent the block
    • cmd-[ - Outdent

      • If you select multiple lines this will outdent the block
    • cmd-l - Select entire line
    • no default mapping - Toggle Soft Wrap

      • Necessary for markdown files for me.
      • Only available via the command pallet when the editing window has focus.
    • cmd-space - Autocomplete

    If I missed anything that should be noted feel free to let me know.

  5. Form Validation and Email

    Invalid DateTime

    When I first started working through this iteration of my website I didn’t want my email address plastered on every page in the footer like it had been in the past. I believe doing that is what caused all the spam email being sent to my school email address. However, I guess I liked working with input forms so much that I decided to add a contact form.

    I knew I wanted a typical contact form, but without any dynamic content I couldn’t process the form directly on this domain. Luckily my search brought me to Jekyll’s Resources page where I saw “Use Simple Form to integrate a simple contact form”.

    Simple Form integrates well with Akismet for spam prevention, but I haven’t opted to go that route (maybe in the future if the form gets abused). Due to this, I wanted my form validation to be thorough (catch possible abuse), but also offer a pleasing user experience (no captchas).

    I settled on two types of validation. The first one occurs when a form element loses focus (onblur) and just does some basic checks to determine if there is content in the field or not. The exception to this is email in which a regex /^[\w._-]+[+]?[\w._-]+@[\w.-]+\.[a-zA-Z]{2,6}$/ is used to do the validation. After the value is checked I give the user some feedback by utilizing Bootstrap validation states.

    The second validation occurs when the user presses submit and if everything looks good it will create a another form that is hidden and contains the Simple Form action and submit it. If there are errors (red fields), nothing will happen and it’s up to the user to fix them. If the message is short (yellow field) the form will display an alert to the user that their message looks a little short, but if submit is pressed a second time the form will go through.

    HTML

    This form requires Bootstrap and Font Awesome to display correctly.

        <form class="form-horizontal" action="javascript:validateForm()" method="post">
            <div id="name-group" class="form-group">
                <div class="col-xs-10 col-xs-offset-1 input-group">
                    <span class="input-group-addon"><i class="fa fa-user"></i></span>
                    <input type="text" class="form-control" id="name" placeholder="Name" onblur="javascript:validateInline(this.id, this.value)">
                </div>
            </div>
            <div id="email-group" class="form-group">
                <div class="col-xs-10 col-xs-offset-1 input-group">
                    <span class="input-group-addon"><i class="fa fa-envelope"></i></span>
                    <input type="email" class="form-control" id="email" placeholder="Email" onblur="javascript:validateInline(this.id, this.value)">
                </div>
            </div>
            <div id="subject-group" class="form-group">
                <div class="col-xs-10 col-xs-offset-1 input-group">
                    <span class="input-group-addon"><i class="fa fa-comment"></i></span>
                    <input type="text" class="form-control" id="subject" placeholder="Subject" onblur="javascript:validateInline(this.id, this.value)">
                </div>
            </div>
            <div id="message-group" class="form-group">
                <div class="col-xs-10 col-xs-offset-1 input-group">
                    <span class="input-group-addon"><i class="fa fa-quote-left"></i></span>
                    <textarea class="form-control" id="message" rows="5" placeholder="Message" onblur="javascript:validateInline(this.id, this.value)"></textarea>
                </div>
            </div>
            <div hidden class="form-group" id="short-message-group">
                <div class="col-xs-10 col-xs-offset-1 alert alert-warning alert-dismissable">
                    <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
                    Your message looks a little short. Press submit again if you'd like to send it anyways.
                </div>
            </div>
            <div class="form-group">
                <div class="col-xs-offset-1">
                    <button type="submit" class="btn btn-default">Submit</button>
                </div>
            </div>
        </form>
    

    JS

    As a note, document.getElementById("").classList doesn’t work in IE prior to version 10.

        function validateInline(id, input) {
            if(id == "name" || id == "subject" || id == "message")
                if(input.trim().length > 0) {
                    if(id == "message" && input.length < 30) {
                        document.getElementById(id + "-group").classList.remove("has-error");
                        document.getElementById(id + "-group").classList.remove("has-success");
                        document.getElementById(id + "-group").classList.add("has-warning");
                    } else {
                        document.getElementById(id + "-group").classList.remove("has-error");
                        document.getElementById(id + "-group").classList.remove("has-warning");
                        document.getElementById(id + "-group").classList.add("has-success");
                    }
                } else {
                    document.getElementById(id + "-group").classList.remove("has-success");
                    document.getElementById(id + "-group").classList.remove("has-warning");
                    document.getElementById(id + "-group").classList.add("has-error");
                }
    
            if(id == "email") {
                emailValidator = /^[\w._-]+[+]?[\w._-]+@[\w.-]+\.[a-zA-Z]{2,6}$/;
                if(input.length > 0 && input.match(emailValidator)) {
                    document.getElementById("email-group").classList.remove("has-error");
                    document.getElementById("email-group").classList.add("has-success");
                } else {
                    document.getElementById("email-group").classList.remove("has-success");
                    document.getElementById("email-group").classList.add("has-error");
                }
            }
        }
    
        function validateForm() {
            valid = true;
    
            var name = document.getElementById("name").value;
            var email = document.getElementById("email").value;
            var subject = document.getElementById("subject").value;
            var message = document.getElementById("message").value;
    
            if(name.trim().length == 0 || subject.trim().length == 0 || message.trim().length == 0)
                valid = false;
    
            if(email.length > 0) {
                emailValidator = /^[\w._-]+[+]?[\w._-]+@[\w.-]+\.[a-zA-Z]{2,6}$/;
                if(!email.match(emailValidator))
                    valid = false;
            } else {
                valid = false;
            }
    
            if(valid && message.length < 30 && document.getElementById("short-message-group").hidden)
                document.getElementById("short-message-group").hidden = false;
            else if(valid) {
                document.body.innerHTML += '<form id="simpleForm" action="http://getsimpleform.com/messages?form_api_token=SIMPLE_FORM_PUBLIC_API_TOKEN" method="post">' +
                                                '<input type="hidden" name="Name" value="'+name+'">' +
                                                '<input type="hidden" name="Email" value="'+email+'">' +
                                                '<input type="hidden" name="Subject" value="'+subject+'">' +
                                                '<input type="hidden" name="Message" value="'+message+'">' +
                                            '</form>';
                document.getElementById("simpleForm").submit();
            }
        }
    

    Criticisms

    If I were to iterate on this implementation I’d probably write more advanced validation checks in JavaScript and use jQuery for the real form submission. I’d also write in a workaround for the IE compatibility issue.

    If you’d like to see it in action you can check it out on my contact page and if you have any suggestions on how to make it better or any other comments feel free to press that submit button!

  6. Implementing a Search Bar without PHP

    Invalid DateTime

    My current website implementation has been more encouraging to me than any past iteration. However, that being said, this is a blog and what good is a blog without search? Typically this can be overcome in a multitude of ways, but without any dynamic pages (not allowed by GitHub Pages), your options become rather limited.

    I chose to rely on one of my favorite Google Search tricks to accomplish this.

    site:michaeljdeeb.com

    Typing site:michaeljdeeb.com search into Google will return all pages from my domain that contain the word “search” on them. Using this knowledge you can rig up a <form> that will search your website for the keywords a user enters into the search bar.

    HTML:

        <form class="navbar-form navbar-right" action="https://google.com/search" method="get" role="search">
            <div class="form-group">
                <input type="hidden" name="q" value="site:example.com">
                <input type="search" name="q" class="form-control" placeholder="Search">
            </div>
                <button type="submit" class="btn btn-default hidden-xs"><i class="fa fa-search"></i></button>
        </form>
    

    Placing the snippet above in your navbar and swapping out example.com for your domain will add this Google search functionality to your GitHub Pages site.

    CSS:

    On my site, I utilize a navbar fixed to the top so that when you scroll it scrolls with you. The navbar is also responsive so it looks different on extra-small devices than it does on desktops and tablets. On OS X with Safari 7.0.3 I noticed that when the <input> received focus the rest of my links font-weight changed and they got less bold (thinner).

    This is a known issue and is caused by “Use LCD font smoothing when available” being checked under System Preferences > General. The following rule fixes this issue without having to tell users to disable LCD font smoothing.

    bootstrap.css

        .navbar-fixed-top,
        .navbar-fixed-bottom {
          -webkit-font-smoothing: subpixel-antialiased;
        }
    

    This rule below corrects some oddities that come with having a search bar in a responsive navbar. These include spacing issues between the search bar and the rest of your links and the border around the search bar.

    custom.css

        .navbar .navbar-form{
            padding: 0 15px;
            border: 0;
            -webkit-box-shadow: none;
            box-shadow: none;
        }
    

    I don’t foresee any major issues with this search solution, but if you do be sure to let me know. The worst I can think is that Google Analytics keywords reports will be skewed.

    Happy 🔎ing!

  7. Excluding Yourself from Google Analytics

    Invalid DateTime

    Although it may feel like an invasion of privacy from the consumer side, analytics are really fun and exciting to see when you’re the webmaster. However, nothing is more depressing than getting excited at a jump in your visitor count only to remember you were the visitor(s).

    I tried avoiding my production site altogether because I can spin up a local copy with ease, but as I push things to GitHub I get nervous that they aren’t taking affect or are causing the site to break (“It worked on my machine”), requiring me to still occasionally visit my site. I finally decided to take the time to solve this problem and hopefully this post is of some help to you.

    Possible Exclusion Methods

    • Opt-out Browser Add-on
    • Exclude via ISP/IP
    • Opt-out via cookies

    *As a note, use universal analytics (analytics.js) (asynchronous). Method three in the list above will be specific to that.

    Opt-out Browser Add-on

    Google has created the Google Analytics Opt-out Browser Add-on to do just what the name says. This is the easiest and quickest way to start blocking your views and the add-on is available for all modern desktop browsers, not just Chrome.

    That said, I had two caveats with this method. The biggest issue with the add-on is that I wanted to be able to do native mobile device testing and add-ons like this aren’t available for mobile (at least on iOS). Also, the add-on will exclude you from all Google Analytics and since I use analytics on my website I don’t think it’s fair to opt-out of other people’s.

    Exclude via ISP/IP

    Log in to Google Analytics and click on the “Admin” tab. Select your account from the dropdown and then click “All Filters”. Make sure “Exclude” is selected from the dropdown and then decide how you’d like to filter (On a Mac, you can type cat /etc/resolv.conf into Terminal to see your ISP domain).

    This method wasn’t ideal for me either because I wanted to be able to work on the site from anywhere and not have to think about where I can and can’t view my production website without skewing analytical data. Also, like most people, I don’t have a static public IP address so I would have to switch the numbers out regularly or use my ISP’s domain which might filter out visits from my neighbors (could be a big deal if you’re in a well populated area).

    Opt-out via cookies

    I settled for creating a cookie to opt-out of tracking because they work on desktops and mobile devices and won’t require much maintenance long-term. Google has great documentation on how to implement this on their advanced configurations for Google Analytics webpage.

    Since my site is relatively static (not passing multiple arguments via URL) I used some pretty basic JavaScript to detect if the argument was passed and create a cookie to opt-out if that’s the case.

        // Place me in a <script> tag above your Google Analytics tracking code
        if (location.search) {
            // Set to the same value as the web property used on the site
            var gaProperty = 'UA-XXXX-Y';
    
            // Since location.search == true, grab the parameter
            // TODO - Handle URL arguments better if your site utilizes them
            var param = location.search.split("param=")[1];
    
            // Verify the url is like http://example.com?param=true
            // and then create the opt-out cookie
            var disableStr = 'ga-disable-' + gaProperty;
            if (param) {
                document.cookie = disableStr + "=true; expires=Thu, 31 Dec 2099 23:59:59 UTC; path=/";
                window[disableStr] = true
            }
        }
    
        // Disable tracking if the opt-out cookie exists
        if (document.cookie.indexOf(disableStr + "=true") > -1) {
            window[disableStr] = true
        }
    

    By changing UA-XXXX-Y to your Google Analytics ID and then placing the code above before any Google Analytics tracking code in your site will allow you to hit any page containing the code and append ?param=true to the URL to create an opt-out cookie which will not count your current visit or any future visits.

    Important Things to Note

    • A cookie will need to be created per browser
    • A new cookie will need to be created per device
    • A new cookie will need to be created if you clear your cookies
    • YMMV when using a browser’s private mode

    If you’re using the classic version of Google Analytics (ga.js), you might have some luck implementing something similar by looking at this Google Groups topic.

    Good luck and thanks for the page view(s)!

  8. Using a Custom Domain with GitHub Pages

    Invalid DateTime

    Update [05/13/2014]: Using this method may cause slow load times

    As you may have noticed, as of last week this site uses a custom domain, but the content is being stored by GitHub. I seem to be playing around with my domains and where they point to a lot and I also always forget how to configure my domain when I actually need to change it. This post is for both you and my future self.

    Resources You’ve Probably Already Found

    This post is going to demonstrate how I got michaeljdeeb.com and www.michaeljdeeb.com to point to my personal GitHub Pages site and also the required settings to forward michaeldeeb.com to my new site as well.

    On the GitHub Pages Side

    You’re going to want to create a file named CNAME at the root of the project and inside that file you’re going to put your bare domain. In my case it was michaeljdeeb.com not http://michaeljdeeb.com

    On the Domain Side

    As a personal sidenote, I use Hover (referral link) for my domains.

    Relevant for Hover users: How to: Edit DNS records - A, CNAME, MX, TXT, and SRV : Hover Help Center

    michaeljdeeb.com (@)

    First, delete any A, AAAA, or CNAME records that use @ for the hostname. Then, create two A records. The hostname for both of them is @ which refers to your top-level (apex) domain. The values at the time of writing are 192.30.252.153 and 192.30.252.154, but I’d check the ”My custom domain isn’t working | GitHub Help” page to verify that the IP addresses haven’t changed.

    www.michaeljdeeb.com (www)

    Next, I created a CNAME record with the hostname www and michaeljdeeb.github.io for the value.

    *.michaeljdeeb.com (*)

    Another issue I ran into is that subdomains (which I no longer utilize) were directing users to a page served up by Hover. To solve this issue I deleted out any previous records with the hostname * and created a new CNAME record with the hostname * and michaeljdeeb.github.io as the value.

    This brings users to a GitHub Pages 404.html, not my 404.html page. I believe without being able to utilize a .htaccess file there’s nothing I can do about this, but if you know otherwise, please let me know.

    michaeldeeb.com (Forwarding)

    This might be a little Hover specific, but after navigating to the management of michaeldeeb.com, I clicked “Edit” in the “Forward This Domain” row. I put http://michaeljdeeb.com in the text field and chose not to enable stealth redirection.

    This means the URL will change in the browser’s address bar. Now michaeldeeb.com and www.michaeldeeb.com forward to my new domain and any navigation tacked onto the end of the URL will be passed through. For example, http://michaeldeeb.com/blog forwards to my new blog and not just http://michaeljdeeb.com.

    On Your Side

    After I had configured everything correctly, pages were being routed correctly after about ten minutes. It can take up to a full day for things to go into effect though, so don’t lose hope and be sure to empty your browser cache.

  9. GitHub Pages, Jekyll, and Mavericks, Oh My!

    Invalid DateTime

    Using Jekyll within GitHub Pages is relatively straight forward, but due to some operating system (OS 10.9.2, Xcode 5.1) issues it became more difficult than necessary.

    At the time of writing, if you are using OS X, do not use the version of ruby that comes with your computer.

    Issue #2125 is the problem and although the ARCHFLAGS work around worked to install Jekyll, it didn’t work when running jekyll serve --watch.

    Install Xcode (Command Line Tools)

    1. Download Xcode from the Mac App Store
    2. Navigate to Xcode > Preferences > Downloads > Command Line Tools and click the download arrow. (You can also start the installation via Terminal with xcode-select --install in Mavericks.)

    Install Brew

    Navigate to brew.sh for more information or type:

    	ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"
    

    Install RVM & Ruby

    Navigate to rvm.io for more information or type:

    	\curl -sSL https://get.rvm.io | bash -s stable
    

    At this point I had to quit Terminal and reopen it to get it to recognize the rvm command.

    After reopening Terminal you’ll want to run rvm install 2.1.1 or you can attempt to find a newer version of Ruby by running rvm list known.

    The install should’ve switched to this version of Ruby (2.1.1), but to make sure you aren’t using the native version of Ruby, type rvm use 2.1.1 or verify you’re using the latest by typing which ruby and ruby --version.

    Finally, Install Jekyll

    Navigate to jekyllrb.com for more information or type:

    	gem install -V jekyll
    

    You can omit the -V, but your Terminal window will be blank for a lengthy amount of time.

    Configure your GitHub Pages Project

    1. Pull your GitHub Pages project.

      • If you need to set one up check out the GitHub Pages site.
    2. In Terminal run: jekyll new /path/to/repository/project-name

      • Note: /path/to/repository/project-name must be a path, you cannot run jekyll new from within the directory you wish to use.
      • If Jekyll says Conflict: /path/to/repository/project-name exists and is not empty., you’ll have to move the files in your project to a temporary location and rerun the command.
    3. In Terminal change directory to your project: cd /path/to/repository/project-name
    4. Then in Terminal run: jekyll serve --watch --drafts

      • --watch updates your local copy every time you save a file.
      • --drafts shows drafts on your local copy
      • Note: on OS X with the native version of Ruby this is where things fell apart and really stopped working.
      • Note: to stop hosting a local copy you can press ctrl-c
    5. At this point if another service isn’t using port 4000, you can navigate to http://localhost:4000/ or http://0.0.0.0:4000 after a couple minutes have passed.
    6. Jekyll’s documentation has great information about the Folder Structure and you’ll probably want to reference their documentation from here on out.

    Good luck and hopefully this guide was of some help!

    Also, feel free to checkout the source of this website.

  10. A New Beginning

    Invalid DateTime

    When I purchased my domain name three years ago, I wanted to use it as a spot to house creations and ideas. Needless to say, neither of those goals were attained.

    It essentially served as a networking hub where people could choose their preferred method of contact (Email, LinkedIn, Twitter, etc.) and as an appropriate place to house a full list of the classes I took during my undergrad.

    I tried hosted solutions like WordPress.com, but the UX wasn’t consistent between my blog and the rest of my site. Then, I tried rolling my own copy of WordPress last year, but that didn’t stick either. This is the solution I’ve been looking for.

    Stay tuned for the struggle of configuring it. I plan to run this website/blog with agility, so if you’re seeing a webpage that looks like it belongs to the beginning of the Internet, I apologize. The best I can offer you is that I’m working on it.

    Feedback is great and I love to have flaws in my posts correct, but when I had WordPress installed on my server the blog comments were pretty spammy. I think I’m going to try something different this time around and hope that it sticks.

  11. Programming Challenge: Change Calculator [Obj-C]

    Invalid DateTime

    As a note, this is a post that was migrated from the few entries on my WordPress blog.

    This week, my major’s on-campus organization has a meeting and we’ll be discussion solutions to r/dailyprogrammer‘s Challenge #119 [Easy] Change Calculator.

    Since this is categorized as an easy challenge I decided to revisit an old friend, Objective-C to come up with a solution.

    First off, you’ll need Xcode from the Mac App Store. I’m using version 4.6 of Xcode and Mac OS 10.8.2 as a reference.

    When you get that installed and configured, you’ll want to create a new project by clicking “Create a new Xcode project” on the splash screen, clicking File > New > Project…, or ⇧⌘N on your keyboard.

    At the project selection screen, under Mac OS X, click “Application”, and then “Command Line Tool”.

    Select a name for your product and organization and an identifier. To utilize Objective-C, you’ll want to select “Foundation” for the type. I chose to use Automatic Reference Counting (ARC) because I didn’t want to deal with retain/release, but feel free to select whatever you’re comfortable with. Click “Next” and pick somewhere to save the project.

    I thought this challenge came from a past ACM competition so I read the numbers in from a text file. You could put them in an array in code, or retrieve them via a terminal prompt.

    If you want to read them in from a text file, you’ll want to click File > New > File… or ⌘N. Under “Mac OS X”, you’ll want to click “Other” and then “Empty”. I called mine “file.in” and saved it under “Supporting Files” rather than “ChangeCalculator”. Populate it with a bunch of test numbers (think of all possible edge cases) followed by returns, save it, and click on the project so we can edit the project settings.

    On the project settings page, click on the target and then click “Build Phases”. Under “Copy File” change the destination to “Products Directory”, delete everything out of the Subpath text field, and drag your text file into the window or click the “+” button and navigate to your text file.

    Now your project is all setup to read input from a text file within the application.

    If you’d like to see what I came up with as a solution you can download the gist here.

    It’s been awhile since I’ve had to deal with Objective-C, so if you have any ways to improve/refactor this code, definitely leave it in the comments or link to your solution to this challenge.

  12. The Guide to Getting Started

    Invalid DateTime

    As a note, this is a post that was migrated from the few entries on my WordPress blog.

    The hardest part about blogging is always the first entry. I’ve decided to use my first post to help a friend and any other individuals that want to advance their programming skills. I’m going to try to break this subject up as best I can into three different levels as everybody has a different skill set. Although, there may be overlap from one level to another.

    Beginner: How to Start or Where to go if Class is Moving too Slow

    Although it can become one of the biggest distractions in your life, I’ve found reddit to be one of the best places to go to further my programming knowledge. Here are some subreddits you might want to subscribe to:

    r/CSEducation - This subreddit is focused mainly on the educating of computer science. I’ve included it at the beginner level because I’ve seen many great websites mentioned and the curriculums covered go from elementary school up through graduate school.

    r/codepros - Don’t let the pro in the name intimidate you. This is a newer subreddit I came across the other day. It’s focused on showcasing programming projects. This isn’t the place to post your homework questions, but if you’ve got something to showcase it seems like a great venue for feedback. Also, many of the projects seem to be hosted on GitHub, so you could fork a project and add to it. This would also be a good time to learn about versioning.

    r/javahelp - I believe similarly named subreddits exist for other languages, but since java is usually the starting point for many, I thought I would explicitly call it out. This would be a great place to search/post if you’re getting stuck.

    r/dailyprogrammer - This is one of the best resources to pick up a new skill set or keep your current skill set fresh. Easy problems are posted every Monday and they recommend posting your solution in the comments. This is a great way to get used to accepting feedback and participating in code reviews.

    r/learnprogramming - The actual posts in this subreddit can get rather advanced, but the sidebar is full of great resources for beginners.

    r/cscareerquestions - It’s never too early to start learning about the industry. I’ve seen a lot of good questions asked here.

    r/resumes - On a related note, if you’re struggling with your résumé, this is a great resource to critique yours. Just make sure to remove any personal information. If you’re not sure what to censor, take a look at a couple that people have posted before you submit yours.

    If you like learning via the traditional classroom setting, I would recommend using iTunes U if you’re a Mac/iOS person, otherwise coursera.org offers a similar product without the Apple ecosystem integration.

    However, not everybody has time time to sit down and start in on something new. If you’re short on time, but still want to get the most out of your classes, you can challenge yourself by modifying what you’re given. If you finish an assigned programming project before it’s due and want to do more, there are a few things to consider:

    • Translate the assignment into a new language you’re unfamiliar with
    • Optimize the program to run more efficiently
    • Rewrite the program to execute with fewer lines of code
    • Go back and comment your code
    • Determine edge cases and write tests accordingly

    If you have any tools that have helped you succeed as a programmer, please tell me about them in the comments. I’m always looking for new ways to learn.

    01000111011011110110111101100100001000000110110001110101011000110110101100100001