putting date strings in order

Discussion in 'Python' started by noydb, May 12, 2009.

  1. noydb

    noydb Guest

    All,

    How best to go about this? >>

    I have a list containing strings referring to months, like ["x_apr",
    "x_jul", "x_jan", "x_aug", "x_may", etc] -- always using the 3-chars
    for month. The list will contain all 12 months, however the starting
    month may not necessarily be jan. I want to order the list
    chronologically, but starting with the user-defined starting month.
    So a list could be [x_aug, x_sep, .... x_jul]. The list might just
    start off in any random order, but I need to ensure, in the end, that
    the list is in chronological order and starting with the proper month
    per user needs.

    Anyone have any good ideas? I was curious to see what people came up
    with.
     
    noydb, May 12, 2009
    #1
    1. Advertisements

  2. noydb

    Paul Rubin Guest

    Is this a homework assignment? Some hints:

    1) figure out how to compare two month names for chronological order,
    leaving out the issue of the starting month not being january.
    2) figure out how to adjust for the starting month. The exact
    semantics of the "%" operator might help do this concisely.
     
    Paul Rubin, May 12, 2009
    #2
    1. Advertisements

  3. noydb

    noydb Guest

    Ha! No, this is not a homework assignment. I just find myself to be
    not the most eloquent and efficient scripter and wanted to see how
    others would approach it.

    I'm not sure how I follow your suggestion. I have not worked with the
    %. Can you provide a snippet of your idea in code form?

    I thought about assigning a number string (like 'x_1') to any string
    containing 'jan' -- so x_jan would become x_1, and so on. Then I
    could loop through with a counter on the position of the number (which
    is something i will need to do, comparing one month to the next
    chronological month, then that next month to its next month, and so
    on). And as for the starting postion, the user could declare, ie, aug
    the start month. aug is position 8. therefore subtract 7 from each
    value, thus aug becomes 1.... but then I guess early months would have
    to be add 5, such that july would become 12. Ugh, seems sloppy to me.

    Something like that.... seems poor to me. Anybody have a bteer
    idea, existing code???
     
    noydb, May 12, 2009
    #3
  4. noydb:
    Then it's a very good moment to learn using it:
    http://en.wikipedia.org/wiki/Modulo_operator
    Implement your first version, run it, and show us its output. Then I/
    we can try to give you suggestions to improve your code.

    Sometimes you have to write code... that's life.

    Bye,
    bearophile
     
    bearophileHUGS, May 12, 2009
    #4
  5. If you simply want to generate an ordered list of months, start with
    it in order:

    dates = ["x_jan",...,"x_dec"]

    and if the desired starting month is

    start = 6 # i.e. x_jun

    dates = dates[start - 1:] + dates[:start - 1]

    If you have to sort the list itself, I would use an intermediate
    dictionary to hold the positions, as in:

    months = {"x_jan" : 1, ..., "x_dec" : 12}

    You can then sort the list with :

    dates.sort(None,lambda x : months[x])

    and then do the

    dates = dates[start - 1:] + dates[:start - 1]

    or alternatively you can get the sorting directly as you want it with:

    dates.sort(None,lambda x : (months[x] - start + 1) % 12)


    Jaime
     
    Jaime Fernandez del Rio, May 12, 2009
    #5
  6. noydb

    MRAB Guest

    Sort the list, passing a function as the 'key' argument. The function
    should return an integer for the month, eg 0 for 'jan', 1 for 'feb'. If
    you want to have a different start month then add the appropriate
    integer for that month (eg 0 for 'jan', 1 for 'feb') and then modulo 12
    to make it wrap around (there are only 12 months in a year), returning
    the result.
     
    MRAB, May 12, 2009
    #6
  7. noydb

    John Machin Guest

    and if you don't like what that produces, try subtract :)
    HTH,
    John
     
    John Machin, May 12, 2009
    #7
  8. noydb

    MRAB Guest

    Actually, subtract the start month, add 12, and then modulo 12.
     
    MRAB, May 12, 2009
    #8
  9. noydb

    John Machin Guest

    Ummm ... 12 modulo 12 is a big fat zero, and Python's % is a genuine
    modulo operator; unlike that of K&R C, it's defined not to go wobbly
    on negatives.

    | >>> [(i - 8 + 12) % 12 for i in range(12)]
    | [4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3]

    | >>> [(i - 8 ) % 12 for i in range(12)]
    | [4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3]
     
    John Machin, May 12, 2009
    #9
  10. Both on my Linux and my Windows pythons, modulos of negative numbers
    are properly taken, returning always the correct positive number
    between 0 and 11. I seem to recall, from my distant past, that Perl
    took pride on this being a language feature. Anyone knows if that is
    not the case with python, and so not adding 12 before taking the
    modulo could result in wrong results in some implementations?
     
    Jaime Fernandez del Rio, May 12, 2009
    #10
  11. noydb

    MRAB Guest

    Ah, yes, it's a true modulo! Nice to see that Python gets it right! :)
     
    MRAB, May 12, 2009
    #11
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.