Python changing file name
Question: My new application offers the ability to user to export the results. My
application exports text files with name Exp_Text_1, Exp_Text_2 etc. I want if
a file with the same file name pre-exists in Desktop to start counting from
this number and upwards. For example if a file with name Exp_Text_3 in already
in Desktop, I want the file will be created to have the name Exp_Text_4.

This is my code:

    
    
    if len(str(self.Output_Box.get("1.0", "end"))) == 1:
                self.User_Line_Text.set("Nothing to export!")
            else:
                import os.path
    
                self.txt_file_num = self.txt_file_num + 1
                file_name = os.path.join(os.path.expanduser("~"), "Desktop", "Exp_Txt" + "_" + str(self.txt_file_num) + ".txt")
    
                file = open(file_name, "a")
                file.write(self.Output_Box.get("1.0", "end"))
                file.close()
    
                self.User_Line_Text.set("A text file has been exported to Desktop!")
    


Answer: you likely want `os.path.exists`:

    
    
    >>> import os
    >>> help(os.path.exists)
    Help on function exists in module genericpath:
    
    exists(path)
        Test whether a path exists.  Returns False for broken symbolic links
    

a very basic example would be create a file name with a formatting mark to
insert the number for multiple checks:

    
    
    import os
    
    name_to_format = os.path.join(os.path.expanduser("~"), "Desktop", "Exp_Txt_{}.txt")
    #the "{}" is a formatting mark so we can do file_name.format(num)
    
    num = 1
    while os.path.exists(name_to_format.format(num)):
        num+=1
    
    new_file_name = name_to_format.format(num)
    

this would check each filename starting with `Exp_Txt_1.txt` then
`Exp_Txt_2.txt` etc. until it finds one that does not exist.

However the format mark may cause a problem if curly brackets `{}` are part of
the rest of the path, so it may be preferable to do something like this:

    
    
    import os
    
    def get_file_name(num):
        return os.path.join(os.path.expanduser("~"), "Desktop", "Exp_Txt_" + str(num) + ".txt")
    
    num = 1
    while os.path.exists(get_file_name(num)):
        num+=1
    
    new_file_name = get_file_name(num)
    

* * *

EDIT: answer to **why don't we need`get_file_name` function in first
example?**

First off if you are unfamiliar with `str.format` you may want to look at
[Python doc - common string
operations](https://docs.python.org/2/library/string.html#format-string-
syntax) and/or this simple example:

    
    
    text = "Hello {}, my name is {}."
    x = text.format("Kotropoulos","Tadhg")
    print(x)
    print(text)
    

The path string is figured out with this line:

    
    
     name_to_format = os.path.join(os.path.expanduser("~"), "Desktop", "Exp_Txt_{}.txt")
    

But it has `{}` in the place of the desired number. (since we don't know what
the number should be at this point) so if the path was for example:

    
    
     name_to_format = "/Users/Tadhg/Desktop/Exp_Txt_{}.txt"
    

then we can insert a number with:

    
    
    print(name_to_format.format(1))
    print(name_to_format.format(2))
    

and this does not change `name_to_format` since `str` objects are
[Immutable](http://stackoverflow.com/questions/1538663/why-are-python-strings-
and-tuples-are-made-immutable) so the `.format` returns a new string without
modifying `name_to_format`. However we would run into a problem if out path
was something like these:

    
    
     name_to_format = "/Users/Bob{Cat}/Desktop/Exp_Txt_{}.txt"
     #or
     name_to_format = "/Users/Bobcat{}/Desktop/Exp_Txt_{}.txt"
     #or
     name_to_format = "/Users/Smiley{:/Desktop/Exp_Txt_{}.txt"
    

Since the formatting mark we want to use is no longer the only curly brackets
and we can get a variety of errors:

    
    
     KeyError: 'Cat'
     IndexError: tuple index out of range
     ValueError: unmatched '{' in format spec
    

So you only want to rely on `str.format` when you know it is safe to use. Hope
this helps, have fun coding!

