3

I can't figure out what's wrong. I've used rename before without any problems, and can't find a solution in other similar questions.

import os
import random

directory = "C:\\whatever"
string = ""
alphabet = "abcdefghijklmnopqrstuvwxyz"


listDir = os.listdir(directory)

for item in listDir:
    path = os.path.join(directory, item)

    for x in random.sample(alphabet, random.randint(5,15)):
        string += x

    string += path[-4:] #adds file extension

    os.rename(path, string)
    string= ""
whwright
  • 531
  • 2
  • 7
  • 21
  • well, what is `path` in `os.rename(path, string)` and does it exist? – Hamish Feb 09 '12 at 23:03
  • 2
    extensions don't have to be 3 characters, so use `os.path.splitext` for that part. – wim Feb 09 '12 at 23:08
  • This is more efficient btw: `string = ''.join( random.sample(alphabet, random.randint(5,15)) )` – jdi Feb 09 '12 at 23:15
  • I think you should expand on the suggestion from @Hamish by showing us the output of your directory structure and adding a print statement right before the `os.rename` – jdi Feb 09 '12 at 23:18
  • If you want to debug this you should inspect the value of your variables. Use print statements in the absence of a debugger. I note that you are including the path in only one of the names. Bottom line is that once you inspect the values it will become obvious. – David Heffernan Feb 09 '12 at 23:18
  • 1
    better variable names would make a big difference here. path and string are poor. Use src and dest instead. – David Heffernan Feb 09 '12 at 23:34

2 Answers2

2

If you want to save back to the same directory you will need to add a path to your 'string' variable. Currently it is just creating a filename and os.rename requires a path.

for item in listDir:
    path = os.path.join(directory, item)

    for x in random.sample(alphabet, random.randint(5,15)):
        string += x

    string += path[-4:] #adds file extension
    string = os.path.join(directory,string)

    os.rename(path, string)
    string= ""
timc
  • 2,124
  • 15
  • 13
  • Switch the for loop to using the more efficient list comp for the best suggestion to the OP, also you have an indentation error in your code – jdi Feb 09 '12 at 23:21
  • @jdi walk before running. Don't worry about perf until program is correct. Also perf not an issue here at all. Think how many clocks are consumed by os.rename?!! You can write this code any which way and the os.rename will determine the elapsed time. Correctness is always the most important goal. – David Heffernan Feb 09 '12 at 23:26
  • @DavidHeffernan - I disagree. Though this is obviously just an opinion. I think its good to also correct idiomatic issues while giving an answer. Looping and adding strings is something that should definitely be addressed to help the OP grow in python. I'm voting up this answer because of it. – jdi Feb 09 '12 at 23:29
  • @jdi I think some debugging skills are the next things to learn. But then we disagree. – David Heffernan Feb 09 '12 at 23:33
  • And yet, sir, I respect the hell out of you all the same! :-) – jdi Feb 09 '12 at 23:34
2

There are a few strange things in your code. For example, your source to the file is the full path but your destination to rename is just a filename, so files will appear in whatever the working directory is - which is probably not what you wanted.

You have no protection from two randomly generated filenames being the same, so you could destroy some of your data this way.

Try this out, which should help you identify any problems. This will only rename files, and skip subdirectories.

import os
import random
import string

directory = "C:\\whatever"
alphabet = string.ascii_lowercase

for item in os.listdir(directory):
  old_fn = os.path.join(directory, item)
  new_fn = ''.join(random.sample(alphabet, random.randint(5,15)))
  new_fn += os.path.splitext(old_fn)[1] #adds file extension
  if os.path.isfile(old_fn) and not os.path.exists(new_fn):
    os.rename(path, os.path.join(directory, new_fn))
  else:
    print 'error renaming {} -> {}'.format(old_fn, new_fn)
wim
  • 338,267
  • 99
  • 616
  • 750