Thursday, 6 February 2020

Spot The Bug: The Calendar Conundrum

Hello and welcome! It's time for another episode of Spot The Bug!

I know you're
out there.

Ruby is a nice language to use with a syntax that is smooth as silk, but surprise, surprise... you can get code bugs in Ruby just as easily as any other language.

Here's what happened when I tried to use Ruby to write a script that would display a calendar view for the current month. For the record, it was this month of this year - February 2020.

In here, calStr is a list of dates, each one separated by a tab, and a break every time Saturday is encountered.
require "date"

nowDate = Date.today
currentDate = Date.new(nowDate.year, nowDate.month, 1)
lastDate = currentDate >> 1
lastDate = (lastDate - 1)
lastDay = lastDate.day

puts "Sun\tMon\tTue\tWed\tThu\tFri\tSat"
calStr = "";

for i in 1..lastDay do
    currentDate = Date.new(2020, 2, i)

    calStr = calStr + i.to_s + "\t"

    if (currentDate.wday == 6)
        calStr = calStr + "\n"
    end
end

puts calStr


Not too bad, right? Except the first day doesn't start on a Sunday, so the calendar is all wrong.


No problem! What I'll do is make another For loop before the For loop, to iterate from 0 to the first day. Then I'll print a tab character for every day before the first day!
puts "Sun\tMon\tTue\tWed\tThu\tFri\tSat"
calStr = "";

for i in 0..currentDate.wday do
    calStr = calStr + "\t"
end

for i in 1..lastDay do
    currentDate = Date.new(2020, 2, i)

    calStr = calStr + i.to_s + "\t"

    if (currentDate.wday == 6)
        calStr = calStr + "\n"
    end
end

What went wrong

Um... nope. For some reason, now the first day, 1, was out of alignment. But everything else was in alignment.


This only meant one thing - the number of tabs before the first date, was wrong. There was an extra tab.

Why it went wrong

See, one of the nice things about Ruby is that it utilizes ranges. Instead of painstakingly typing out stuff like for (int i = 0; i < x; i++), you can simply go for i in 1..x do. 1..x is the range and you can do a lot more with that. Follow this link for more about Ruby ranges!

Anyway, where I went wrong was the range. Ruby range syntax goes like this...

If you want to go from 0 to 10, you use this.
0..10


If you want to go from 0 to 9, excluding 10, you use this. See the extra dot?
0...10


I only had two dots in my range 0..currentDate.wday. Therefore the script would churn out a tab character from 0 to the first weekday... including the first weekday! So even if the first weekday was on a Sunday, there would still be a tab in front of it!

How I fixed it

That's right, all it took was an extra dot. Which meant only the number of tabs from 0 (Sunday) to the first weekday of the month (Saturday), five in all, would be printed.
for i in 0...currentDate.wday do
    calStr = calStr + "\t"
end


Voila!


Moral of the story

It's usually the very tiny things that elude us. And in this case, it was literally a dot.

Till next time..............................
T___T

No comments:

Post a Comment