0

I'm writing a python program that uses a list of all of the words in an English dictionary, so we're talking a few megabytes. I would like a clean way of including the list as a constant without it getting in the way of the source code. I would put it in a JSON file or something, but I'm using PySimpleGUI, and I want to take advantage of its ability to turn the code into a Windows EXE file, and I doubt it could do that with an external text file.

So, in order of preference I would like to do one of the following:

  1. Have it in an external text file if PySimpleGui's exe-maker can support that.
  2. Have it in another python script and import it.
  3. Have it in the original python script, but declare it at the top but actually fill it up at the bottom where it won't get in the way of seeing the source code.
  4. Declare it with values and all at the top of the source file, and just scroll down to the bottom whenever I look at the source code.

What's the best way to tackle this? Is there a clever way that I am missing?

Jim Clay
  • 963
  • 9
  • 24
  • Another option is to use an editor with code folding: you could have the list at the top of your file, but keep it collapsed except when you need to edit it. (I don't think #1 would work: the pysimplegui exe-maker is apparently a front end for pyinstaller, which can certainly handle external data files, but I don't think the exe-maker gives you access to such features.) – jasonharper May 27 '20 at 21:15
  • Yeah, why don't you just use `pyinstaller` and the external json file? You really shouldn't have these giant literals in source code... – juanpa.arrivillaga May 27 '20 at 21:17

1 Answers1

1

I personally think having the data in a separate file is the cleanest way. You could for example just create a csv or json or simple text file from another application and just place it in the right directory.

It seems, that pysimpleGUI does not create executables by itself, it seems to be using pyinstaller ( https://pysimplegui.readthedocs.io/en/latest/#creating-a-windows-exe-file )

Pyinstaller allows to add non python files (like for example in your case json or csv files) to its executable.

When the executable is started a temporary directory is created and all the python and the added files will be extracted and stored there.

You have to use the switch --add-data *source_path*:**destination_path**

Below example shows how to do this.

just create in the directory where your python script is installed a directory named files and place your datafiles you want to be bundled with your application inside it.

For this example this will be one file named files/info.csv

For this example to work it should contain at least one line.

Then create your python file (for this test with following contents)

example filename: sg_w_fread.py

import os
import sys

import PySimpleGUI as sg

if getattr(sys, "frozen", False):
    # for executable mode
    BASEDIR = sys._MEIPASS  
else:
    # for development mode
    BASEDIR = os.path.dirname(os.path.realpath(__file__))

print("BASEDIR =", BASEDIR)


fname = os.path.join(BASEDIR, "files", "info.csv")

# just for debugging
print("FNAME", repr(fname))
print(os.path.isfile(fname))

sg.theme('DarkAmber')   # Add a touch of color

# read something from a file
with open(fname) as fin:
    txt = fin.read().split("\n")[0]

layout = [  [sg.Text("first line of file is '" + txt + "'")],  # display something from the file
            [sg.Text('Enter something on Row 2'), sg.InputText()],
            [sg.Button('Ok'), sg.Button('Cancel')] ]

window = sg.Window('Window Title', layout)

while True:
    event, values = window.read()
    if event in (None, 'Cancel'):   # if user closes window or clicks cancel
        break
    print('You entered ', values[0])

window.close()

and type following command to create the executable:

pyinstaller -wF sg_w_fread.py --add-data files:files
gelonida
  • 5,327
  • 2
  • 23
  • 41