Tuesday, April 28, 2009

Console Based Schedule Reminder in Ruby

Ruby is a dynamic, open source programming language with a focus on simplicity and productivity.

Schedule Reminder is a console based small application that reads the events from a yaml file and displays reports based on the user's choice.

Its written in Ruby.For the beginning, prepare your schedule.yml file by using a text editor.

Sample yaml file can contain following lines in it for this program.

## YAML Template.

app1:
 date_time : 2009-04-22 00:00
 subject : Deadline for HW

app2:
 date_time : 2009-04-23 14:00
 subject : Lecture Hour

app3:
 date_time : 2009-04-29 14:00
 subject : Research

app4:
 date_time : 2009-04-28 14:00
 subject : Meeting at Office

app5:
 date_time : 2009-04-28 14:00
 subject : Meeting with friends

app6:
 date_time : 2009-04-28 14:00
 subject : Library

app7:
 date_time : 2009-04-30 20:00
 subject : Watch game

You can also download schedule.yml file from the link.

Then prepare your generateScheduleReport.rb file and create a new GenerateReport class in it.

When the user runs the program, a console based menu is displayed to the client. Until the client enters a valid input from the console it is displayed.

To find events of today following method can be implemented.

Method searches for the entry with today's time from the hash and if found puts it in an array.

  def generate_report_for_the_events_of_the_day()
      t = Time.now
      t = t.strftime("%Y-%m-%d")
      event_array, event_index, hashelement = load_yaml_from_location
      for i in (0...hashelement.keys.size)
        x = hashelement[hashelement.keys[i]]
        str = x[x.keys[1]]
        str = str[0..9]
        if str.eql?(t.to_s)
          event_array[event_index] = x[x.keys[0]] +" --- "+x[x.keys[1]]
          event_index = event_index + 1
        end
      end
      if event_array.size > 0
        puts "Report for the events of today is:\n"
        if event_array.size==1
            puts "There is 1 event in your schedule for today\n"
        else
            puts "There are "+event_array.size.to_s
            +" events in your schedule for today\n"
        end
        for j in (0 ... event_array.size)
          puts event_array[j]+"\n"
        end
      else
        puts "There is no event in schedule for today\n"
      end
  end

To find events of the week following method can be implemented. 

Method searches for the entry with this week's date from the hash and if found puts it in an array. strftime("%W") used to find the number of week.



  def generate_report_for_the_events_of_the_week()
      t = Time.now
      searched_week_of_year =t.strftime("%W")
      event_array, event_index, hashelement = load_yaml_from_location
      for i in (0...hashelement.keys.size)
        x = hashelement[hashelement.keys[i]]
        str = x[x.keys[1]]
        time_from_yaml = Time.parse(str)
        week_of_year_from_yaml = time_from_yaml.strftime("%W")
        if searched_week_of_year.eql?(week_of_year_from_yaml)
           event_array[event_index] = x[x.keys[0]] +" --- "+x[x.keys[1]]
           event_index = event_index + 1
        end
        week_of_year_from_yaml = 0
      end
      if event_array.size > 0
        puts "Report for the events of the week is:\n"
        if event_array.size==1
            puts "There is 1 event in your schedule for this week\n"
        else
            puts "There are "+event_array.size.to_s
            +" events in your schedule for this week\n"
        end
        for j in (0 ... event_array.size)
          puts event_array[j]+"\n"
        end
      else
        puts "There is no event in schedule for this week\n"
      end
  end

To find events of the month following method can be implemented.


Method searches for the entry with this month's date from the hash and if found puts it in an array. 

  def generate_report_for_the_events_of_the_month()
      t = Time.now
      t = t.strftime("%Y-%m-%d")
      event_array, event_index, hashelement = load_yaml_from_location
      for i in (0...hashelement.keys.size)
        x = hashelement[hashelement.keys[i]]
        str = x[x.keys[1]]
        str = str[5..6]
        if str.eql?(t.to_s[5..6])
          event_array[event_index] = x[x.keys[0]] +" --- "+x[x.keys[1]]
          event_index = event_index + 1
        end
      end
      if event_array.size > 0
        puts "Report for the events of the month is:\n"
        if event_array.size==1
            puts "There is 1 event in your schedule for this month\n"
        else
            puts "There are "+event_array.size.to_s
            +" events in your schedule for this month\n"
        end
        for j in (0 ... event_array.size)
          puts event_array[j]+"\n"
        end
      else
        puts "There is no event in schedule for this month\n"
      end
  end
To find events in the upcoming n days following method can be implemented. 

  def generate_report_for_the_events_in_the_upcoming_n_days()
      while(1)
        puts "Please enter for the number of upcoming days to generate report"
        user_input = gets
        user_input = user_input.chomp
        if is_a_number?(user_input)
          t = Time.now
          day_of_year = t.yday
          searched_day_of_year = day_of_year + user_input.to_i
          t = t.strftime("%Y-%m-%d")
          event_array, event_index, hashelement = load_yaml_from_location
          for i in (0...hashelement.keys.size)
            x = hashelement[hashelement.keys[i]]
            str = x[x.keys[1]]
            time_from_yaml = Time.parse(str)
            day_of_year_from_yaml = time_from_yaml.yday
            if day_of_year_from_yaml >= day_of_year
               and day_of_year_from_yaml <= searched_day_of_year
              event_array[event_index] = x[x.keys[0]] +" --- "+x[x.keys[1]]
              event_index = event_index + 1
            end
            day_of_year_from_yaml = 0
          end
          if event_array.size > 0
           puts "Report for the events of the upcoming "+user_input.to_s
                 +" days is:\n"
           if event_array.size==1
            puts "There is 1 event in your schedule for upcoming "
                  +user_input.to_s+" days\n"
           else
            puts "There are "+event_array.size.to_s
                  +" events in your schedule for upcoming "
                  +user_input.to_s+" days\n"
           end
           for j in (0 ... event_array.size)
             puts event_array[j]+"\n"
           end
           break
          else
            puts "There is no event in schedule for upcoming "
                  +user_input.to_s+" days"
            break
          end
        else
          puts "Enter a valid number of upcoming days!"
        end
      end
  end

To find events in the upcoming n work days following method can be implemented. 

yday method returns day of year. Exclude Sunday and Saturday in the if condition.

  def generate_report_for_the_events_in_the_upcoming_n_work_days()
      while(1)
        puts "Please enter for the number of"
              +" upcoming n working days to generate report"
        user_input = gets
        user_input = user_input.chomp
        if is_a_number?(user_input)
          t = Time.now
          day_of_year = t.yday
          searched_day_of_year = day_of_year + user_input.to_i
          t = t.strftime("%Y-%m-%d")
          event_array, event_index, hashelement = load_yaml_from_location
          for i in (0...hashelement.keys.size)
            x = hashelement[hashelement.keys[i]]
            str = x[x.keys[1]]
            time_from_yaml = Time.parse(str)
            day_from_yaml = time_from_yaml.strftime("%a")
            day_of_year_from_yaml = time_from_yaml.yday
            if day_of_year_from_yaml >= day_of_year
               and day_of_year_from_yaml <= searched_day_of_year
              if (day_from_yaml !="Sun" and day_from_yaml != "Sat")
                  event_array[event_index] = x[x.keys[0]] +" --- "+x[x.keys[1]]
                  event_index = event_index + 1
              end
            end
            day_of_year_from_yaml = 0
          end
          if event_array.size > 0
           puts "Report for the events of the upcoming "
                 +user_input.to_s+" working days is:\n"
           if event_array.size==1
            puts "There is 1 event in your schedule for upcoming "
                  +user_input.to_s+" working days\n"
           else
            puts "There are "+event_array.size.to_s
                  +" events in your schedule for upcoming "
                  +user_input.to_s+" working days\n"
           end
           for j in (0 ... event_array.size)
             puts event_array[j]+"\n"
           end
           break
          else
            puts "There is no event in schedule for upcoming "
                  +user_input.to_s+" working days"
            break
          end
        else
          puts "Enter a valid number of upcoming days!"
        end
      end
  end


To find events in the weekend following method can be implemented. strftime("%W") returns week of year. 

  def generate_report_for_the_events_in_the_weekend()
      t = Time.now
      searched_week_of_year =t.strftime("%W")
      event_array, event_index, hashelement = load_yaml_from_location
      for i in (0...hashelement.keys.size)
        x = hashelement[hashelement.keys[i]]
        str = x[x.keys[1]]
        time_from_yaml = Time.parse(str)
        day_from_yaml = time_from_yaml.strftime("%a")
        week_of_year_from_yaml = time_from_yaml.strftime("%W")
        if searched_week_of_year.eql?(week_of_year_from_yaml)
           and (day_from_yaml.eql?("Sun") or day_from_yaml.eql?("Sat"))
           event_array[event_index] = x[x.keys[0]] +" --- "+x[x.keys[1]]
           event_index = event_index + 1
        end
        week_of_year_from_yaml = 0
      end
      if event_array.size > 0
        puts "Report for the events of the weekend is:\n"
        if event_array.size==1
            puts "There is 1 event in your schedule for weekend\n"
        else
            puts "There are "+event_array.size.to_s
                  +" events in your schedule for weekend\n"
        end
        for j in (0 ... event_array.size)
          puts event_array[j]+"\n"
        end
      else
        puts "There is no event in schedule for this weekend\n"
      end
  end


To load yaml file and store its content in a hash, following method can be implemented: 

  def load_yaml_from_location
    hashelement = {}
    hashelement = YAML::load_file('/home/tufangorel/Desktop/schedule_reminder/schedule.yml')
    event_array = Array.new
    event_index = 0
    return event_array, event_index, hashelement
  end

Ruby comes with a rich date library operations.

You can download generateScheduleReport.rb file from the link. 

Put this generateScheduleReport.rb and schedule.yml files into the same folder and execute following command from the console to run the application.

user@machine:~/Desktop/reminder$ ruby generateScheduleReport.rb

A welcome menu is displayed and it loops until the user enters one of the options. 

Tested on ubuntu9.04

No comments:

Post a Comment