开发者

Generate a list of file names based on month and year arithmetic

开发者 https://www.devze.com 2023-02-10 20:04 出处:网络
How can I list the numbers 01 to 12 开发者_高级运维(one for each of the 12 months) in such a way so that the current month always comes last where the oldest one is first.In other words, if the number

How can I list the numbers 01 to 12 开发者_高级运维(one for each of the 12 months) in such a way so that the current month always comes last where the oldest one is first. In other words, if the number is grater than the current month, it's from the previous year.

e.g. 02 is Feb, 2011 (the current month right now), 03 is March, 2010 and 09 is Sep, 2010 but 01 is Jan, 2011. In this case, I'd like to have [09, 03, 01, 02]. This is what I'm doing to determine the year:

for inFile in os.listdir('.'):
    if inFile.isdigit():
    month = months[int(inFile)]
       if int(inFile) <= int(strftime("%m")):
           year = strftime("%Y")
       else:
           year = int(strftime("%Y"))-1
       mnYear = month + ", " + str(year)

I don't have a clue what to do next. What should I do here?


Update:

I think, I better upload the entire script for better understanding.

#!/usr/bin/env python

import os, sys
from time import strftime
from calendar import month_abbr

vGroup = {}
vo = "group_lhcb"
SI00_fig = float(2.478)
months = tuple(month_abbr)

print "\n%-12s\t%10s\t%8s\t%10s" % ('VOs','CPU-time','CPU-time','kSI2K-hrs')
print "%-12s\t%10s\t%8s\t%10s" % ('','(in Sec)','(in Hrs)','(*2.478)')
print "=" * 58

for inFile in os.listdir('.'):
    if inFile.isdigit():
        readFile = open(inFile, 'r')
        lines = readFile.readlines()
        readFile.close()

        month = months[int(inFile)]
        if int(inFile) <= int(strftime("%m")):
            year = strftime("%Y")
        else:
            year = int(strftime("%Y"))-1
        mnYear = month + ", " + str(year)

        for line in lines[2:]:
            if line.find(vo)==0:
                g, i = line.split()
                s = vGroup.get(g, 0)
                vGroup[g] = s + int(i)

        sumHrs = ((vGroup[g]/60)/60)
        sumSi2k = sumHrs*SI00_fig
        print "%-12s\t%10s\t%8s\t%10.2f" % (mnYear,vGroup[g],sumHrs,sumSi2k)
        del vGroup[g]

When I run the script, I get this:

[root@serv07 usage]# ./test.py 

VOs               CPU-time  CPU-time     kSI2K-hrs
                  (in Sec)  (in Hrs)      (*2.478)
==================================================
Jan, 2011        211201372     58667     145376.83
Dec, 2010          5064337      1406       3484.07
Feb, 2011         17506049      4862      12048.04
Sep, 2010        210874275     58576     145151.33

As I said in the original post, I like the result to be in this order instead:

Sep, 2010        210874275     58576     145151.33
Dec, 2010          5064337      1406       3484.07
Jan, 2011        211201372     58667     145376.83
Feb, 2011         17506049      4862      12048.04

The files in the source directory reads like this:

[root@serv07 usage]# ls -l
total 3632
-rw-r--r--  1 root root 1144972 Feb  9 19:23 01
-rw-r--r--  1 root root  556630 Feb 13 09:11 02
-rw-r--r--  1 root root  443782 Feb 11 17:23 02.bak
-rw-r--r--  1 root root 1144556 Feb 14 09:30 09
-rw-r--r--  1 root root  370822 Feb  9 19:24 12

Did I give a better picture now? Sorry for not being very clear in the first place. Cheers!!


Update @Mark Ransom

This is the result from Mark's suggestion:

[root@serv07 usage]# ./test.py 

VOs               CPU-time  CPU-time     kSI2K-hrs
                  (in Sec)  (in Hrs)      (*2.478)
==========================================================
Dec, 2010          5064337      1406       3484.07
Sep, 2010        210874275     58576     145151.33
Feb, 2011         17506049      4862      12048.04
Jan, 2011        211201372     58667     145376.83

As I said before, I'm looking for the result to b printed in this order: Sep, 2010 -> Dec, 2010 -> Jan, 2011 -> Feb, 2011 Cheers!!


You can't print a sorted list unless you sort the list! I think the easiest way to modify your code is to get the filenames first, sort them, then operate on the sorted list. By building the list as a tuple with the year and month in that order, the sorting will give you the correct order automatically.

filelist = []
for inFile in os.listdir('.'):
    if inFile.isdigit():
        if int(inFile) <= int(strftime("%m")):
            year = strftime("%Y")
        else:
            year = int(strftime("%Y"))-1
        filelist.append((year, inFile))
filelist.sort()
for year, inFile in filelist:
    month = months[int(inFile)]
    ...


Third Update:

import os, sys
from time import strftime
from calendar import month_abbr

thismonth = int(strftime("%m"))
sortedmonths = ["%02d" % (m % 12 + 1) for m in range(thismonth, thismonth + 12)]
inFiles = [m for m in sortedmonths if m in os.listdir('.')]

for inFile in inFiles:
    readFile = open(inFile, 'r')
    # [ ... everything else is the same from here (but reindented)... ]

List comprehensions are preferable but if something I've done isn't kosher in 2.3, try this:

inFiles = filter(lambda x: x.isdigit(), os.listdir('.'))
sortedmonths = map(lambda x: "%02d" % (x % 12 + 1), range(thismonth, thismonth + 12))
inFiles = filter(lambda x: x in inFiles, sortedmonths)

Second Update:

Ok, based on your edit, here's what I think is the simplest solution:

import os, sys
from time import strftime
from calendar import month_abbr

thismonth = int(strftime("%m"))
inFiles = []
for inFile in os.listdir('.'):
    if inFile.isdigit():
        inFiles.append(inFile)
inFiles.sort(key=lambda x: (int(x) - thismonth - 1) % 12)

for inFile in inFiles:
    readFile = open(inFile, 'r')
    # [ ... everything else is the same from here (but reindented)... ]

This way your main loop goes through the files in the correct order.

You could also replace the four-line loop above with a one-line comprehension:

inFiles = [inFile for inFile in os.listdir('.') if inFile.isdigit()]

Also, I recommend using from datetime import datetime and then datetime.now(). Its interface is nicer than strftime() -- datetime.now().month returns a numerical month (same for .year, .min, .second, etc., and str(datetime.now()) presents a nicely formatted date-time string.

Update:

Ok, after some more fiddling, here's what I think works best -- this works regardless of whether Jan = 1 or Jan = 0:

>>> themonths = [1, 2, 3, 9]
>>> themonths.sort(key=lambda x: (x - thismonth - 1) % 12)
>>> themonths
[2, 3, 9, 1]

Original Post:

If I understand you correctly:

>>> thismonth = 1
>>> [m % 12 for m in range(thismonth + 1, thismonth + 13)]
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1]

Or if you only want some months you could to this:

>>> thismonth = 1
>>> themonths = [0, 1, 2, 8]
>>> [m % 12 for m in range(thismonth + 1, thismonth + 13) if m % 12 in themonths]
[2, 8, 0, 1]

Note that in this scheme Jan = 0 .... Dec = 11. If you want Jan = 1 you could just add 1 to the resulting numbers (i.e. [m % 12 + 1 for ... if m % 12 + 1 in themonths]) . But I think Jan = 0 is a better system, at least for the backend.


Your question is hard for me to understand.

If you just want to rotate the 12 digits of the months so the current month's digit is last, this does it:

>>> def rot_list(l,n):
...    return l[n:]+l[:n]
... 
>>> rot_list(range(1,13),2)
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2]

If what you are looking for is the target list (in your example) ending up sorted and rotated so that the one closest to the current month (represented by n) is at the end, this does it:

>>> tar=[1,2,3,9]
>>> n=2
>>> [x for x in range(1,13)[n:]+range(1,13)[:n] if x in tar]
[3, 9, 1, 2]
>>> tar=[3,1,2,9]
>>> [x for x in range(1,13)[n:]+range(1,13)[:n] if x in tar]
[3, 9, 1, 2]

Now if you need that list to have leading zeros and the individual elements be strings:

>>> nm=[3,9,1,2]
>>> fn=['%02i' % x for x in nm]
>>> fn
['03', '09', '01', '02']

All these methods work regardless of Jan being '0' or '1'. Just change any reference of range(1,13) to range(0,12) depending on the convention.

Edit

If I am understanding what you are doing, this code will help:

import datetime

def prev_month(year,month,day):
    l=range(1,13)
    l=l[month:]+l[:month]
    p_month=l[10]
    if p_month>month:
        p_year=year-1
    else:
        p_year=year
    return (p_year,p_month,1)

def next_month(year,month,day):
    l=range(1,13)
    l=l[month:]+l[:month]
    p_month=l[0]
    if p_month<month:
        p_year=year+1
    else:
        p_year=year
    return (p_year,p_month,1)

year=2011
month=2
t=(year-1,month,1)
ds=[]
for i in range(1,13):
    print datetime.date(*t).strftime('%m, %y')
    t=next_month(*t)

Output:

02, 10
03, 10
04, 10
05, 10
06, 10
07, 10
08, 10
09, 10
10, 10
11, 10
12, 10
01, 11

Just put the applicable format of the file name in the strftime() method...

Hope that is what you are looking for...

0

精彩评论

暂无评论...
验证码 换一张
取 消