|
|
CS 3721
Programming Languages
Spring 2013 |
Recitation 11.
Ruby: Classes
|
Week 12-13: Apr 10-19
|
Submit following directions at:
submissions
and rules at:
rules.
Deadlines are:
- 2013-04-19 23:59:59
(that's Fri, 19 Apr 2013, 11:59:59 pm)
for full credit.
- 2013-04-22 23:59:59 (that's Mon, 22 Apr 2013, 11:59:59 pm)
for 75% credit.
|
Program involving classes:
[See the Chapter
on Classes in the PPG for much of the notation here.]
Note that even though this problem also involves dates, it is
independent of the date problem in
Recitation 10.
You should not have any common
code between the two problems. This problem has you working with
dates and times. Ruby, like most programming languages, has
library functions for treating times and dates, and in normal applications,
you should use such library functions. This problem has you
creating classes from scratch in order to learn how to do it.
You are not allowed to use Ruby time/date library classes for
this assignment.
Consider the following Date1 class in Ruby.
(Here is the whole file, Date1 class plus
test code: date.rb.
I named this class Date1 because Ruby has a library
class Date. It actually worked to redefine
the library class, but there were other problems.)
Date1 class in Ruby,
file: date.rb |
The class Date1 |
Test code and a run |
#!/usr/bin/ruby
class Date1
attr_reader :year, :month, :day
def initialize(y, m, d)
if check_date(y, m, d)
@year, @month, @day = y, m, d
else
@year, @month, @day = 2000, 1, 1
end
end
@@mon = [nil,"Jan","Feb","Mar","Apr",
"May","Jun","Jul","Aug",
"Sep","Oct","Nov","Dec"]
@@days = [0, 31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31]
def check_date(y, m, d)
if m < 1 or m > 12 or
d < 0 or d > 31 or y < 0
false
elsif d > 0 and d <= @@days[m]
true
elsif m == 2 and d == 29 and
is_leap(y)
true
else
false
end
end
def is_leap(y)
if (y%400 == 0 or
(y%4 == 0 and y%100 != 0) )
true
else
false
end
end
def to_s
@@mon[@month] + " " + day.to_s +
", " + year.to_s
end
def incr_day
@day +=1
if not (@month == 2 and
is_leap(@year) and
@day == 29) and
@day > @@days[@month]
@day = 1
incr_month
end
end
def incr_month
@month +=1
if @month > 12
@month = 1
incr_year
end
end
def incr_year
@year += 1
end
end
|
def test_date(y, m, d)
date = Date1.new(y, m, d)
print "Start Date: ", date," "
date.incr_day
print "\n Next day: ", date
date.incr_day
print "\n Next day: ", date
date.incr_day
print "\n Next day: ", date,
"\n"
end
print "TEST ORDINARY DATES\n"
test_date(2004, 4, 22)
test_date(2013, 3, 30)
test_date(2013, 4, 29)
print "\nTEST YEAR END\n"
test_date(2001, 12, 30)
test_date(1999, 12, 30)
print "\nTEST LEAP YEARS\n"
test_date(2004, 2, 28)
test_date(2001, 2, 27)
test_date(2000, 2, 28)
test_date(1900, 2, 27)
test_date(2100, 2, 27) % ruby date.rb
TEST ORDINARY DATES
Start Date: Apr 22, 2004
Next day: Apr 23, 2004
Next day: Apr 24, 2004
Next day: Apr 25, 2004
Start Date: Mar 30, 2013
Next day: Mar 31, 2013
Next day: Apr 1, 2013
Next day: Apr 2, 2013
Start Date: Apr 29, 2013
Next day: Apr 30, 2013
Next day: May 1, 2013
Next day: May 2, 2013
TEST YEAR END
Start Date: Dec 30, 2001
Next day: Dec 31, 2001
Next day: Jan 1, 2002
Next day: Jan 2, 2002
Start Date: Dec 30, 1999
Next day: Dec 31, 1999
Next day: Jan 1, 2000
Next day: Jan 2, 2000
TEST LEAP YEARS
Start Date: Feb 28, 2004
Next day: Feb 29, 2004
Next day: Mar 1, 2004
Next day: Mar 2, 2004
Start Date: Feb 27, 2001
Next day: Feb 28, 2001
Next day: Mar 1, 2001
Next day: Mar 2, 2001
Start Date: Feb 28, 2000
Next day: Feb 29, 2000
Next day: Mar 1, 2000
Next day: Mar 2, 2000
Start Date: Feb 27, 1900
Next day: Feb 28, 1900
Next day: Mar 1, 1900
Next day: Mar 2, 1900
Start Date: Feb 27, 2100
Next day: Feb 28, 2100
Next day: Mar 1, 2100
Next day: Mar 2, 2100 |
- Answer the following questions about the Ruby program above.
(These are not necessarily obvious. You will need to consult the
reference above, or some other reference.)
- In code outside the class (at the top of the right
hand column above), the statement on the third line
is (truncated) "print date". This statement
causes things to be printed. How is the output determined?
- Does the class Date1 have a constructor? What is it?
- What is the meaning (or purpose) of the character '@'
in front of year in the code?
- What is the meaning (or purpose) of the characters '@@'
in front of days in the code?
- What is the purpose (or effect) of the line
attr_reader :year, :month, :day ?
- In the same file add another class Time1 that
will keep track of hours, minutes, and seconds. This new class
should be similar to the Date1 class.
(Again, it is named Time1 because Ruby has
a library class named Time.)
In particular, it should have methods:
initialize, check_time,
to_s, incr_sec,
incr_min, and incr_hour.
Test this new class with code to instantiate time objects
and to test incrementing by seconds, including showing that
it handles the end of a minute and the end of an hour correctly.
- Change your Time1 class so that it
inherits the Date1 class, that is Date1
is a superclass of Time1, and Time1 is
a subclass of Date1.
(In Java terms, Time1 extends Date1,
and in place of the Java "Time1 extends Date1", Ruby
writes "Time1 < Date1".
The initializer for Time1 should now have 6
parameters, including the ones before, along with year, month,
and day. These last three will be passed on into Date1
using the super method.
[Again see the Chapter on Classes
in the PPG.]
- Alter the incr_hour method of Time1,
so that in case an addition goes past hour 23, it will wrap around
to hour 0 and increment to the next day.
It is permissible to change the code in the class Date1,
although I didn't need to make any changes. There are many different
ways to write this code. You should test your program with the
following initial data, and your output should look something
like the following:
Possible output
for this question |
Start Time: Apr 22, 2004 13:15:30
Next second: Apr 22, 2004 13:15:31
Next second: Apr 22, 2004 13:15:32
Start Time: Feb 28, 2000 13:59:59
Next second: Feb 28, 2000 14:00:00
Next second: Feb 28, 2000 14:00:01
Start Time: Feb 28, 2000 23:59:59
Next second: Feb 29, 2000 00:00:00
Next second: Feb 29, 2000 00:00:01
Start Time: Feb 29, 2000 23:59:59
Next second: Mar 1, 2000 00:00:00
Next second: Mar 1, 2000 00:00:01
Start Time: Feb 28, 2001 23:59:59
Next second: Mar 1, 2001 00:00:00
Next second: Mar 1, 2001 00:00:01
Start Time: Dec 31, 2001 23:59:58
Next second: Dec 31, 2001 23:59:59
Next second: Jan 1, 2002 00:00:00
Start Time: Apr 30, 2001 23:59:58
Next second: Apr 30, 2001 23:59:59
Next second: May 1, 2001 00:00:00
|
What you should submit:
Refer to the submissions directions and to
deadlines at the top of this page. If two people are working
together, be sure that both signed in as a pair and that both
names appear at the top of the submission.
Contents of submission
for Recitation 14:
Last Name, First Name; Course Number; Recitation Number.
1. Give short answers to the questions here.
2. For your own benefit and for partial credit, you should first
create the class Time1 as a completely separate
class (in a separate file). This is very similar to Date1,
but simpler, so you should really try this one. You should test this
separately and show your test.
3. and 4. These parts just add
extra features. For full credit, it is enough to have a single Ruby
program in a single file that does everything, producing roughly the
output shown above for the 7 given inputs. (The two classes
could also be in separate files, but in that case you would need
a "require" statement.)
|
Revision date: 2013-03-23.
(Please use ISO 8601,
the International Standard Date and Time Notation.)
|