Relative paths error depending on Terminal's current folder - python

I've been trying to implement in my scripts that work with files the possibility to run my program regardless of the path the package is located in.
I found that with this code, it would generally work well:
import os.path
file_path = os.path.dirname(__file__)
data_path = file_path + '/myfile's/path/'
If from Terminal I try to execute
python3 path/to/my/script/script.py
I get no problem. However, if I try to run my script within the current folder it is located in (cd path/to/my/script/) an error shows up. Claiming that /myfile's/path is not a valid directory.
I figured that I could implement the following:
file_path = os.path.dirname(__file__)
if file_path:
data_path = file_path + '/myfile's/path'
else:
data_path = 'myfile's/path'
This seems to work out fine, but I wonder if there is a normalized or better way to do this that regards other types of errors I might have not encountered yet.
Thanks ;)

not really (this question isnt actually appropriate for SO but here goes)
you need to do this... but when I do i tend to abstract it out
def rel_path(*parts):
BASE = os.path.dirname(__file__)
return os.path.abspath(os.path.join(BASE,*parts))
then I use this function everywhere
my_path = rel_path("myfiles","path","example.jpg")
# /path/to/this/file/myfiles/path/example.jpg

Related

How to get the directory to open a file from another file in Python

Having this directory structure. fileOpener.py opens the testfile.txt. And fileCallingFileOpener.py, fileCallingFileOpener2.py and fileCallingFileOpener3.py call a method from fileOpener.py that opens testfile.txt. What would be the correct path written in fileOpener.py so that it always work? Even in other computers.
\parentDirectory
\subfldr1
-fileOpener.py
-testfile.txt
\subfldr2
-fileCallingFileOpener.py
\subfldr2
-fileCallingFileOpener2.py
-fileCallingFileOpener3.py
I am asking something like:
os.path.join("..", "subfldr1", "testfile.txt")
But make it generic so it doesn't depends from where you call it.
You could try to get the location of the fileOpener module using __file__ and then make the path relative to that:
# parentDirectory/subfldr1/fileOpener.py
from pathlib import Path
def read_file():
file_path = Path(__file__).parent / "testfile.txt"
with file_path.open("r", encoding="utf-8") as file:
...
An alternative is to just use an absolute path to a file created in a temp directory, if necessary, or configurable by the end user with, for example, an environment variable.

How can I set the path of the script as working directory in Python using Atom editor?

I want to set the path of the python script as the working directory. I've tried the solutions I've found other solutions, but they aren't working for me.
This solution:
import os
path = os.path.dirname(os.path.realpath(sys.argv[0]))
dn = os.path.dirname(os.path.realpath("__file__"))
dn
gives:
'C:\\Users\\23392\\Desktop'
and my script is in a folder of desktop.
This solution:
import os
print(os.path.dirname(os.path.realpath(__file__)))
gives the following error:
NameError: name '__file__' is not defined
I need to define it as a string to prevent the error. And I get the same result that the previous one:
'C:\\Users\\23392\\Desktop'
The path should be:
C:\Users\23392\Desktop\05_Work\test.py
EDIT
I've found a partial solution. If I open the file with right click->open with->Atom, it recognizes the path of the file. It works this way but it has to be another way to do it.
Please try this version:
import os
abspath = os.path.abspath(__file__)
basename = os.path.basename(__file__)
fullpath = os.path.join(abspath + "\\" + basename)
print(fullpath)
Write this code into a file and then run it using Python interpreter.
If you try it from an interactive shell it will not work, __file__ is not defined in the interactive interpreter because it is meaningless there.
It is set by the import implementation, so if you use a non-standard import mechanism it might also be unset.

Struggling to handle paths in Jupyter Notebook

I'm struggling to handle my paths for the project. To give you an overview I need to show you my directory tree:
I'd like to setup the paths correctly so that I won't have to change them when working on two machines.
In PortfolioOptimizer notebook, I'm using:
# set current working path
notebook_path = os.getcwd()
print (notebook_path)
I don't understand, why it prints out C:\xampp\htdocs\tools\python\learn2fly which is the path to the different project.
Even when I add let's say portfolio_paths.py to Portfolio_analysis directory with this code:
import os
def get_dir_path():
current_path = os.getcwd()
return current_path
and then in my notebook I use the below line of code:
from Portfolio_analysis.portfolio_paths import get_dir_path
# set current working path
notebook_path = get_dir_path()
I'm still getting C:\xampp\htdocs\tools\python\learn2fly
getcwd() returns the current working directory, this may change based on the way you run Jupyter Notebook or Lab (namely if you use --notebook-dir).
Take also a look to this answer.

Python, Creating a new file/folder in the same directory as the script

I've written a script that basically creates two new folders when it's run the first time, if the folders don't already exist.
import os
try:
os.makedirs('results/graphs')
except OSError:
pass
And everytime the script is run, the graphs are produced in the results/graphs folder.
But I noticed recently that if the script is run from another directory, (eg. script is in home/user/script/ but I run it from: home/user/programs/), the new folders are created in home/user/programs/.
My goal is ultimately that the folders are created only in the script folder and all eventual graphs that are produced will thus be destined to home/user/script/results/graphs.
Is there someway to achieve this using python?
I'm using Debian 8 and python 2.7.13. The graphs are produced using matplotlib.
It's a solution for me, check it (I tried it on windows):
import os
d = os.path.dirname(__file__) # directory of script
p = r'{}/results/graphs'.format(d) # path to be created
try:
os.makedirs(p)
except OSError:
pass
In your script results/graphs refers to the results folder within whatever folder you ran the script from. If you always want the folders to be created in /home/user/script/results/graphs use ~/script/results/graphs in your script instead. Alternatively you could hard code the whole path, /home/user/script/results/graphs.
There is another way, apart from hard coding which is mentioned earlier. You can use __file__ to extract the path of the file where the script is present. And then you can use it to append as parent path to results/graphs
All you have to do is to define the path where your script is. This can be done within the code as:
path = 'home/user/script/'
or by getting the input from the user using a filedialog box.
Then you can use the path variable to make the directories.
os.makedirs(path + 'results/graphs')
##creating folder
import tkinter as tk
from tkinter import filedialog
root = tk.Tk()
root.withdraw()
file_path = filedialog.askopenfilename()
dirctry = os.path.dirname(file_path)
toolSharePath = os.path.abspath(dirctry)
final_directory = os.path.join(toolSharePath, r'new_folder')
if not os.path.exists(final_directory):
os.makedirs(final_directory,exist_ok=True)

Using Python 2.7 to call an application in a sub folder of the folder containing the .py

I was wondering if there was a way to call an external application that is in the sub folder of the existing folder (To look like Figure 1, And not Figure 2). Im aware I can have it open a specific file path, however I need this to work on ANY computer when the folder is in ANY directory, Which simply would not work in when on another computer.
Figure 1:
https://gyazo.com/4c98428836e03e0b7a3e2c6bf2c0d9e1
Figure 2:
https://gyazo.com/8e0263ee7918e2fa26653a1dcc6187c7
I'm currently using code that looks like this to launch them, But it only works when its in the same folder:
def Button3():
os.startfile('procexp.exe')
def Button4():
os.startfile('IJ.exe')
def Button5():
os.startfile('Br.exe')
def Button6():
os.startfile('Cs.exe')
Sorry if this seems as a bit of a newbie question, But it would really help me out if I got an answer on this
Just add the relative path:
. means starting from present-working-directory (usually the location where the program is launched from).
So if you are launching the main program from the same folder that it's in then:
def Button3():
os.startfile('./resources/procexp.exe')
def Button4():
os.startfile('./resources/IJ.exe')
def Button5():
os.startfile('./resources/Br.exe')
def Button6():
os.startfile('./resources/Cs.exe')
However that's not usually the case, most of the time you would launch the program from wherever you are (either because it's in your PATH environment) or by supplying the full path to it. In that case you want to figure out where the program is installed and then figure out where you put the resources relative to it:
the special variable __file__ contains where your script is including the path to it. You can get the directory name by using dirname method in the os.path package:
program_dir = os.path.dirname(__file__)
You can then work relative to that:
resource_dir = os.path.join(program_dir, 'resources')
os.path.join is a way to join path bits together in a operating system agonstic way.
So eventually your program can become:
resource_dir = os.path.join(os.path.dirname(__file__), 'resources');
def Button3():
os.startfile(os.path.join(resource_dir, 'procexp.exe'))
def Button4():
os.startfile(os.path.join(resource_dir, 'IJ.exe'))
def Button5():
os.startfile(os.path.join(resource_dir, 'Br.exe'))
def Button6():
os.startfile(os.path.join(resource_dir, 'Cs.exe'))
etc.
Of course in order to use os.path you need to import it:
import os;
You have to provide the path and can use the sys module, e.g. like this
import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), 'relative_path_to_your_file'))

Categories

Resources