correct path for np.load function in python - python

I have a small question which about the funcion of numpy load.
First I save a Matrix called matrix.npy to a Folder called No_Shadowing using np.save.
I have the following folder structure: scripts -> Plots -> NO_Shadowing
Inside the folder scripts I create a script in which I want to load the saved matrix.
I don't understand which path I should give np.load, so that it loads my file.
Do I need to give the path from scripts, e.g. something like np.load('Plots/No_Shadowing/matrix.np)? I tested all variants I can imagine, none worked.

Depends...if the path is relative to your current folder you can use:
import os
np.load(os.getcwd() + "\\scripts\\Plots\\No_Shadowing\\matrix.np")
or...if scripts is at the root dir.
np.load('c:\\scripts\\Plots\\No_Shadowing\\matrix.np')

Related

Imported python file with relative path inside

I have a problem with relative paths in my python 2.7 project. I have two files, let's call them script.py and importedScript.py, which have different directories, because importedScript is in a subfolder.
importedScript.py has a method called openCSV(), which gets imported in script.py with
from subfolder.importedScript import openCSV
This works fine. The method openCSV(filename) has the following code inside:
script_path = os.path.dirname(os.path.abspath(__file__))
filepath = os.path.join(script_path, 'subfolder2/' + filename)
dataset = pd.read_csv(filepath)
This code imports a .csv file from a subfolder. This works also fine, if I run the importedScript.py by itself.
The problem now is, that when I run script.py, the relative path in importedScript.py is generated wrong. For some reasons, the system tries to load the importedScript.py from "subfolder2/" instead of "subfolder/subfolder2".
Does anyone know how to fix this?
Edit: In subfolder2 are different .csv files and I want to open different files from different python files.
you can pass the __file__ variable to the method on call:
def OpenCSV(file):
here = os.path.dirname(os.path.abspath(file))
...etc
can be called by doing OpenCSV(__file__)

How do you play sounds when the python file is in a different directory as the sound file?

So I'm making a text-based game, and after completion, I want to compile the end product to a .exe format so it's fairly easy to share (I plan on using cx_freeze)
Now, I wanted to add some background music for the game, the code below works fine IF AND ONLY IF the python file is on the desktop and so is the "sound.wav" I'm looking for ways to execute the sound.wav in background whether it's on the same or different directory as the python file, thanks
import winsound
winsound.PlaySound('sound.wav', winsound.SND_FILENAME)
Use os package to generate absolute path to your music file to make sure it always works fine.
For exampe, if your project's structure is
root
src
your_python_file.py
assets
sound.wav
So you can generate the absolute path to the sound.wav by
import os
# __file__ means the path of the current python script
root_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
bg_path = os.path.join(root_dir, "assets", "sound.wav")
Lets say you have a sub-folder called foo and a second sub-folder called subfoo
If you want go into foo sub-folder use foo/sound.wav if you want to go in the second sub-folder subfoo use foo/subfoo/sound.wav.
If you want to go up a dictionary you can use ./. For example if your sound is located in foo and you script in subfoo it could be accessed with ./sound.wav to go up one by one file use ./ again.
Otherwise you can use an 'absolute' file path where you start from C: or the drive you wish to access. For example if your file filename was located in Desktop you could use:
C:/users/username/Desktop/foo/subfoo/sound.wav

Parent path Python Maya

I have a problem. I have a GUI in maya generated by a script in python.
The GUI, when launched opens an image.To load the image I used the following line of code:
cmds.image( image='/home/s4915717/myName/artefacts/Images/UIheader02.png' )
As you can understand, if I move my script into another computer, I should manually change the path to correctly load the image.
Is there a way to prevent this and let the program find to allocation of the image by itself?
I also tried to use the following method:
import os
.
.
.
path = os.path.abspath('myName/artefacts/Images/UIheader02.png')
cmds.image( image=path )
it works on my pc, but if I move on another one it doesn't work(yes I moved the whole folder with the image inside myName/artefacts...
Your first path is absolute, your second is relative, which may be part of your issue.
Depending on your OS, Maya looks in slightly different places in the user directory for icons. See this page in the docs down near the bottom, under XBMLANGPATH for the locations Maya is expecting. You can also set XBMLANGPATH to a custom location before starting Maya if you want to point at a special place, like a network share.
If your script is called from a file outside of Maya, you can use the __file__ attribute which will give you the path to the file where you use it. You can then use it to build your path.
For example, if your script is stored in '/home/s4915717/myName/artefacts', the __file__ will return '/home/s4915717/myName/artefacts'
So __file__ + '/Images/UIheader02.png' will give you the full path : '/home/s4915717/myName/artefacts/Images/UIheader02.png'
The safest way is probably to have all your scripts stored in a specific folder (for example the Maya script file) from which you can build relative paths.
Like Martin mentioned, you can use __file__ within your script and it will return that script's full path.
So let's say you have your image in a folder with your script like so:
+--my_script.py
+--my_folder
| +--my_image.png
You can access the image in your script this way:
import os
os.path.join(os.path.dirname(__file__), "my_folder", "my_image.png")
And let's say your folder was up one directory like so:
+--my_image.png
+--my_folder
| +--my_script.py
You can use os.path.abspath instead:
import os
os.path.abspath(os.path.join(__file__, "..", "..", "my_image.png"))
abspath helps resolve the ".." to go up a directory. At the end you can use os.path.exists to verify that the resulting path does in fact exist.

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)

Accessing resource files in Python unit tests & main code

I have a Python project with the following directory structure:
project/
project/src/
project/src/somecode.py
project/src/mypackage/mymodule.py
project/src/resources/
project/src/resources/datafile1.txt
In mymodule.py, I have a class (lets call it "MyClass") which needs to load datafile1.txt. This sort of works when I do:
open ("../resources/datafile1.txt")
Assuming the code that creates the MyClass instance created is run from somecode.py.
The gotcha however is that I have unit tests for mymodule.py which are defined in that file, and if I leave the relative pathname as described above, the unittest code blows up as now the code is being run from project/src/mypackage instead of project/src and the relative filepath doesn't resolve correctly.
Any suggestions for a best practice type approach to resolve this problem? If I move my testcases into project/src that clutters the main source folder with testcases.
I usually use this to get a relative path from my module. Never tried in a unittest tho.
import os
print(os.path.join(os.path.dirname(__file__),
'..',
'resources'
'datafile1.txt'))
Note: The .. tricks works pretty well, but if you change your directory structure you would need to update that part.
On top of the above answers, I'd like to add some Python 3 tricks to make your tests cleaner.
With the help of the pathlib library, you can explicit your ressources import in your tests. It even handles the separators difference between Unix (/) and Windows ().
Let's say we have a folder structure like this :
`-- tests
|-- test_1.py <-- You are here !
|-- test_2.py
`-- images
|-- fernando1.jpg <-- You want to import this image !
`-- fernando2.jpg
You are in the test_1.py file, and you want to import fernando1.jpg. With the help to the pathlib library, you can read your test resource with an object oriented logic as follows :
from pathlib import Path
current_path = Path(os.path.dirname(os.path.realpath(__file__)))
image_path = current_path / "images" / "fernando1.jpg"
with image_path.open(mode='rb') as image :
# do what you want with your image object
But there's actually convenience methods to make your code more explicit than mode='rb', as :
image_path.read_bytes() # Which reads bytes of an object
text_file_path.read_text() # Which returns you text file content as a string
And there you go !
in each directory that contains Python scripts, put a Python module that knows the path to the root of the hierarchy. It can define a single global variable with the relative path. Import this module in each script. Python searches the current directory first so it will always use the version of the module in the current directory, which will have the relative path to the root of the current directory. Then use this to find your other files. For example:
# rootpath.py
rootpath = "../../../"
# in your scripts
from rootpath import rootpath
datapath = os.path.join(rootpath, "src/resources/datafile1.txt")
If you don't want to put additional modules in each directory, you could use this approach:
Put a sentinel file in the top level of the directory structure, e.g. thisisthetop.txt. Have your Python script move up the directory hierarchy until it finds this file. Write all your pathnames relative to that directory.
Possibly some file you already have in the project directory can be used for this purpose (e.g. keep moving up until you find a src directory), or you can name the project directory in such a way to make it apparent.
You can access files in a package using importlib.resources (mind Python version compatibility of the individual functions, there are backports available as importlib_resources), as described here. Thus, if you put your resources folder into your mypackage, like
project/src/mypackage/__init__.py
project/src/mypackage/mymodule.py
project/src/mypackage/resources/
project/src/mypackage/resources/datafile1.txt
you can access your resource file in code without having to rely on inferring file locations of your scripts:
import importlib.resources
file_path = importlib.resources.files('mypackage').joinpath('resources/datafile1.txt')
with open(file_path) as f:
do_something_with(f)
Note, if you distribute your package, don't forget to include the resources/ folder when creating the package.
The filepath will be relative to the script that you initially invoked. I would suggest that you pass the relative path in as an argument to MyClass. This way, you can have different paths depending on which script is invoking MyClass.

Categories

Resources