RSS

CEK.io

Chris EK, on life as a continually learning software engineer.

On Blog Scheduling

Or, evidence that I’ve learned something in four weeks at Flatiron School.

Each student at Flatiron School is expected to write a blog post about every two weeks, but when exactly are blog posts due? I confirm my dates by referring to a schedule on our Piazza course page (a screenshot appears to the right).

But how was this schedule generated? Of course it could have been done manually, copying and pasting four names at a time into each date (manually cutting out) weekends. But programmers are better than that. Avi certainly didn’t manually construct this schedule. He must have automated the process by writing a program. This post chronicles my effort to do the same.

Some context

At the end of today, we’ll have completed four of twelve weeks at Flatiron School, a full one-third. Those four weeks have covered the following:

  • Git
  • Ruby fundamentals
  • Web scraping (Nokogiri)
  • ERB
  • ORMs, databases, etc.
  • Servers, Rack, Sinatra, etc
  • Model-View-Controller (MVC) pattern
  • Test-driven development

The bolded items? Those are the ones I used in this exercise so as to intentionally practice.

My blog scheduler

You can see the full code on Github. My blog scheduler program does three main things (and two other kind of important things):

Three main things
  1. The Author class gets an array of all blog “authors” by scraping each student name from the Flatiron students site.
  2. (author.rb) download
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    # # scrape array of authors for blogs (students from flatiron site)
    class Author
      def initialize(url = 'http://students.flatironschool.com/')
        @doc = Nokogiri::HTML(open(url))
      end
    
      def scrape_authors
        @authors = @doc.css("h3 a").collect{|student| student.text}
        @authors
      end
    end
    
  3. The BlogDate creates an array of all blog dates, specifically all weekdays occuring during the semester (beginning one week into the semester).
  4. (blog_date.rb) download
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    class BlogDate
    
      #create array of all dates for blog posts (each weekday in a given range)
      def find_weekdays
        weekdays = [1,2,3,4,5]
        dates = (get_beginning..get_end).to_a.select {|k| weekdays.include?(k.wday)}
        return dates
      end
    
      #establish beginning of range of dates
      def get_beginning
        start_date = Date.new(2014, 02, 11)
        start_date
      end
    
      #establish end of range of dates
      def get_end
        end_date = Date.new(2014, 04, 26)
        end_date
      end
    
    end
    
  5. The GenerateAssignments class integrates the two arrays (authors and blog dates) and generates an html document displaying the schedule in a similar format to the one on Piazza.
  6. (generator.rb) download
    1
    2
    3
    4
    5
    6
    7
    
    class GenerateAssignments
      def make_index!
        template_doc = File.open("app/views/index.html.erb")
        template = ERB.new(template_doc.read)
        File.write("_site/index.html", template.result(binding))
      end
    end
    
Two other things
  • In order to do number 3 (above), I need an erb template.
  • (index.html.erb) download
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    <!DOCTYPE html>
    <html>
      <head>
        <title>Blog Schedule</title>
      </head>
      <body>
        <h3>Blog Schedule</h3>
          <% @groups = Author.new.scrape_authors * 6 %>
          <% BlogDate.new.find_weekdays.each do |date| %>
            <b><%= date %></b><br>
            <!-- on next line, could use shift method instead of pop to assign authors differently -->
            <% @foursome = @groups.pop(4)%> 
              <% @foursome.each do |author| %>
                <%= author %><br>
              <% end %>
              <br>
          <% end %>    
      </body>
    </html>
    
  • A runner to make it go. This way I can simply type ‘bin/runner’ into my command line, and it generates the index.
  • (runner) download
    1
    2
    3
    4
    5
    6
    
    #!/usr/bin/env ruby
    
    require_relative "../config/environment"
    
    new_blog_assignments = GenerateAssignments.new
    new_blog_assignments.make_index!
    

It works! Left: original blog schedule on Piazza. Right: my blog schedule.

Why do all this?

This was a pretty simple but worthwhile exercise. Actually, “simple” is an overstatement—I ran into quite a few snags along the way, and that’s reason enough to do it. To practice, and thus learn how to navigate those issues more easily.

But beyond just practicing, I did it for the following reasons:

  1. Looking back: I wanted to look back at what I’ve accomplished. Every day at Flatiron School there are moments that are stressful, overwhelming, and/or confusing, when it seems as if we’ll never understand /. Of course those moments come and go, but the cycle runs all over again, without any opportunity to reflect on the progress we’ve made. As Justin noted the other day, like skier making their way down a difficult slope, we need to stop along the way, look up, and realize how far we’ve come.
  2. Ensuring that I understand: I could look back at what I’ve done by running through old labs and homework exercises. But that wouldn’t accomplish what I wanted; it wouldn’t prove that I can do it myself. Almost everything we work on at Flatiron School is structured and standardized to some degree (it is a “school,”” after all). That means that my work is generally guided, whether by the other students I’m collaborating with, the test files in each given project, the pull requests up on Github, the project’s Readme, etc. I’ve learned a ton this way, but it’s left a doubt: can I do it myself? Isolated from those crutches, can I solve a problem–however basic–using the tools I’ve learned?
  3. Finish what I start: Expanding on number 2, I want to make sure I can put it all together. Sure, I can remember a basic Ruby method or a given concept like ERB. I can write methods and classes and modules and templates. But I want to make sure I can put it all together, actually run it, and see my program spit out a solution to a problem.