Re: putting date strings in order

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

  1. noydb

    noydb Guest

    On May 12, 12:26 pm, John Machin <> wrote:
    > On May 13, 1:58 am, Jaime Fernandez del Rio <>
    > wrote:
    >
    >
    >
    >
    >
    > > On Tue, May 12, 2009 at 5:02 PM, MRAB <> wrote:
    > > > John Machin wrote:

    >
    > > >> MRAB <google <at> mrabarnett.plus.com> writes:

    >
    > > >>> 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

    >
    > > >> and if you don't like what that produces, try subtract :)

    >
    > > > Oops!

    >
    > > >>> 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.

    >
    > > > Actually, subtract the start month, add 12, and then modulo 12.

    >
    > > 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?

    >
    > If that happens, it's a bug.http://docs.python.org/reference/expressions.html#binary-arithmetic-o...
    >
    > If you look at function i_divmod() in the 2.x branch's Objects/
    > intobject.c, you'll be reassured to see that it doesn't just take
    > whatever C serves up :)- Hide quoted text -
    >
    > - Show quoted text -


    Thanks to those who provided suggestions. I ended up using code
    similar to what Jaime provided above first -- truly eloquent and
    simple, especially compared to my original thoughts of several messy
    loops. I knew it could be done way better. Thanks very much Jaime!!
    That was a good learning experience for me.

    fairly finished portion of code:

    ordered_raster_list = []

    pRasters = gp.ListRasters("precip_*", "All") # an enumeration object,
    arcgis method
    pRast = pRasters.next()
    while pRast:
    ## month = pRast[-3:]
    ## print month
    print pRast
    ordered_raster_list.append(pRast)
    pRast = pRasters.next()


    print ordered_raster_list #unordered at this point

    # create a dictionary dictating the order of the the precip_<months>
    rasters
    monthsD = {"precip_jan" : 1, "precip_feb" : 2, "precip_mar" : 3,
    "precip_apr" : 4, "precip_may" : 5, "precip_jun" : 6,
    "precip_jul" : 7, "precip_aug" : 8, "precip_sep" : 9,
    "precip_oct" : 10, "precip_nov" : 11, "precip_dec" : 12}

    # sort the list based on the dictionary
    ordered_raster_list.sort(None, lambda x : monthsD[x])

    print ordered_raster_list #ordered

    start = 2 #user to define, starting month

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

    print ordered_raster_list #ordered but starting in the middle, feb in
    this case, ending with jan
     
    noydb, May 14, 2009
    #1
    1. Advertising

  2. noydb

    Peter Otten Guest

    noydb wrote:

    > On May 12, 12:26 pm, John Machin <> wrote:
    >> On May 13, 1:58 am, Jaime Fernandez del Rio <>
    >> wrote:
    >>
    >>
    >>
    >>
    >>
    >> > On Tue, May 12, 2009 at 5:02 PM, MRAB <>
    >> > wrote:
    >> > > John Machin wrote:

    >>
    >> > >> MRAB <google <at> mrabarnett.plus.com> writes:

    >>
    >> > >>> 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

    >>
    >> > >> and if you don't like what that produces, try subtract :)

    >>
    >> > > Oops!

    >>
    >> > >>> 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.

    >>
    >> > > Actually, subtract the start month, add 12, and then modulo 12.

    >>
    >> > 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?

    >>
    >> If that happens, it's a
    >> bug.http://docs.python.org/reference/expressions.html#binary-arithmetic-

    o...
    >>
    >> If you look at function i_divmod() in the 2.x branch's Objects/
    >> intobject.c, you'll be reassured to see that it doesn't just take
    >> whatever C serves up :)- Hide quoted text -
    >>
    >> - Show quoted text -

    >
    > Thanks to those who provided suggestions. I ended up using code
    > similar to what Jaime provided above first -- truly eloquent and
    > simple, especially compared to my original thoughts of several messy
    > loops. I knew it could be done way better. Thanks very much Jaime!!
    > That was a good learning experience for me.
    >
    > fairly finished portion of code:
    >
    > ordered_raster_list = []
    >
    > pRasters = gp.ListRasters("precip_*", "All") # an enumeration object,
    > arcgis method
    > pRast = pRasters.next()
    > while pRast:
    > ## month = pRast[-3:]
    > ## print month
    > print pRast
    > ordered_raster_list.append(pRast)
    > pRast = pRasters.next()
    >
    >
    > print ordered_raster_list #unordered at this point
    >
    > # create a dictionary dictating the order of the the precip_<months>
    > rasters
    > monthsD = {"precip_jan" : 1, "precip_feb" : 2, "precip_mar" : 3,
    > "precip_apr" : 4, "precip_may" : 5, "precip_jun" : 6,
    > "precip_jul" : 7, "precip_aug" : 8, "precip_sep" : 9,
    > "precip_oct" : 10, "precip_nov" : 11, "precip_dec" : 12}
    >
    > # sort the list based on the dictionary
    > ordered_raster_list.sort(None, lambda x : monthsD[x])
    >
    > print ordered_raster_list #ordered
    >
    > start = 2 #user to define, starting month
    >
    > ordered_raster_list = ordered_raster_list[start - 1:] +
    > ordered_raster_list[:start - 1]
    >
    > print ordered_raster_list #ordered but starting in the middle, feb in
    > this case, ending with jan


    Hm, if ordered_raster_list is guaranteed to contain one string item for
    every month the above can be simplified to

    months = [
    'precip_jan', 'precip_feb', 'precip_mar', 'precip_apr',
    'precip_may', 'precip_jun', 'precip_jul', 'precip_aug',
    'precip_sep', 'precip_oct', 'precip_nov', 'precip_dec']

    start = 2
    ordered_raster_list = months[start-1:] + months[:start-1]

    print ordered_raster_list

    What am I missing?

    Peter
     
    Peter Otten, May 14, 2009
    #2
    1. Advertising

  3. noydb

    noydb Guest

    On May 14, 4:13 pm, Scott David Daniels <> wrote:
    > Peter Otten wrote:
    > > Hm, if ordered_raster_list is guaranteed to contain one string item for
    > > every month the above can be simplified to

    >
    > > months = [
    > >     'precip_jan', 'precip_feb', 'precip_mar', 'precip_apr',
    > >     'precip_may', 'precip_jun', 'precip_jul', 'precip_aug',
    > >     'precip_sep', 'precip_oct', 'precip_nov', 'precip_dec']

    >
    > > start = 2
    > > ordered_raster_list = months[start-1:] + months[:start-1]

    >
    > Or even:
    >  >
    >      multi_months = [
    >          'precip_jan', 'precip_feb', 'precip_mar', 'precip_apr',
    >          'precip_may', 'precip_jun', 'precip_jul', 'precip_aug',
    >          'precip_sep', 'precip_oct', 'precip_nov', 'precip_dec'] * 2
    >      start = 2
    >      ordered_raster_list = multi_months[start - 1: start + 11]
    >
    > --Scott David Daniels
    >


    Peter and Scott --

    ordered_raster_list is guaranteed to have one string item for all 12
    months -- it is just NOT guaranteed to have those in chronological
    order, which is what is required, whether the data starts in january
    (thus ending in dec of same year) or august (thus ending in jul of the
    following year) or whenever. The initial order of the list is
    dictated by when the raster (precip_<month>) was added to it's
    container. One would hope the rasters would be added in order, but I
    cannot count on that and shouldn't.
     
    noydb, May 14, 2009
    #3
  4. noydb

    Peter Otten Guest

    noydb wrote:

    > On May 14, 4:13 pm, Scott David Daniels <> wrote:
    >> Peter Otten wrote:
    >> > Hm, if ordered_raster_list is guaranteed to contain one string item for
    >> > every month the above can be simplified to

    >>
    >> > months = [
    >> > 'precip_jan', 'precip_feb', 'precip_mar', 'precip_apr',
    >> > 'precip_may', 'precip_jun', 'precip_jul', 'precip_aug',
    >> > 'precip_sep', 'precip_oct', 'precip_nov', 'precip_dec']

    >>
    >> > start = 2
    >> > ordered_raster_list = months[start-1:] + months[:start-1]

    >>
    >> Or even:
    >> >

    >> multi_months = [
    >> 'precip_jan', 'precip_feb', 'precip_mar', 'precip_apr',
    >> 'precip_may', 'precip_jun', 'precip_jul', 'precip_aug',
    >> 'precip_sep', 'precip_oct', 'precip_nov', 'precip_dec'] * 2
    >> start = 2
    >> ordered_raster_list = multi_months[start - 1: start + 11]
    >>
    >> --Scott David Daniels
    >>

    >
    > Peter and Scott --
    >
    > ordered_raster_list is guaranteed to have one string item for all 12
    > months -- it is just NOT guaranteed to have those in chronological
    > order, which is what is required, whether the data starts in january
    > (thus ending in dec of same year) or august (thus ending in jul of the
    > following year) or whenever. The initial order of the list is
    > dictated by when the raster (precip_<month>) was added to it's
    > container. One would hope the rasters would be added in order, but I
    > cannot count on that and shouldn't.


    Then you can indeed build the list directly instead of reading it out of
    ListRasters(...) and then sorting it.

    You will get wrong results when there are missing or duplicate months anyway
    unless you work the start month into the lookup dictionary

    ordered_months = months[start-1:] + months[:start-1]
    month_dict = dict(zip(ordered_months, range(12)))
    ordered_raster_list.sort(key=month_dict.get)

    or use the modulo key.

    Peter
     
    Peter Otten, May 15, 2009
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. BoBo the monkey

    Putting a date in a .ASPX page

    BoBo the monkey, Mar 5, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    2,413
    Peter Rilling
    Mar 6, 2004
  2. Peter Grison

    Date, date date date....

    Peter Grison, May 28, 2004, in forum: Java
    Replies:
    10
    Views:
    3,303
    Michael Borgwardt
    May 30, 2004
  3. Saurabh
    Replies:
    6
    Views:
    4,572
    Chris Smith
    May 30, 2004
  4. Ben

    Strings, Strings and Damned Strings

    Ben, Jun 22, 2006, in forum: C Programming
    Replies:
    14
    Views:
    788
    Malcolm
    Jun 24, 2006
  5. noydb

    putting date strings in order

    noydb, May 12, 2009, in forum: Python
    Replies:
    10
    Views:
    494
Loading...

Share This Page