I am having trouble referencing a file in another directory in my rails app. I have a controller located in my_app/app/controllers/concerns/my_controller with the following line of code:
#value = %x(python ../../lib/assets/python/test.py #{Shellwords.escape(params[:first_name])} 2>&1)
That is running test.py located in my_app/lib/assets/python/test.py with the %x() subshell.
When I reference the file from my desktop, it runs the test.py code correctly. But when I place the script in my lib/assets/python folder I get a cannot find file or directory error.
How should I correctly reference my test.py file so that the %x() command can find it?
If the PATH isn't set so the user running your code is able to find python then you'll get that error.
Instead of referencing it as python which forces the system to try to locate Python by walking the PATH, use the full path to the interpreter. You can usually find that by typing
which python
at the command prompt, and then putting that into the code replacing the single word python.
Ruby's File class has several very useful methods for finding the path from a directory to another, or to a specific file. Look at:
absolute_path
realpath
expand_path
I generally use realpath since it checks to see that the target actually exists before returning a path to it.
You could use it something like:
File.realpath('../../path/to/file', File.dirname(__FILE__))
which should return a path relative to the script that is currently being executed.
You can reference from the running script using:
File.realpath('../../path/to/file', File.dirname($0))
You'll need to figure out whether you want to base your path from __FILE__ or $0 and what the differences are.
Related
Every time I try to do an action such as running a program in the VScode Terminal (also happens in PyCharm) I have to enter in the full pathname instead of just the file name. For example, instead of just doing python3 test.py to run a program, I have to enter in python3 /Users/syedrishad/Desktop/Code/test.py.
Now, this is annoying and all but it doesn't bother me too much. What does bother me is when my program is trying to pull/ open files from somewhere else. If I wanted an image call Apple.jpeg, instead of just typing in Apple.jpeg, I'd have to go and find the full pathname for it. If I were to upload a piece of code doing this to someplace like GitHub, the person who'd want to test this code out for themselves will have to go in and replace each pathname with just the file name or it won't work on their computer. This problem has been going on for a while, and I sadly haven't found a solution to this. I would appreciate any help I get. I'm also on a Mac if that makes a difference.
You could use os and sys that gives you the full path to the folder of the python file.
Sys gives you the path and os gives you the possibility to merge it with the file name.
import sys, os
print(sys.path[0]) # that is the path to the directory of the python file
print(sys.path[0]+'/name.txt') #full path to the file
print(os.path.join(sys.path[0],'name.txt')) # os.path.join takes two parameters and merges them as one path using / but the line above is also fine
In VS Code, its internal terminal is in the currently opened project folder by default. Therefore, when you use the command "python file_name.py" to run the file, the terminal cannot find the file that exists in the inner folder.
Therefore, in addition to using the file path, we can also add related settings to help it find the file.
Run: When using the run button to execute the file, we can add the following settings in "settings.json", it will automatically enter the parent folder of the executed file.
"python.terminal.executeInFileDir": true,
"When executing a file in the terminal, whether to use execute in the file's directory, instead of the current open folder."
debug: For debugging code, we need to add the following settings in "launch.json":
"cwd": "${fileDirname}",
I am building an application that needs access to a resource in the same folder (It needs the xsd file to validate the input file).
How can I reach this xsd file reliably?
To elaborate:
I need to be able to call the executable:
cd not/the/directory/of/the/program
path/to/program -c config.xml
What is the path to use here?
subprocess.Popen("xmllint --noout --schema ?/?/config.xsd " + configfilename)
Take a look at the zeroth command-line argument your program gets. It's usually the name of the program, and might also include a path to the program. Combine that with the current directory. Then use realpath or some equivalent of it to get rid of symbolic links. However, I think there are still some corner cases where this approach might fail.
You didn't specify /the programming language/ or operating system you are using. If you're writing a bash script, see here:
https://stackoverflow.com/a/246128/11451509
For Python, see How do I get the path of the current executed file in Python?
If the operating system is Linux, you could also go through the /proc pseudo filesystem, as explained here:
https://stackoverflow.com/a/738024/11451509
I currently have a Python scrip that runs through all Excel files in the current directory and generates a PDF report.
It works fine now but I don't want the users to be anywhere near frozen Python scripts. I created an MSI with cxFreeze which puts the EXE and scripts in the Program Files directory.
What I would like to be able to do is create a shortcut to this executable and pass the directory the shortcut was run from to the Python program so that can be set as the working directory. This would allow the user to move the shortcut to any folder of Excel files and generate a report there.
Does Windows send the location of a opened shortcut to the executable and is there a way to access it from Python?
When you launch a shortcut, Windows changes the working directory to the directory specified in the shortcut, in the Start in field. At this point, Windows has no memory of where the shortcut was stored.
You could change the Start in field to point to the directory that the shortcut is in. But you'd have to do that for every single shortcut, and never make a mistake.
The better approach is to use a script, rather than a shortcut. Place your actual Python script (which we'll call doit.py for sake of example) somewhere in your PYTHONPATH. Then create a single-line Python script that imports it:
import doit
Save it (but don't name it doit.py) and copy it to each directory from which you want to be able to invoke the main script. In doit.py you can use os.getcwd() to find out what directory you're being invoked from.
You could also do it with a batch file. This is a little more flexible in that you can specify the exact name of the script and which Python interpreter should be used, and don't need to store the script in a directory in PYTHONPATH. Also, you don't need to worry about the file's name clashing with the name of a Python module. Simply put this line in a file:
C:\path\to\your\python.exe C:\path\to\your\script.py
Save it as (e.g.) doit.bat and copy it into the directories from which you want to invoke it. As before, your Python script can call os.getcwd() to get the directory. Or you can write it so your Python script accepts it as the first argument, and write your batch file like:
C:\path\to\your\python.exe C:\path\to\your\script.py %cd%
Another thing you can do with the batch file approach is add a pause command to the end so that the user is asked to press a key after the script runs, giving them the opportunity to read any output generated by the script. You could even make this conditional so that it only happens if an error occurs (which requires returning a proper exit code from the script). I'll leave that as an exercise. :-)
Is there a problem with modifying the script to take the directory to process as a command line argument?
You could then configure the different shortcuts to pass in the appropriate directory.
Type the following into a batch file (i.e. script.bat):
python \absolute\path\to\your\script.py %~dp0
pause
Then add these imports at the top of your python file script.py (if not already included):
import os
import sys
And add this to the bottom of the python file (or combine it with a similar statement):
if __name__ == "__main__":
# set current working directory:
if len(sys.argv) > 1:
os.chdir(sys.argv[1])
main()
replace main() with whatever function you want to call or code you want to run.
The following is how I came to my answer:
I tried using kindall's answer and had the following issues:
The first suggestion of storing the script somewhere in PYTHONPATH could not be applied to my situation because my script will be used on a server and needs to be independent of the client computer's python environment (besides having the required pip installations).
I tried calling my python script from a Windows Batch File which could be moved to a different location. Instead of the batch file's location being used as the current working directory, it was C:\Windows.
I tried passing %cd% as an argument to my python script, then setting that to be my CWD. This still resulted in a CWD of C:\Windows.
After reviewing the comments, I tried Eryk Sun's suggestion of instead passing %~dp0 as an argument to the python script. This resulted in the CWD being correctly set to the batch file's location.
I hope this helps others facing similar difficulties.
I am using sqlite3 and python for a new website I am creating. The problem is, the "files_storage.db" file I am trying to create will not appear in any Windows 10 Folder Window, PyCharm's Directory View, nor will it appear via the command line interface.
The catch to this is, if I execute my python script multiple times, I get an error that states the database file already exists... So this file is somewhere, I guess it is a game of cat and mouse to find it.
I have ran into this problem before, but I have ALWAYS been able to find the file via the command line. Usually, I wouldn't both yall with such a question but, this is really irking me and I am going to run into serious issues when it comes time to put this baby on a server. :(
thanks in advance, and here's some screenshots I suppose.
You are using a relative file path.
Relative paths are converted to absolute ones by something like os.path.join(os.getcwd(), <relative path>). So they depend on the current working directory of the process.
Try to open it with an absolute path (starting with drive letter) to avoid any ambiguities.
If you use just a filename without a path, the file will be saved in whatever the current working directory of the Python interpreter is.
To see where the current working directory is, add the following code to the beginning of your program:
import os
print(os.getcwd())
You should then see the working directory in the output.
There is a setting for the current working directory in your IDE somewhere. See e.g. the answers to this question.
You can also do something like:
import os
path = os.path.expanduser("~") + '/Documents'
print(path)
This will allow you to access the directories for the current user. For me, this prints:
'/Users/thomasweeks/Documents'
My Python3 utility has a function that doesn't work (unless it's placed within selected directories, where it can then run the non-python pdflatex scripts successfully). I want to run the utility from a set location on any of the template.tex files I have, stored in various other locations.
The Python utility prompts the user to select a pdflatex template file from an absolute path using a tkinter.filedialog GUI, then runs the user's selected pdflatexscript using, for example: os.system("pdflatex /afullpath/a/b/c/mytemplate.tex")
Python's os.system runs pdflatex, which then runs its mytemplate.tex script. mytemplate.tex has numerous inputs written with relative paths like ./d/another.tex.
So, the Python utility works fine as long as it's in the exact same path as /afullpath/a/b/c/mytemplate.tex that the user selects. Otherwise pdflatex can't finds its own input files. pdflatex delivers an error message like: ! LaTeX Error: File ./d/another.tex not found because the execution path is relative to the Python script and not the pdflatex script.
[pdflatex needs to use relative paths because the folders with its .tex files get moved around, as needed.]
I found the following similar case on Stack Overflow, but I don't think the answers are geared towards this situation: Relative Paths In Python -- Stack Overflow
By referring to other files with relative paths like ./d/another.tex, your mytemplate.tex file is assuming (and requiring) that pdflatex is only run on it from the same directory that mytemplate.tex is located in. You thus need to satisfy this requirement by changing to the directory containing mytemplate.tex before calling os.system:
input_file = '/afullpath/a/b/c/mytemplate.tex'
olddir = os.getcwd()
os.chdir(os.path.dirname(input_file))
os.system('pdflatex ' + input_file)
os.chdir(olddir)
Even better is to use subprocess.call, as it handles the change of directory for you and isn't vulnerable to shell quoting issues:
subprocess.call(['pdflatex', input_file], cwd=os.path.dirname(input_file))
Use subprocess.run instead of os.system and pass in the cwd parameter as the directory of the latex script.
See the subprocess.run docs here, and look at the cwd parameter for subprocess.Popen.
Example:
subprocess.run(["pdflatex", "/afullpath/a/b/c/mytemplate.tex"], cwd="/afullpath/a/b/c/")