0

I'm trying to build an exe with this script:

from pandas import read_csv

def csv_parser(path):
    a = read_csv(path, header=0, sep=";")
    return a

volume_surfarea_table = csv_parser(R"GURPS Vehicles Calc\Tables\Volume Area Table.csv")
component_dr_table = csv_parser(R"GURPS Vehicles Calc\Tables\Components DR Table.csv")

def get_CF():
    vsp = float(input("What's the VSP? "))
    cf = vsp/5
    
    rowN = 0
    for x in range(64):
        if cf <= volume_surfarea_table.iloc[rowN,0]:
            hit_points = volume_surfarea_table.iloc[rowN,1]
            break
        rowN = rowN + 1
    
    return hit_points


def get_DR():
    compo_type = input("What's the component type? ")
    compo_type = compo_type.title()
    
    rowN = 0
    for x in range(6):
        if compo_type in component_dr_table.iloc[rowN,0]:
            compoDR = component_dr_table.iloc[rowN,1]
            break

        rowN = rowN + 1
    
    return compoDR


finished = "false"
while finished == "false":
    hit_points = get_CF()
    compoDR = get_DR()

    compo_stats = f"""Your component has {hit_points}HP and a DR of {compoDR}."""

    print(compo_stats)
    
    done = input("Are you finished? (y/n) ")
    if done == "y":
        finished = "true"

Here's what I use on prompt:

pyinstaller -F --add-data "Tables\Volume Area Table.csv;GURPS Vehicles Calc\Tables" --add-data "Tables\Components DR Table.csv;GURPS Vehicles Calc\Tables" "Vehicles Calc.py"

The building process works fine, but whenever I try to run the exe, it gives me this error:

Traceback (most recent call last):
  File "Vehicles Calc.py", line 7, in <module>
  File "Vehicles Calc.py", line 4, in csv_parser
  File "pandas\util\_decorators.py", line 311, in wrapper
  File "pandas\io\parsers\readers.py", line 586, in read_csv
  File "pandas\io\parsers\readers.py", line 482, in _read
  File "pandas\io\parsers\readers.py", line 811, in __init__
  File "pandas\io\parsers\readers.py", line 1040, in _make_engine
  File "pandas\io\parsers\c_parser_wrapper.py", line 51, in __init__
  File "pandas\io\parsers\base_parser.py", line 222, in _open_handles
  File "pandas\io\common.py", line 701, in get_handle
FileNotFoundError: [Errno 2] No such file or directory: 'Volume Area Table.csv'
[16192] Failed to execute script 'Vehicles Calc' due to unhandled exception!

What am I doing wrong? I've checked the documentation and a bunch of other stuff, but I can't build an exe that works.

AnFa
  • 47
  • 2
  • 9
  • Try passing in the full directory instead. I have a feeling you're trying the run the exe file from a different directory, and that might be causing the issue. – PreciXon Aug 26 '21 at 01:46
  • @HarshNagouda By "passing in the full directory", I assume you mean when invoking pyinstaller on prompt, right? Also, what do you mean "different directory?" shouldn't pyinstaller include the csvs inside the exe? – AnFa Aug 26 '21 at 01:53
  • I don't think its including the csv location in your script, since you're not using the full path. You might want use this structure"x:\users\dir\to\file\file" – PreciXon Aug 26 '21 at 01:56
  • @HarshNagouda I tried using full paths when doing --add-data and it didn't work. I don't understand the structure. Could you elaborate? – AnFa Aug 26 '21 at 02:01
  • Sorry, I didn't say it right. Please try using full paths inside the python file – PreciXon Aug 26 '21 at 02:02
  • I'm sorry, I think I misunderstood your question. Please try using this (https://github.com/HNagouda/Project-Creation-Automation/blob/master/create_executables.py) script to make your exe file. – PreciXon Aug 26 '21 at 02:04
  • @HarshNagouda But if I do that and give this executable to someone else, and they don't have the same folder structure that I do, they won't be able to use it, right? – AnFa Aug 26 '21 at 02:05
  • That is a good point. The only way to make it work in that case would be to create a new variable called base_path and define it this way: >>>from pathlib import Path >>> base_path = Path(__file__).resolve().parent.parent Then, you can define the variables using the os library >>>import os >>> volume_surfarea_table = csv_parser(os.path.join(base_path, R"GURPS Vehicles Calc\Tables\Volume Area Table.csv")) – PreciXon Aug 26 '21 at 02:08
  • @HarshNagouda Sorry, I have no idea what you're talking about anymore, but thanks for the help anyway. – AnFa Aug 26 '21 at 02:16

1 Answers1

2

I see that you are using the --onefile flag ( or -F) to bundle your application.

In this case you need special method to access your data files. Because your files are extracted into a temporary directory (In Windows that is %temp%\_MEIPASS). You can see the docs for reference.

So, you can do like this:

# Answer: https://stackoverflow.com/a/44352931
import sys
import os

def resource_path(relative_path):
    """ Get absolute path to resource, works for dev and for PyInstaller """
    base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
    return os.path.join(base_path, relative_path)


volume_surfarea_table = csv_parser(resource_path(r"GURPS Vehicles Calc\Tables\Volume Area Table.csv"))

You can see the question here: Bundling data files with PyInstaller (--onefile)

gfdsweds
  • 345
  • 3
  • 11
  • 1
    You mean "your files are extracted into a temporary directory" when the executable is run? Also, with this my --add-data would be "Tables\Volume Area Table.csv;GURPS Vehicles Calc\Tables"? – AnFa Aug 26 '21 at 03:11
  • Yes. You can see https://pyinstaller.readthedocs.io/en/latest/advanced-topics.html#bootloader – gfdsweds Aug 26 '21 at 03:14
  • @AnFa You can use `--onedir` to debug whether the files has been collected. – gfdsweds Aug 26 '21 at 03:19
  • When using this function, I cannot run the program through prompt or IDE. Is this the expected behavior? – AnFa Aug 26 '21 at 04:45
  • @AnFa Did you place the files correctly? It should work. Assuming script is in `a/` , then the csv files would be in `a/GURPS Vehicles Calc/Tables/` – gfdsweds Aug 26 '21 at 08:41
  • The files are where they've always been, `GURPS Vehicles Calc/Tables/`, and works just fine if I don't add the function you gave me. The error message is this: `FileNotFoundError: [Errno 2] No such file or directory: 'h:\\01 Libraries\\Documents\\Tosh0kan Studios\\Coding\\GURPS Vehicles Calc\\GURPS Vehicles Calc\\Tables\\Volume Area Table.csv'`. There's an extra `GURPS Vehicles Calc` on the path – AnFa Aug 26 '21 at 13:58
  • 1
    Found the problem. I had tried taking off `GURPS Vehicles Calc` from the code and it still didn't work. Problem was, I left it as `\Tables\Volume Area Table.csv`. That first backward slash was the problem. Now I can run the script on the IDE or through prompt without issue, and so does the executable. Thank you so much! – AnFa Aug 26 '21 at 15:04