2

I have a code snippet using elif that checks if a file exists and continues to check through the letters of the alphabet (for example _A, _B, _C etc). All works fine but I think there must a better (or cleaner) way to write the code using a loop function instead of the way I have done.

#Create MXD file path
mxdOutput = wrFolder + "/M_" + WorkrequestRaw +"_01.mxd"
mxdPath = wrFolder + "/M_" + WorkrequestRaw +"_01"

#check for latest version and create next letter
if  not arcpy.Exists(mxdOutput):
    mxdOutput = wrFolder + "/M_" + WorkrequestRaw +"_01.mxd"
    pdfversion = ""
elif not arcpy.Exists(mxdPath +"_A.mxd"):
    mxdOutput = wrFolder + "/M_" + WorkrequestRaw +"_01_A.mxd"
    pdfversion = "A"
elif not arcpy.Exists(mxdPath +"_B.mxd"):
    mxdOutput = wrFolder + "/M_" + WorkrequestRaw +"_01_B.mxd"
    pdfversion = "B"
elif not arcpy.Exists(mxdPath +"_C.mxd"):
    mxdOutput = wrFolder + "/M_" + WorkrequestRaw +"_01_C.mxd"
    pdfversion = "C"
elif not arcpy.Exists(mxdPath +"_D.mxd"):
    mxdOutput = wrFolder + "/M_" + WorkrequestRaw +"_01_D.mxd"
    pdfversion = "D"

I am a self taught beginner and trying to keep the code tidy. Welcome any comments on a better methodology?

Update poorly written question: What I am trying to do is if file name exists write new file called 'filenameA' and if 'filenameA' exists write 'filenameB' and if 'filenameB exists write 'filenameC' etc.

4 Answers 4

5
names = ['','_A', '_B', '_C']

mxdPath = wrFolder + "/M_" + WorkrequestRaw +"_01"

for name in names:
  mxdOutput = mxdPath + name + '.mxd'
  if not arcpy.Exists(mxdOutput):
      pdfversion = name
      break
7
  • 1
    nice job with putting '' in the list of names, hadn't thought of that.
    – mr.adam
    Mar 31, 2015 at 0:09
  • So what happens if A and B exist? In this code B trumps A.. that is probably the most likely situation. Mac, if you want to stop at A (or the earliest version that exists) you can include a break statement to stop the iteration. Nice solution Nathan, concise and simple. Mar 31, 2015 at 0:09
  • Thanks @Nathan W. I substituted the code and it wrote 'filenameC' first (instead of just 'filename', and then on the second iteration did nothing. I have edited my question to make it clearer Mar 31, 2015 at 1:14
  • Are you sure? It works for me here. i.imgur.com/qIwzn4r.png
    – Nathan W
    Mar 31, 2015 at 1:44
  • 1
    Well if you get that error you code isn't nested right. I suspect you don't have the if inside the for
    – Nathan W
    Mar 31, 2015 at 4:01
3

This question is pretty close to off-topic (pure python). However, here is another method.

import os, sys, string
import arcpy

mxdPath = os.path.join(wrFolder, "M_" + WorkrequestRaw +"_01")

for letter in [''] + list(string.ascii_uppercase):
    mxdOutput = (mxdPath + '_' + letter).strip('_')+ '.mxd'
    if not arcpy.Exists(mxdOutput):
        pdfversion = name
        break
    if letter=='Z':
        raise RuntimeError('No more backup filenames available!')
3
  • Good use of ascii_uppercase as a list, +1 for that. Doesn't account for '' though. Perhaps chars = [''].extend(string.ascii_uppercase) then for letter in chars. Mar 31, 2015 at 4:44
  • Didn't even know about ascii_uppercase. Nifty.
    – Nathan W
    Mar 31, 2015 at 4:58
  • This worked as well but as @Michael points out I need to check for '' first. Mar 31, 2015 at 6:46
3

I strongly recommend using os.path.exists() when checking the existence of files (especially inside a loop)! The arcpy.Exists() function is slow and it is much faster to use os.path.exists().

1

Try this to construct name:

for i in range(10):
    fName='%s_%s.mxd'%("BASENAME",chr(65+i))

and break if does not exist. Construct new name using i

1
  • That's a great method if letters go beyond C, that way you can go from A to Z and with a little more work with divide and mod you can do AA to ZZ. Doesn't account for '' though. Mar 31, 2015 at 4:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.