How to find a file in the subfolder? - python

I have a script that uses icons on buttons. When I leave icon.gif in the folder with the script the icons can be found without an error. But I want to keep these icons in myicons folder and use them from that folder. So the structure would be like this: myscript_folder/myicons/icon_1.gif
I have a variable that keeps the path to icons, but as you've guessed the variable has only 'icon.gif' in it.
How do I add a path to "myicons" folder to this variable which is os independent?

You can use the join function from the os.path module. This module comes in different versions for different operating systems, each using the respective file separators, etc.
import os.path
os.path.join("myicons", "icon_1.gif")

Try this, which is very same as tobias_k's reply.
import os
base_dir = r"path/to/your/myscript_folder"
print os.path.join(base_dir, "myicons", "icon_1.gif")

Related

Python os.getcwd() is not working on subfolders in VSCODE

I have a python file, converted from a Jupiter Notebook, and there is a subfolder called 'datasets' inside this file folder. When I'm trying to open a file that is inside that 'datasets' folder, with this code:
import pandas as pd
# Load the CSV data into DataFrames
super_bowls = pd.read_csv('/datasets/super_bowls.csv')
It says that there is no such file or folder. Then I add this line
os.getcwd()
And the output is the top-level folder of the project, and not the subfolder when is this python file. And I think maybe that's the reason why it's not working.
So, how can I open that csv file with relative paths? I don't want to use absolute path because this code is going to be used in another computers.
Why os.getcwd() is not getting the actual folder path?
My observation, the dot (.) notation to move to the parent directory sometimes does not work depending on the operating system. What I generally do to make it os agnostic is this:
import pandas as pd
import os
__location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))
super_bowls = pd.read_csv(__location__ + '/datasets/super_bowls.csv')
This works on my windows and ubantu machine equally well.
I am not sure if there are other and better ways to achieve this. Would like to hear back if there are.
(edited)
Per your comment below, the current working directory is
/Users/ivanparra/AprendizajePython/
while the file is in
/Users/ivanparra/AprendizajePython/Jupyter/datasets/super_bowls.csv
For that reason, going to the datasets subfolder of the current working directory (CWD) takes you to /Users/ivanparra/AprendizajePython/datasets which either doesn't exist or doesn't contain the file you're looking for.
You can do one of two things:
(1) Use an absolute path to the file, as in
super_bowls = pd.read_csv("/Users/ivanparra/AprendizajePython/Jupyter/datasets/super_bowls.csv")
(2) use the right relative path, as in
super_bowls = pd.read_csv("./Jupyter/datasets/super_bowls.csv")
There's also (3) - use os.path.join to contact the CWD to the relative path - it's basically the same as (2).
(you can also use
The answer really lies in the response by user2357112:
os.getcwd() is working fine. The problem is in your expectations. The current working directory is the directory where Python is running, not the directory of any particular source file. – user2357112 supports Monica May 22 at 6:03
The solution is:
data_dir = os.path.dirname(__file__)
Try this code
super_bowls = pd.read_csv( os.getcwd() + '/datasets/super_bowls.csv')
I noticed this problem a few years ago. I think it's a matter of design style. The problem is that: your workspace folder is just a folder, not a project folder. Most of the time, your relative reference is based on the current file.
VSCode actually supports the dynamic setting of cwd, but that's not the default. If your work folder is not a rigorous and professional project, I recommend you adding the following settings to launch.json. This is the simplest answer you need.
"cwd": "${fileDirname}"
Thanks to everyone that tried to help me. Thanks to the Roy2012 response, I got a code that works for me.
import pandas as pd
import os
currentPath = os.path.dirname(__file__)
# Load the CSV data into DataFrames
super_bowls = pd.read_csv(currentPath + '/datasets/super_bowls.csv')
The os.path.dirname gives me the path of the current file, and let me work with relative paths.
'/Users/ivanparra/AprendizajePython/Jupyter'
and with that it works like a charm!!
P.S.: As a side note, the behavior of os.getcwd() is quite different in a Jupyter Notebook than a python file. Inside the notebook, that function gives the current file path, but in a python file, gives the top folder path.

python import with absolute path

I have the following folder structure and want to find a good way to import python modules.
project1/test/benchmark/benchmark_project1.py
#in benchmark_project1.py
from project1.test.benchmark import *
My question is how to get rid of project1, since it might be renamed to "project2" or something else. I want to use import with absolute path, but don't know a good way to achieve that.
You can use os.chdir() to change your directory before the import statement, and then to change it back afterward. This will allow you to specify the precise file to import. You can use os.listdir() to get the list of all files in the directory, and then simply index them. Using a loop will get all the modules in the folder, or providing the right index according to some pattern will give you a specific one. The glob module allows you to select files using regex.
import os
cwd = os.getcwd()
new_dir = 'project1/test/benchmark/'
list_dir = os.listdir(new_dir) # Find all matching
os.chdir(new_dir)
for i in range(len(list_dir)): # Import all of them (or index them in some way)
module = list_dir[i][0:-3] # Filter off the '.py' file extension
from module import *
os.chdir(cwd)
Alternatively, you can add the location to your path instead of changing directories. Take a look at this question for some additional resources.

How do I utilize a relative path?

I'm confused to as how I would do this. For example if I am referencing pic0.gif on my computer of course all I have to do for something like
def drawx():
myImWin = ImageWin('\Python34\images\pic0.gif',300,300)
Im = FileImage('\Python34\images\pic.gif')
Im.draw(myImWin)
But this would only work on my computer because I know the directory of the pic0.gif. What would I need to do so that it would automatically seek pic0.gif on a different computer with a different directory?
Usually you have a folder within your project with resources which include images:
[my_project]
[images]
pic0.gif
In your code you determine project home directory:
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
Then you get the image file like this:
myImWin = ImageWin(os.path.join(BASE_DIR, r'images/pic0.gif', 300, 300)
If you know where the image you are looking for is relative your python script, for example if the image is bundled with your script, you can retrieve the absolute path to the script and go from there:
import os
# This is the full path of the directory containing this script
dirname = os.path.abspath(os.path.dirname(__file__))
# We know that the images are in a folder named 'img'
image_path = os.path.join(dirname, "img", "pic0.gif")
Here we are using the module os.path extensively and the __file__ variable which is explained in this stackoverflow answer.
This has the advantage that it would work not where you launch your python script from.
YOu can try to play around with os module. I.e. Show full path to current folder:
import os
os.path.curdir
>>> '.'
os.path.abspath(os.path.curdir)
>>> 'C:\\Users\\User\\Desktop'

How to set current working directory in python in a automatic way

How can I set the current path of my python file "myproject.py" to the file itself?
I do not want something like this:
path = "the path of myproject.py"
In mathematica I can set:
SetDirectory[NotebookDirectory[]]
The advantage with the code in Mathematica is that if I change the path of my Mathematica file, for example if I give it to someone else or I put it in another folder, I do not need to do anything extra. Each time Mathematica automatically set the directory to the current folder.
I want something similar to this in Python.
The right solution is not to change the current working directory, but to get the full path to the directory containing your script or module then use os.path.join to build your files path:
import os
ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
# then:
myfile_path = os.path.join(ROOT_PATH, "myfile.txt")
This is safer than messing with current working directory (hint : what would happen if another module changes the current working directory after you did but before you access your files ?)
I want to set the directory in which the python file is, as working directory
There are two step:
Find out path to the python file
Set its parent directory as the working directory
The 2nd is simple:
import os
os.chdir(module_dir) # set working directory
The 1st might be complex if you want to support a general case (python file that is run as a script directly, python file that is imported in another module, python file that is symlinked, etc). Here's one possible solution:
import inspect
import os
module_path = inspect.getfile(inspect.currentframe())
module_dir = os.path.realpath(os.path.dirname(module_path))
Use the os.getcwd() function from the built in os module also there's os.getcwdu() which returns a unicode object of the current working directory
Example usage:
import os
path = os.getcwd()
print path
#C:\Users\KDawG\Desktop\Python

Save a file depending on the user Python

I try to write a script in Python that saves the file in each user directory.
Example for user 1, 2 and 3.
C:\Users\user1\Documents\ArcGIS\file1.gdb
C:\Users\user2\Documents\ArcGIS\file1.gdb
C:\Users\user3\Documents\ArcGIS\file1.gdb
How can I do this?
As one commenter pointed out, the simplest solution is to use the USERPROFILE environment variable to write the file path. This would look something like:
import os
userprofile = os.environ['USERPROFILE']
path = os.path.join(userprofile, 'Documents', 'ArcGIS', 'file1.gdb')
Or even more simply (with better platform-independence, as this will work on Mac OSX/Linux, too; credit to Abhijit's answer below):
import os
path = os.path.join(os.path.expanduser('~'), 'Documents', 'ArcGIS', 'file1.gdb')
Both of the above may have some portability issues across Windows versions, since Microsoft has been known to change the name of the "Documents" folder back and forth from "My Documents".
If you want a Windows-portable way to get the "Documents" folder, see the code here: https://stackoverflow.com/questions/3858851#3859336
In Python you can use os.path.expanduser to get the User's home directory.
>>> import os
>>> os.path.expanduser("~")
This is a platform independent way of determining the user's home directory.
You can then concatenate the result to create your final path
os.path.join(os.path.expanduser("~"), 'Documents', 'ArcGIS', 'file1.gdb')
You want to use the evironment variable HOME, something like this:
import os
homeDir = os.environ["HOMEPATH"]
file = open(homeDir+"Documents\ArcGIS\file1.gdb")
file.write("Hello, World")
file.close()
Notice that I've used HOMEPATH considering you're using Windows, it may be wrong depending on your OS. Take a look at this: http://en.wikipedia.org/wiki/Environment_variable

Categories