CSc 120: Dates
Background
This problem involves managing a database of dates and events,
for example, for a calendar app or history website. The purpose of this assignment is to use classes
and objects.
Restrictions
-
For the long problems, your code should follow the style guidelines
for the class. The long problem specification details the commenting requirements for methods.
-
You may not use concepts and/or short-hand syntax not yet covered in class. The restrictions include the following:
list (or dictionary) comprehensions, e.g., [n * 2 for i in range(10)]
-
with open (explicitly open and close the file instead)
-
the ternary operator (use an if instead)
-
nested functions (using def within a function to define another function)
-
recursion
-
exceptions and asssertions
-
type annotations
-
lambda expressions
-
generators and user defined iterators
-
importing libraries (unless a library is explicitly mentioned in the specification)
Problem Description
Suppose you wanted to offer a website or app to manage a database of dates
and events. Such a database might be used to look up dates in the past
("on this date in history...", as in the sites mentioned above);
or they might be used as a calendar service to provide reminders for future
events. In either case, you need a program that can record and look up
strings (i.e., events) associated with dates.
One catch here is that people use many different formats
to write dates, e.g., "December 25, 2021", "2021-12-25",
and "12/25/2021", all of which represent the same date. The
format that was used to insert an event into the database may or may not be
the same as the format that will be used to look up that date. Your program therefore
needs a way to process dates in different formats and recognize when dates in different
formats are equivalent. To that end, this programming assignment
involves writing a class to maintain information about dates and events
and to recognize dates in different formats. The program will read a file
containing a series of operations, where each operation refers to a
database of dates and events, and will process each operation in turn.
Input Formats
The input to the program is read from a file (see Expected Behavior below).
Each line of the file is an operation, and is in one of the following two formats:
I Date : Event
R Date
The Date and Event fields in the operation line are as follows:
- Date
-
This specifies a date. It can be in any of the following three formats.
-
yyyy-mm-dd,
where yyyy is a 4-digit sequence
giving the year; mm is a 1- or 2-digit sequence giving the
month; and dd is a 1- or 2-digit sequence giving the date.
Example: 2017-02-31
-
mm/dd/yyyy,
where yyyy is a 4-digit sequence
giving the year; mm is a 1- or 2-digit sequence giving the
month; and dd is a 1- or 2-digit sequence giving the date.
Example: 02/31/2017.
-
MonthName dd yyyy, where MonthName is
a three-letter sequence giving the name of a month
(one of: Jan, Feb, Mar, Apr, May,
Jun, Jul, Aug, Sep, Oct, Nov,
Dec); dd is a 1- or 2-digit sequence giving the date; and
yyyy is a 4-digit sequence giving the year.
Example: Feb 31 2017
NOTE:
To simplify programming, we will assume that all months have 31 days.
- Event
-
This is a string starting at the first non-whitespace character after
the colon ":" following the date and going as
far as the end of the line.
Examples of operations are:
I 2017-01-16 : Martin Luther King Day
I Mar 31 1997: Arizona Wildcats win National Basketball Title
R 03/31/1997
The first of these inserts the event "Martin Luther King
Day" for the date Jan 16, 2017 into the
calendar. The second adds the event "Arizona Wildcats win
National Basketball Title" for the date March 31,
1997.
The third item retrieves and prints out all events for the date March 31, 1997.
NOTE:
The event may also contain the colon character ":", as shown in the Examples section (see Example 4 in that section). Be sure to consider that when you are parsing the input line.
Expected Behavior
Write a Python program, in a file dates.py, that maintains a
collection of Date objects, each of which has associated with it
a sequence of strings that refer to events for that date, processing these objects
in accordance with operations
read from an input file. Your program should behave as follows:
-
Use input() (without any argument) to read the name of an
input file.
-
Read the file specified and process the
operation given on each line as follows:
-
OpType = I. Add the Event string to the collection
of events for the date specified (duplicates are OK).
If there is no existing Date object for that date,
create one and initialize its collection of events to the Event
string specified.
-
OpType = R. Print out the event strings for that date
one per line (see Output Format below).
If there is no existing Date object for that date,
do not print anything.
-
If the OpType is not a valid operation, print an error message
(see Errors below).
Dates are considered equal if their canonical representations (see below)
are the same.
Some examples of input files and generated output are shown
here.
Canonical Representation of Dates
A date with year yyyy, month mm, and day dd, where
yyyy, mm, and dd are strings of digits,
has a canonical (i.e., standard) representation given by
"{:d}-{:d}-{:d}".format(
int(yyyy ),
int(mm),
int(dd))
The reason for converting yyyy, mm, and dd to
numbers using int() and then back to strings is to
remove any leading zeros.
Example:
Input format | Canonical representation |
Mar 7 1997
Mar 07 1997
03/07/1997
3/7/1997
1997-3-07
1997-03-7
|
1997-3-7 |
Output Format
Print out the events for a given date one event per line using the statement
print("{}: {}".format(date_canonical, event))
where date_canonical is the canonical representation of
the date, and event is an event for that date.
If there are multiple events for a given date, they should be printed in alphabetical order.
Programming Requirements
Your program must implement the following classes:
-
class Date
-
An instance of this class describes a date.
Attributes: These should include:
-
a string representing the canonical representation of the date
-
the associated events (a collection of strings, e.g., a list or set).
Methods: These should include:
-
__init__(self, date_str, event), where
date_str is a string of the date (in its canonical representation)
event is a string for an event
-
Getter methods for the attributes
-
add_event(self, event), where
event is a string for an event;
this method adds event to the collection of
events for a Date object
-
__str__(self), which returns a string representation of a Date object
-
class DateSet
-
An instance of this class describes a collection of dates.
Attributes: These should include:
-
a dictionary of Date objects.
(Consider what might you use as keys.)
Methods: These should include:
-
__init__(self), which creates an empty dictionary to hold Date objects
-
add_date(self, date_str, event), where
date_str is a string and eventis a string.
If the date is not in the collection, a new Date object is created and added to the collection.
If the date is already in the collection, the event is added to the Date object.
-
__str__(self), which returns a string representation of a DateSet object
Additionally, you will need code for the following:
-
To read in an input file name (use input() without arguments),
read a series of operations from this file (see Input Formats above), and
process them as specified under Expected Behavior above. You can
put this code in a function that is not within any class (just like
main()).
-
To convert a date string to canonical format. (You can use your solution to the short problem.) You can put this code in a function
that is not within any class (just like main()).
Your program should be appropriately modularized. In particular,
other than the code mentioned above for processing input and converting
dates to their canonical form, your code should
be placed in methods in the appropriate class.
Error Output
You need only check for the invalid operation error. Print the following error message on a single line and continue processing the input file:
“Error - Illegal operation.“
Commenting
Comment the class definitions and any functions that are outside of main with a doc string.
Comment all methods that are not getter or setter methods using a docstring.
Examples
Some examples are shown at this link:
Input and Output Examples.