vishi has asked for the wisdom of the Perl Monks concerning the following question:

Hi All!

I am trying to write a program that will try and automate a 'time-table' of sorts where PersonA is assigned to work on TaskX, PersonB->TaskY, PersonC->TaskZ ..and so on. This pattern repeats daily and the tasks can be assigned to different people (not necessarily the same association followed earlier). I'd like to use a hash for this association.

The thing I am doubtful about is this: Being a 'calendar/time table', I need to display this information for each day in a meaningful manner. I have something like this in mind:

Mon,22Apr13:PersonA->TaskX,PersonB->TaskY, PersonA->TaskZ Tue,23Apr13:PersonA->TaskL,PersonD->TaskT, PersonK->TaskQ, PersonP->Ta +skA ... ...

I am not sure how I can generate the calendar values and display information like above. I know I can get the date (or a range of dates) and use them but I'm not able to put both of these together, i.e., the dates and the assignments.

I'm thinking an Array (or List) where in each element will be a hash. Other ideas include using a Hash where the Key is the Date and the Value will be an array with colons separating the Person:Task list. Is this the best way to do it or are there simpler, easier methods to achieve the same result? I'd like to know how I can design this - any help/alternate ideas with the design and structure will be highly appreciated.

Cheers!

Replies are listed 'Best First'.
Re: Calendar / Scheduler in Perl
by blue_cowdawg (Monsignor) on Apr 25, 2013 at 13:03 UTC
        I'd like to know how I can design this - any help/alternate ideas with the design and structure will be highly appreciated.

    If you were my boss or a client (same thing really) presenting me with this requirement I'd call this an incomplete program spec.

    • is this a command line application or a web application
    • are we printing reports or emailing them?
    • what is the user interface for entering data?
    • is there a database involved?
    • if not a database what type of repository?
    and from the answer to those questions would probably generate more.


    Peter L. Berghold -- Unix Professional
    Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg

      Apologies for not giving you guys the full details! Okay Here are the details:

      • This would be a command line application only
      • We are just printing reports on screen
      • The data will be read from plain text files - One will have Person Names and the other will have a List of Tasks
      • There is no database involved as of now, but if things continue to grow (either # of tasks or people), we *may* think of moving everything to a DB
      • All the reports will again be stored as flat files (CSV perhaps)

      This is precisely why I am looking for design ideas / suggestions ... I have the scenario with me; I just dont know how to put everything together. Moreover, we may have to deal with things like people taking the day off, vacations, etc. which will come later as a part of my algorithm.

      I'm sure there are others who have had a similar problem and have implemented it in their own ways - I tried a search but got only topics related to 'calendar' and 'date' modules. Modules will come later - right now I am thinking of a good data structure to implement this idea.

      I could use a list of lists too... lots of "possibilities" in my head right now.. but I'm really not sure which one works best; That's where I need your suggestions as I believe atleast one of you may have come across such a task in your Perl work...

      Thanks Again!!

        This should give you a starting point.

        #!/usr/bin/perl -w use strict; my $OldIFS = $/; $/="**"; my ($taskList,$assigns)=<DATA>; chomp($taskList); $/=$OldIFS; my @tasks=split(/[\n]/,$taskList); my $timeline={}; foreach my $task(@tasks){ $timeline->{$task}=[]; } my @resourceList=split(/[\n]+/,$assigns); foreach my $assign(@resourceList){ my($resource,$theTasks)=split(/[\=]/,$assign); next unless $resource; # Deal with empty lines $resource =~ s/\s+$//; $theTasks =~ s/^\s+//; $theTasks =~ s/\s+$//; my @tasks=split(/[\s]+/,$theTasks); foreach my $task(@tasks){ push @{$timeline->{$task}},$resource; } } foreach my $key(sort keys %$timeline){ printf "%s\t%s\n",$key,join(",",@{$timeline->{$key}}); } exit(0); __END__ Task1 Task2 Task3 Task4 Task5 ** Joe Blow = Task1 Sally Brown = Task1 Task2 Jane Doe = Task3 Task5 Sid Down = Task2 Task4 Hoof Hearted = Task1 Task5


        Peter L. Berghold -- Unix Professional
        Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
Re: Calendar / Scheduler in Perl
by flexvault (Monsignor) on Apr 25, 2013 at 16:58 UTC

    Hello vishi,

    blue_cowdawg is absolutely correct about asking more questions before starting this task.

    So I'm going to give you some thoughts and ideas about how to arrange the data. I once automated a court calendar, and I arranged the data as:

    $key = "$date|$time|$court|$judge|$seq"; # $seq allows duplicates ( + "","01",... ) $value = "$case|...";
    This work was done in C, and I didn't have the luxury of having Perl to get the project completed. :-(

    I used a "key/value" indexed database, and when it came to producing reports, the data was already in the correct order. As each value was entered into the indexed DB, the DB stored the data in the correct order because of the way the key was designed. So if asked to produce the report for a specific court for the next week, it was just set the DB key to the start of the week and reading the DB sequentially until the $date result wasn't part of the week. If you needed a report for a specific judge, you just read the data for the week as above and then use 'split'* to get the $judge and when you find the correct judge, simple add that entry to the report.

    Some other thoughts:

    • $date should be "YYYYMMDD" to make sure it's in correct order, and make sure MM and DD are 2 digits. You can add a delimiter for visual help.
    • $time should be 24 clock or use the output from 'time'. Note: Today I use 'time' to combine date and time.
    • Before entering the key/value into the DB, I would use 'lc' on the $key to eliminate case typos. If any part of the $key needs to be case sensitive, then add that to the value part of the record.

    Notice that the DB is very much like a Hash, it just the DB can get a lot bigger than the memory you have. To test this without needing a DB, you can use a file and a delimiter between the key and the value. I use chr(254), but any unique unused character will work. Read the file and 'split' on your delimiter to get the key/value for each record and then use 'sort keys %Hash' when reporting or updating the file. To continue to use this without a DB, you can name the files by year, i.e. Cal2013.index, etc.

    Now Perl can be as complex as you want, but sometimes a little simplicity goes a long way. But that's part of your decisions in implementing this project.

    Good Luck...Ed

    * How I wish I had 'split' back then!

    "Well done is better than well said." - Benjamin Franklin

Re: Calendar / Scheduler in Perl
by BillKSmith (Monsignor) on Apr 25, 2013 at 14:37 UTC
    Refer to the function strftime in the module posix to format the date as required.
    Bill