Search code examples
pythonpython-3.xwindowssystem32

Python script execution directory changes when I execute outside of Console


TLDR: I want to change the working directory of my script to the script file's location(instead of system32) when i run it by double clicking on it.
I have a really annoying problem I couldn't solve. I am building a python script that will take 4 text files as input and create some graphs and an excel sheet using these text files. I am going to pass my script to a friend who will copy this script into different folders and execute the script in those folders by just double-clicking on the script. The problem I am facing is when I execute my code out of cmd everything works fine. But if I double click on it, the directory my code is working changes automatically, and my program can't find the required 4 text files. I am attaching the required parts of my code below and also attaching some screenshots.
ss1
ss2

def fileOpenCheckLoad(fname):
    pl=list()
    try:
        fh=open(fname)
    except:
        print("ERROR:"+ fname +" is missing. Execution will terminate.")
        x=input("Press enter to quit.")
        quit()
    test1=fh.readline()
    test2=fh.readline()
    if test1[6]!=fname[5] and test2!='t x y\n' :
        print("ERROR: Check the contents of:"+ fname)
        x=input("Press enter to quit.")
        quit()
    count=0
    for lines in fh:
        count=count+1
        if count>2 :
            nums=lines.split()
            pl.append((float(nums[2]), float(nums[2])))
    tbr=(pl,count-2)
    return tbr

# main starts here.
cwd = os.getcwd()
print(cwd)
# In this part we open and load files into the memory. If there is an error we terminate.
(pl1, count1)=fileOpenCheckLoad('point1.txt')
(pl2, count2)=fileOpenCheckLoad('point2.txt')
(pl3, count3)=fileOpenCheckLoad('point3.txt')
(pl4, count4)=fileOpenCheckLoad('point4.txt')

Solution

  • Before calling os.getcwd(), insert this line:

    os.chdir(os.path.dirname(os.path.abspath(__file__)))
    

    Explanation

    • __file__ is a special variable in Python; as described here, "__file__ is the pathname of the file from which the module was loaded"
    • os.path.abspath returns the absolute path to the input file or directory (I included this because depending on how you load up a Python file, sometimes __file__ will be stored as a relative path, and absolute paths tend to be safer to work with)
    • os.path.dirname returns the name of the directory which contains the input file (because chdir will return an error if we give it the name of a file, so we need to give it the name of the directory which contains the file)
    • os.chdir changes the working directory