I have written a program to solve a problem. I am not a programmer. I am looking for some examples of how some of you more experienced programmers would handle this task (using my program as a reference).
Background:
I have four years worth (500MBs) of digital photos and MPEG files of my kids/family on my windows PC. Each year, I burn CDs for my extended family. I often use the last modified date as a reference to the time that the photo was taken.
Some time ago, my Mother-in-Law asked how old my son was when he began walking, and I told her she could refer to the last modified date on the CD where I have his first steps recorded in an MPEG video file. I was surprised to find out that all of the dates on all of the files are the burn date.
Task:
So, I decided I need to rename all of the files based on the last modified date, and to do it I would write a program.
Result:
Here is the program that took me several weeks to write (during "free time" at work on UNIX):
#!/bin/env python2.2
from os import getcwd, listdir, chdir, rename from os.path import getmtime, isdir from time import localtime, strftime from string import split from glob import glob
def chname(apath): ntlist = [] mlist = glob('*.mpg') jlist = glob('*.jpg') tlist = listdir(apath) for item in tlist: #look for subdirectories if isdir(item): ntlist.append(item)
for h in range(0,4): #NOTE 1 list1 = list2[h] for i in range(len(list1)): tdir = root + '/' + list1[i] chdir(tdir) tlist = chname(tdir) for j in range(len(tlist)): tlist[j] = list1[i] + '/' + tlist[j] list2.append(tlist) chdir(root)
A couple of comments:
I could not get used to the this.that() style of code, so I stuck with: 'from this import that' so I could just write 'that(this)'. Seeing some examples of the this.that style using my program as a reference would be very helpful in my understanding.
Recursively doing operations through a directory structure is harder than I thought. I could not get the for loop by NOTE 1 to iterate as the list grew. I wanted 'for item in list: and thought the loop would keep iterating as long as directories were added to the list. Any help on geting that to work would be great. Instead, I just used integers to go as many levels deep as I needed.
I tried and tried to use the walk() function in the os.path module, but I could not get it to work. Obviously, this seems to be the way to go, and if some could get that to work I think I would do a backflip.
I have not tried this on my home machine yet since I have not installed Python yet. I'm curious if it will work with the time and os functions.
Since I'm having so much fun, I'm going to try Tkinter and make it into a gui. I'll post my progress and ask for similar comments to help me understand Python (no help with the gui until I give it a shot please).
def needsRenaming(file_name): """ Return True or False depending on whether <file_name> needs renaming """
# We only want to rename the files right? if os.path.isdir(file_name): return False
neat_extension = file_name.lower().split('.')[-1] # Returns True if our file extension is in the list. False otherwise return neat_extension in NEED_RENAMING
def renameFile(file_path): """ Rename <file_name> with the modified date """
def walkerFunction(arg, path, file_list): """ The function called for each directory visited. We'll rename all the .jpg and .mpg files we find """
print 'Folder:', path
for file_name in file_list:
# We need the full path to locate the file file_path = os.path.join(path, file_name)
if needsRenaming(file_path): renameFile(file_path)
if __name__ == '__main__':
import sys
# Call this script as; # rename.py <path to rename> # eg. # rename.py 'd:/test' if len(sys.argv) > 1: os.path.walk(sys.argv[1], walkerFunction, None) else: print "No path to rename specified." sys.exit(1)
I've tested it (on windows) and it seems to work for me. One thing I wonder about is what to do when two files in the same folder have the same modified date? Will this ever occur?
Your code is pretty good for a first go, I recommend more desciptive variable names though.
Your comments;
this.that() - It varies I guess. I like to keep the module name on the front most of the time. Unless maybe I'm calling the function a lot and it becomes a drag. But here, I've only used them once or twice so they're on.
Recursively doing operations ... - os.path.walk replaces this. Also see I've kept the full pathnames so there's no need to change directories.
os.path.walk - See the above code for it's use. It is slightly confusing I guess. Do your backflip now ;)
time and os functions - Yes, they should work. The libraries might be different internally on different OSes but provide the same functionality.
Thanks for the fast reply!! This is very much what I was looking for - some alternative ways of doing it. Also, I think that other beginners can identify with the task, follow along, and maybe even ask some questions.
You asked, One thing I wonder about is what to do when two files in the same folder have the same modified date? Will this ever occur?
I added the %H%M%S to the filename to account for that. That is one of the reasons why I wondered if windows would have seconds. With birthdays and similar events, I'm sure there will be files taken within the same minute. Did you make some dummy files with the appropriate extensions and get the expected output?
Thanks for the props on my code, my variable names were mainly acronyms. Ill provide more descriptive ones in the future.
Here is a sample of my random thoughts as I look through your code:
Only time and os were imported yet os.path.isdir(file_name) is used. This must mean that you can call a function from a module without explicitly importing it. If this is true, it helps explain the this.that() method. I dont see file_name defined anywhere wait, there it is, but what is the path, before the file_name declaration I dont see path listed as a reserved word, hmmm I see more instances of path, in front of variables I need to figure out what "path" is in Python.
Im going to play around with it some to try to figure some stuff out. There is quite a bit that I dont understand. I should be able to gain some insight by running your code with some additional print statements. Im sure Ill return with specific questions.