1

The question may seem confusing and I am not a coding expert, so hopefully I can explain it properly...

I have a simple windows batch file that I use to run a python script. The batch file looks something like this:

cd C:\model\scripts
python run_project.py C:\2017to2021\Spruce2\button-down-president

So after changing directories to where they python script is saved, run_project.py initializes a hydrologic model that uses inputs from the path C:\2017to2021\Spruce2\button-down-president.

The thing is, I often have many different model runs set up, each with a unique path to the inputs. Normally I will just copy a stock version of this batch file directly to the path of a given run, then manually go in and update it with the new path name. So I would copy the example batch file above to a new directory and manually turn it into something like:

cd C:\model\scripts
python run_project.py C:\Documents\BAER_Roads\Modeling\Wepp_PEP\Runs\SingleStorm\NomeCreek

Doing it this way works well enough, but it is rather clunky and it's easy to make a mistake when updating to the new path name. I would love it if there was a way for the batch file to automatically update with the path to the directory where the file itself is saved. That way I could just paste the batch file in the directory of the new model inputs are, and it would without me having to manually open the file and copy/paste the new path name.

I'm not sure if this is something that the batch file could do all together before initializing python, or if python would have to somehow look back out at the path of the file that was used to initialize it? Maybe this isn't even possible to do at all? Maybe I have no idea what I'm talking about and should keep my 2-cents to myself?

Hopefully that explanation is relatively clear... Any help would be greatly appreciated. Maybe this is quite simple for someone that knows what they're doing. But if it isn't already obvious, I am not one of those people.

Lycheki
  • 45
  • 1
  • 5

4 Answers4

1

The question in my mind is, why do you bother cd'ing to the directory containing run_project.py?

Why do you think that is necessary? If you didn't do that, then it seems you wouldn't need the absolute path to the data file.

Just use

python C:\model\scripts\run_project.py button-down-president

user15187356
  • 807
  • 3
  • 3
1

I would suggest following better solution.

First create a batch file with the following command lines:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Assign the folder path passed to batch file to environment variable FolderPath.
set "FolderPath=%~1"
rem Use the batch file path if started without a folder path argument.
if not defined FolderPath set "FolderPath=%~dp0"
rem Remove all double quotes from folder path.
set "FolderPath=%FolderPath:"=%"
if not defined FolderPath set "FolderPath=%~dp0"
rem Replace all slashes by backslashes in folder path.
set "FolderPath=%FolderPath:/=\%"
rem Make sure the folder path ends with a backslash.
if not "%FolderPath:~-1%" == "\" set "FolderPath=%FolderPath%\"
rem Check the existence of this folder and run Python on folder existing.
if exist "%FolderPath%" cd /D "C:\model\scripts" && python.exe "run_project.py" "%FolderPath%"
rem Restore the initial execution environment which includes the initial current directory.
endlocal

This batch file should be stored in one of the folders listed in environment variable PATH. Run in a command prompt window set path to get output the two environment variables PATH and PATHEXT used by cmd.exe to find executables like python.exe and scripts like the batch file with the command lines above.

Then the batch file can be run with just double clicking on it on being copied into the folder containing the files to process as well as from within a command prompt window with folder path as argument entered in a command prompt window, best with file/folder name completion as described by the usage help output on running cmd /? in a command prompt window.

But most useful would be right clicking on the batch file in its final folder and left clicking in context submenu Send to on menu item Desktop (create shortcut). Next the shortcut file created on user´s desktop is selected, cut with Ctrl+X and pasted with Ctrl+V into the folder %APPDATA%\Microsoft\Windows\SendTo which expands usually to something like C:\Users\UserName\AppData\Roaming\Microsoft\Windows\SendTo.

This makes it possible to right click on any folder in Windows File Explorer and left click in opened context menu in submenu Send to on the name of the menu item according to name of the shortcut file to start the batch file with the full qualified folder name of the right clicked folder as first argument passed by Windows File Explorer to the batch file. So the batch file can be used for any folder without the need to copy around the batch file or entering the folder path manually in a command prompt window.

The batch file is fail safe as much as possible even on wrong usage from within a command prompt window on which a folder path is entered manually perhaps not correct as argument on running the batch file. The batch file can be also called from another batch file without affecting the parent batch file environment.

The command lines starting with rem can be removed as these are only remarks explaining the code.

To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.

  • call /? ... explains %~dp0 and %~1
  • cd /?
  • echo /?
  • endlocal /?
  • for /?
  • if /?
  • rem /?
  • set /?
  • setlocal /?

See also single line with multiple commands using Windows batch file for an explanation of operator && to run python.exe only if changing the current directory to C:\model\scripts was successful which should never fail, but who guarantees data for the future.

Mofi
  • 46,139
  • 17
  • 80
  • 143
0

Normally to avoid path problems for commonly executed items, one installs those items to a folder that is apart of your path. For example, if you open "Anaconda Prompt" and run the command "openssl" it runs without care about what directory you are at. This is because Anaconda installed openssl to a folder .../Anaconda3/Library/bin and added this path to the paths that your system looks for. You can do this yourself as well.

  1. Create folder, say C:\Scripts.
  2. Add said folder to your systems PATH or to your PYTHONPATH. Windows menu, RUN, type "systempropertiesadvanced", pops open the menu, click Environment Variables. You can now add another path if you like.
  3. Drop your run_project.py file into the folder.
  4. Open any terminal and type "python run_project.py" no matter where your terminals location is.
Bobby Ocean
  • 3,120
  • 1
  • 8
  • 15
  • To clarify: to be able to run `python run_project.py` from anywhere, you would need to add the folder run_project.py is in to the PYTHONPATH environment variable. Adding it to PATH would not have the desired effect. (PYTHONPATH controls which folders Python looks in to find Python scripts; PATH controls what folders Windows looks in to find executable programs.) – Jack Taylor Feb 11 '21 at 01:45
  • @Jack Taylor My understanding is that windows Anaconda does not have a PYTHONPATH. I also doubled checked it in pycharm ipython session just to be sure. So, it appears the usage of PYTHONPATH is a linux thing. – Bobby Ocean Feb 11 '21 at 01:46
  • PYTHONPATH works on both Windows and Anaconda. A quick proof of concept: open Anaconda Prompt, run `python -c "import sys; print(sys.path)"` and observe the list of paths. Then run `set PYTHONPATH=C:\Scripts`, and run `python -c "import sys; print(sys.path)"` again. The second time you should see "C:\Scripts" in the list of paths. – Jack Taylor Feb 11 '21 at 02:07
  • Very strange. I agree with you. However, do note that "anaconda prompt" does not recogise the name PYTHONPATH as an environment variable. Hence, it is only understood when the python kernel launches. This is very different from linux. For example (just tested), you can set your extension ".py" to launch with python.exe, then windows will execute the script with python without updating your PYTHONPATH. – Bobby Ocean Feb 11 '21 at 02:19
  • As you say, the PYTHONPATH environment variable is only read by the Python executable, so it only takes effect after Python starts. However, this behaviour is the same on both Windows and Linux; Python itself doesn't differ very much between the two systems. – Jack Taylor Feb 11 '21 at 02:45
  • Ya, I clearly got confused somewhere. Thanks. – Bobby Ocean Feb 11 '21 at 02:50
0

You can do this by putting the following in your batch file:

cd /d %~dp0

cd /d moves to the relevant directory, even if that directory is on another drive. The %~dp0 part expands to the directory of the script (see this answer for more details).

The other answer about using the PYTHONPATH environment variable is also a good way to do what you want.

Jack Taylor
  • 5,588
  • 19
  • 35