0

When I run my python script via the terminal by going into the directory the python script is held and running > python toolstation.py, the script runs successfully.

Then what I try to do is run the script via a .bat file. My .bat file is set as so:

"C:\Users\xxxx\AppData\Local\Programs\Python\Python39\python.exe" "C:\Users\xxxx\Downloads\axp_solutions\python_scripts\toolstation.py"

When I run this bat file, it gives me an exception which states it cannot find the directory to open the csv file, which is one directory above the python script.

Exception:

Traceback (most recent call last):
  File "C:\Users\xxx\Downloads\axp_solutions\python_scripts\toolstation.py", line 12, in <module>
    f = open('../input/toolstation.csv', 'r')
FileNotFoundError: [Errno 2] No such file or directory: '../input/toolstation.csv'

The code for this in the python script is set like so:

f = open('../input/toolstation.csv', 'r')

Now I can set this via a hardcoded path like so to get around it:

f = open('C:/Users/xxxx/Downloads/axp_solutions/input/toolstation.csv', 'r')

But as I am sending this script and bat file to a friend, they will have a different path set. So my question is, how should the dynamic path be set so that it is able to recognise the directory to go to?

BruceyBandit
  • 3,978
  • 19
  • 72
  • 144
  • when you run it via script the current directory is the location of the script, _not_ the python. So when python looks "up" a directory it looks up "from" the .bat file. I guess, anyway. Not used windows for a while – Paul Collingwood May 27 '21 at 15:18
  • Are you familiar with command-line arguments? You could have the user pass the specific path as an argument to your script. – Nicholas Flees May 27 '21 at 15:18
  • See https://stackoverflow.com/questions/7162366/get-location-of-the-py-source-file – jarmod May 27 '21 at 15:19
  • @PaulCollingwood ah that's how it works. Makes sense and it worked. Btw, noticed you have the same name as a profesional english cricketer. You must get that a lot :) – BruceyBandit May 27 '21 at 15:28
  • It has happened, yes! – Paul Collingwood May 27 '21 at 15:38

3 Answers3

1

Instead of constructing the path to the CSV file (based on this answer), I would suggest using Python's argparse library to add an optional argument which takes the path to that CSV file.

You could give it a reasonable default value (or even use the automatically determined relative path as the default), so that you don't have to specify anything if you are on your system, while at the same time adding a lot of flexibility to your script.

You and everyone using your script, can at any moment decide which CSV file to use, while the overhead is manageable.

Here's what I would start with:

import argparse
import os

DEFAULT_PATH = r'C:\path\that\makes\sense\here\toolstation.csv'

# Alternatively, automatically determine default path:
# DEFAULT_PATH = os.path.join(
#     os.path.dirname(os.path.abspath(__file__)),
#     r'..\input\toolstation.csv',
# )

parser = argparse.ArgumentParser(prog='toolstation')
parser.add_argument(
    '-i',
    '--input-file',
    default=DEFAULT_PATH,
    help='Path to input CSV file for this script (default: %(default)s).'
)

args = parser.parse_args()

try:
    in_file = open(args.input_file, 'r')
except FileNotFoundError:
    raise SystemExit(
        f"Input file '{args.input_file}' not found. "
        "Please provide a valid input file and retry. "
        "Exiting..."
    )

Your script gets a nice and extensible interface with out-of-the-box help (you can just run python toolstation.py --help).

People using your script will love you because you provided them with the option to choose their input file via:

python toolstation.py --input-file <some_path>

The input file path passed to the script can be absolute or relative to the directory the script is executed from.

Paul P
  • 3,346
  • 2
  • 12
  • 26
0

Use os module to get the script path and then add the path to the src file.

Ex:

import os

path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'input', 'toolstation.csv')
with open(path, 'r') as infile:
    ...
Rakesh
  • 81,458
  • 17
  • 76
  • 113
  • Because the relative directory of his friend's CSV file may not be the same as on his machine. – geofurb May 27 '21 at 15:39
  • @geofurb. that is why i am using the os module to get the script path and then for the destination path. OP states the file is `one directory above the python script` – Rakesh May 27 '21 at 15:44
  • On his machine that's the case. He has not told us that this will be true for his friend's machine. – geofurb May 27 '21 at 16:01
0

You can pass the path to that CSV in as an argument to the python script.

This tutorial may be helpful.

The batch file:

set CSV_PATH="C:\...\toolstation.csv"
"C:\...\python.exe" "C:\...\toolstation.py" %CSV_PATH%

You'll have to fill in the "..."s with the appropriate paths; this isn't magic.

The Python script:

import sys
toolstation_csv = sys.argv[1]

...

f = open(toolstation_csv, 'r')

...
geofurb
  • 489
  • 4
  • 13