Python cx-freeze and missing files due to exe path - python

I did an application in Python using Pygame, then I did the exe using cx-freeze with build_msi option. The result is that the folder where I install the application contains in its root all files needed to run (apart the libs created by cx-freeze). So running my app from the folder where is installed or clicking its link on the desktop it works. Instead if I tr to start the application from a different folder using the console it does not start because it does not find some files, but it does not search for them in the folder where they are installed... so... the problem is that I need to start the application also from a different folder and I can not use a bat file where I could change to the folder and then run the application. Is there a way so that the Python application may know where are the files without fix their path on it (because in this case I would have a lot of problems during development)? I tryed to access them trough something like os.getcwd() + fileName but it does not work anyway.

The problem here is with the working directory because if you open the file from it's folder then the working directory will be correct but if you open the file from another place the working directory will be different and you will be looking for something that doesn't exist. os.getcwd() returns the working directory. but os.path.dirname(__file__) returns the directory to the folder that the running script is in. so you can do that:
import os
projectFolder = os.path.dirname(__file__)
os.path.join(projectFolder, fileName)

Related

How to find the path of a specific file from another folder

Problem definition:
I am running python scripts from Excel using xlwings and I have a file that I am using in these scripts.
I used to have the path specific to my computer (ex--> C:\users\myuser\some_folder\myfile).
now I am sending these scripts to my collogues to use, and I want the path of the file to be automatically configured according to the location of the file on their machines. I tried using os package.
I tried this post and this post and finally tried moving the file in the same location and used os.getcwd() to get the working directory and concatenated with the file name to get the path.
these methods worked fine when I am running the python scripts alone (not from Excel), but When I tried running from Excel it did not work because for some reason when running python scripts from Excel the working directory changes to C:\\ProgramData\\Anaconda3\\
and no longer sees the file. also, these method (according to my understanding) uses the path of the directory from which the file is running.
they are only seeing files in C:\\ProgramData\\Anaconda3\\.
my 1st thought was to try to search for the folder name using this solution but the problem is that I do not know which location the end user will store the folder in.
What I am thinking now is find a way to locate (form this location C:\\ProgramData\\Anaconda3\\ (where python is run from Excel)) the folder which the file is stored at and from there easily grab the file path. after searching the web I did not find a suitable solution for my case.
so, is there a way to do this using os or any other package?
__file__ contains the absolute path to the executed python script without being effected by the current working directory
# example script located at /usr/bin/foo.py
print(__file__)
output:
/usr/bin/foo.py

How to avoid python running file in the directory where the code is located?

I'm writing a script that will download an executable from the internet, which will create more files. Now, if I download the file, it will be downloaded to the directory I told it, but when I open it using os.startfile(), it creates the files to the directory where the python script is located. How can I avoid that?
Either you can move the .py file to any other directory.
or
You can use os.chdir() to change the current working directory of the script during the runtime.
os.chdir('/path/to/directory')
Do a os.chdir() before trying to run the executable:
os.chdir('<the target folder where you want the files to be created>')
...
os.startfile('<path to where the executable was downloaded>')

Setting working direction to direction of the script in Python (pyinstaller)

I have a pretty simple script that takes data from some .csv or .db files, performs manipulations and saves output in the similar files. I am working from Spyder with the parameter "Run in the directory of the file", so when I run the file my wd is set to file's directory automatically. SO that I put all files in one folder and do not mess with paths (e.g. using always open("data.csv")). And my files are stored like:
/Users/username/docs/script.py
/Users/username/docs/data.cv
/Users/username/docs/database.db
I've tried to use pyinstaller to that colleagues could you the script easily as well, but any time they would run it, it would set the working directory to /Users/username/ and all relative paths are getting broken.
How could I preserve this issue, so that the script (pyinstaller shell script) would be taking as working directory the folder with its location, like Spyder is doing?
Instead of using plain open('data.csv'), you should use a snippet like the following:
import os
import sys
if getattr(sys, 'frozen', False):
base_dir = sys._MEIPASS
else:
base_dir = os.path.abspath(os.path.dirname(__file__))
file = open(os.path.join(base_dir, 'data.csv'))
Then, when building you include your data files with --add-data=data.csv;.. Please use a colon (:) instead of a semi-colon (;) when not on Windows. If you're on Windows and using PowerShell, then escape the semi-colon with a backtick (`).
You can use the getcwd() function in os module to get the location of the current working directory. Then open the files like this.
open(os.getcwd()+'/data.csv')

How do I change my default working directory for Python (Anaconda) on VSCode?

So I have been trying to open very basic files like this: inputFile = open("keywords.txt", "r")
But I get this error:
FileNotFoundError: [Errno 2] No such file or directory: 'keywords.txt'
This must be because Python's default working directory is not the one where my .py file is (correct me if i'm wrong).
How can I find the exact path of the directory I'm working in and then change Python's default working directory to it?
Note: I'm on OSX Mojave using VSCode and Anaconda (Python 3.6)
We have to distinguish the two notions: the "working directory" and the "python environment".
When you go into VS code from Anaconda, then you are in an Anaconda virtual python environment and it's default directory.
You can test it with upon-left first icon - "Explorer".
Here you will find a directory structure, where your .py file actually is.
But sometimes the file what the .py searching for could be in some quite other directory. If you want to run a python program with some additional files stored in a common directory, then I prefer to use some variable to set the working directory:
work_dir = "path/to/working_directory"
The use
import os
path = os.join(work_dir, somefile.txt)
If the files the python program uses are in a complex directory structure, then changing the working directory won't be a solution.
Though when the programmer uses relative paths, it can be.
In VS Code has a terminal where you can check the current Anaconda environment and directory in a bash shell manner.
When you run the program you will see what environment and options your .py file is actually running in and with.
By default Python's "current working directory" is the folder which it is placed in. Though this might be different when using Anaconda
This will print your current directory
import os
print(os.getcwd())
This will change your directory
os.chdir('Your new file path here')
Then do another print(os.getcwd()) to make sure it worked

How can Python get the path to a directory of images when packaging a script?

Here is my script:
current_directory=os.path.abspath(os.curdir)
self.image_array = glob.glob(os.path.join(current_directory,"./data/world_flag_game/flags/*.png")
This works fine when I run it (using quickly) from the terminal but when I package it (using quickly package) it seems that the path is not working.
If the path is not working, it probably isn't the path where the .png images are located. Try printing the path from the terminal as well as from your packaged application. Something like the following will help you to see why the images are not found.
print("%r" % current_directory)
It's not surprising that the application's build directory would be different than its development directory. So you may want to replace your os.path.join(...) with an absolute directory to verify that your application works when packaged. Then it's a matter of storing your images into the build directory and then pointing to that location correctly.

Categories