0

So my program takes a CSV file that's already made and makes a new file that's more organized. It works fine when I run the program from within a Windows command prompt window. But it prints out the error message that before.csv cannot be found when running it using Win+R. The CSV file is in the same folder as the batch script used to run Python with the Python script file and two CSV file names like before.csv and after.csv.

Does anyone know what could be wrong?

import csv
import sys


def main():
    if len(sys.argv) < 3:
        sys.exit("Too few command-line arguments")
    elif len(sys.argv) > 3:
        sys.exit("Too many command-line arguments")
    else:
        if sys.argv[1][-4:] != ".csv":
            sys.exit("Not a CSV file")
        else:
            clean(sys.argv[1], sys.argv[2])


def clean(input, output):
    try:
        with open(input) as input:
            reader = csv.DictReader(input)
            with open(output, "w") as output:
                header = ["first", "last", "house"]
                writer = csv.DictWriter(output, fieldnames = header)
                writer.writeheader()
                for student in reader:
                    last, first = student["name"].split(", ")
                    house = student["house"]
                    writer.writerow({"first": first, "last": last, "house": house})
    except FileNotFoundError:
        sys.exit(f"Could not read {input}")


if __name__ == "__main__":
    main()

PS So I'm seeing that I need to add the full PATH name to my arguments. Thing is don't that kind defeat the purpose of Win-r being quick if I have to type all that.

Big_Port
  • 91
  • 9
  • Try using the full pathname as the first argument. I suspect that the current directory in your faulty installation is different from that in your working installation. – Magoo Aug 26 '23 at 14:52
  • can you tell me which cmd you are using to run the file? – sifat Aug 26 '23 at 14:54
  • 1
    Your script references the CSV file with a path relative to the current working directory. Your script does not set the current working directory. The current working directory for `python.exe` interpreting your script is defined by the process calling the Windows kernel library function [CreateProcess](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw) with the function parameter `lpCurrentDirectory` and can be any directory. – Mofi Aug 26 '23 at 14:54
  • I strongly recommend to read [How do I get the full path of the current file's directory?](https://stackoverflow.com/a/3430395/3074564) It is very easy to get the fully qualified path of the Python script file and concatenate this path with the name of any file or folder being in same directory as the Python script file for having a Python script working independent on which directory is the current working directory on execution of the Python script. – Mofi Aug 26 '23 at 14:57
  • @sifat I believe its just the regular CMD not the python one if that's what you're asking – Big_Port Aug 26 '23 at 15:09
  • By the way: If the batch file of unknown contents contains `@python.exe "C:\Path\Python Script.py" before.csv after.csv`, it can be modified to `@python.exe "C:\Path\Python Script.py" "%~dp0before.csv" "%~dp0after.csv"`. `%~dp0` is the *Windows Command Processor* method to reference the full path of the directory containing the batch script file. `%~dp0` is explained by the usage help of command __CALL__ output on running `call /?` in a Windows command prompt window. It means drive and path of argument 0 which is the full path of the batch file currently processed by `cmd.exe`. – Mofi Aug 26 '23 at 15:09
  • `%~dp0` expands to a directory path string always ending with ``\`` which is the directory separator on Windows. `%~dp0` is concatenated with file names like `before.csv` and `after.csv` without any additionally backslash which otherwise the Windows file IO functions would need to remove before passing the resulting absolute file name to the file system as explained by the Microsoft documentation Microsoft documentation about [Naming Files, Paths, and Namespaces](https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file) which should be read once by anybody writing Windows programs. – Mofi Aug 26 '23 at 15:12
  • Last but not least a batch file should not be used on containing just the single command line for running `python.exe` with the fully qualified file name of the *Python* script file and the two file names passed to the *Python* script file. It would be much better to use a shortcut file (`.lnk` file) for this task with property __Target__ containing the fully qualified file name (drive + path + name + extension) of `python.exe` enclosed in `"` and the other three arguments (*Python* script file name, input CSV file name, output CSV file name). – Mofi Aug 26 '23 at 15:16
  • The property __Start in__ defines the current working directory. Most of the shortcut properties for a Windows console application like `python.exe` are passed by `explorer.exe` (= the Windows shell with Windows __Desktop__, __Start__ menu and __Taskbar__ as visible elements for the user) to `CreateProcess` on double clicking the shortcut file or pressing the hotkey defined as __Shortcut key__ to run the application as defined with __Target__. That makes a shortcut file for running an application without or with arguments much better than a batch file on which the user cannot define anything. – Mofi Aug 26 '23 at 15:21
  • I've closed your question since the Python side of what you're asking has already been asked and answered, but there's also a CMD/batch side that I don't know about cause I don't use Windows. I presume there are existing questions about that too, or you could ask a new question if needed, like maybe "How do I pass the full path of a file to a command?" – wjandrea Aug 26 '23 at 15:42
  • BTW, it helps to make a [mre], which in this case would include the contents of the batch script and how you're calling it (like any arguments you're passing to it), as well as the [full error](//meta.stackoverflow.com/q/359146/4518341) and minimal code (like no argument checking since it's irrelevant to the problem). – wjandrea Aug 26 '23 at 15:47

0 Answers0