easygui fileopenbox: open a path with a '.' (ex C:\Users\user\.atom) - python

I would like to open a file dialog with easygui but the path contains a folder with a .: C:\Users\user\.atom
myfile= easygui.fileopenbox(msg="Choose a file", default=r"C:\Users\user\.atom")
This opens the dialog box to C:\Users\user not C:\Users\user\.atom

I didn't / don't use easygui, just looked at the source code.
easygui does some path processing on the default argument. That processing involves [Python]: os.path.split(path) which splits the path in 2 parts (what comes before and after the last path separator (bkslash or "\")).
Since ".atom" comes after the last "\", it's not considered as part of the path (the fact that it contains a "." is just a coincidence and has nothing to do with it).
To fix your problem, add a wildcard to your path, e.g.:
myfile = easygui.fileopenbox(msg="Choose a file", default=r"C:\Users\user\.atom\*")

Another solution is to end default with two \\:
r"C:\Users\user\.atom\\"

Related

How to ignore system/hidden directories when using os.listdir?

When I am using os.listdir() to analyze a content of a zip file, I often get unexpected system directories like __MACOSX. I know I just can write a function to ignore __MACOSX but I need a more sophisticated solutions . I need all hidden directories from whatever operating system (MAC OS, windows or linux) to be automatically ignored.
Any suggestion ?
Hidden Files start with ".", so you can remove filename that starts with "."
import os
for f in os.listdir('Your_path'):
if not f.startswith('.'):
print(f)

Subprocess doesn't open the correct directory

I'm running a script which prompts the user to select a directory, saves a plot to that directory and then uses subprocess to open that location:
root = Tkinter.Tk()
dirname = tkFileDialog.askdirectory(parent=root,initialdir="/",title='Please select a directory')
fig.savefig(dirname+'/XXXXXX.png',dpi=300)
plt.close("all")
root.withdraw()
subprocess.Popen('explorer dirname')
When I run the file I select a sub-directory in D:\Documents and the figure save is correct. However the subprocess simply opens D:\Documents as opposed to D:\Documents\XXX.
Ben
To open a directory with the default file explorer:
import webbrowser
webbrowser.open(dirname) #NOTE: no quotes around the name
It might use os.startfile(dirname) on Windows.
If you want to call explorer.exe explicitly:
import subprocess
subprocess.check_call(['explorer', dirname]) #NOTE: no quotes
dirname is a variable. 'dirname' is a string literal that has no relation to the dirname name.
You are only passing the string 'dirname' not the variable that you have named dirname in your code. Since you (presumably) don't have a directory called dirname on your system, explorer opens the default (Documents).
You may also have a problem with / vs \ in directory names. As shown in comments, use os.path module to convert to the required one.
You want something like
import os
win_dir = os.path.normpath(dirname)
subprocess.Popen('explorer "%s"' %win_dir)
or
import os
win_dir = os.path.normpath(dirname)
subprocess.Popen(['explorer', win_dir])
Add ,Shell=True after 'explorer dirname'
If Shell is not set to True, then the commands you want to implement must be in list form (so it would be ['explorer', ' dirname']. You can also use shlex which helps a lot if you don't want to make Shell = True and don't want to deal with lists.
Edit: Ah I miss read the question. often you need a direct path to the directory, so that may help.

Accessing file path in the os

The following line, unless I'm mistaken, will grab the absolute path to your directory so you can access files
PATH = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0])))
This is what I've been using typically access files in my current directory when I need to use images etc in the programs i've been writing.
Now, say I do the following since I'm using windows to access a specific image in the directory
image = PATH + "\\" + "some_image.gif"
This is where my question lies, this works on windows, but if I remember correctly "\\" is for windows and this will not work on other OS? I cannot directly test this myself as I don't have other operating systems or I wouldn't have bothered posting. As far as I can tell from where I've looked this isn't mentioned in the documentation.
If this is indeed the case is there a way around this?
Yes, '\\' is just for Windows. You can use os.sep, which will be '\\' on Windows, ':' on classic Mac, '/' on almost everything else, or whatever is appropriate for the current platform.
You can usually get away with using '/'. Nobody's likely to be running your program on anything but Windows or Unix. And Windows will accept '/' pathnames in most cases. But there are many Windows command-line tools that will confuse your path for a flag if it starts with /, and some even if you have a / in the middle, and if you're using \\.\ paths, a / is treated like a regular character rather than a separator, and so on. So you're better off not doing that.
The simple thing to do is just use os.path.join:
image = os.path.join(PATH, "some_image.gif")
As a side note, in your first line, you're already using join—but you don't need it there:
PATH = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0])))
It's perfectly legal to call join with only one argument like this, but also perfectly useless; you just join the one thing with nothing; you will get back exactly what you passed in. Just do this:
PATH = os.path.abspath(os.path.dirname(sys.argv[0]))
One last thing: If you're on Python 3.4+, you may want to consider using pathlib instead of os.path:
PATH = Path(sys.argv[0]).parent.resolve()
image = PATH / "some_image.gif"
Use os.path.join instead of "\\":
os.path.join(PATH, "some_image.gif")
The function will join intelligently the different parts of the path.
PATH = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0])))
image = os.path.join(PATH, "some_image.gif")
os.path.join will intelligently join the arguments using os.sep which uses the OS file separator for you.

How to process files from one subfolder to another in each directory using Python?

I have a basic file/folder structure on the Desktop where the "Test" folder contains "Folder 1", which in turn contains 2 subfolders:
An "Original files" subfolder which contains shapefiles (.shp).
A "Processed files" subfolder which is empty.
I am attempting to write a script which looks into each parent folder (Folder 1, Folder 2 etc) and if it finds an Original Files subfolder, it will run a function and output the results into the Processed files subfolder.
I made a simple diagram to showcase this where if Folder 1 contains the relevant subfolders then the function will run; if Folder 2 does not contain the subfolders then it's simply ignored:
I looked into the following posts but having some trouble:
python glob issues with directory with [] in name
Getting a list of all subdirectories in the current directory
How to list all files of a directory?
The following is the script which seems to run happily, annoying thing is that it doesn't produce an error so this real noob can't see where the problem is:
import os, sys
from os.path import expanduser
home = expanduser("~")
for subFolders, files in os.walk(home + "\Test\\" + "\*Original\\"):
if filename.endswith('.shp'):
output = home + "\Test\\" + "\*Processed\\" + filename
# do_some_function, output
I guess you mixed something up in your os.walk()-loop.
I just created a simple structure as shown in your question and used this code to get what you're looking for:
root_dir = '/path/to/your/test_dir'
original_dir = 'Original files'
processed_dir = 'Processed files'
for path, subdirs, files in os.walk(root_dir):
if original_dir in path:
for file in files:
if file.endswith('shp'):
print('original dir: \t' + path)
print('original file: \t' + path + os.path.sep + file)
print('processed dir: \t' + os.path.sep.join(path.split(os.path.sep)[:-1]) + os.path.sep + processed_dir)
print('processed file: ' + os.path.sep.join(path.split(os.path.sep)[:-1]) + os.path.sep + processed_dir + os.path.sep + file)
print('')
I'd suggest to only use wildcards in a directory-crawling script if you are REALLY sure what your directory tree looks like. I'd rather use the full names of the folders to search for, as in my script.
Update: Paths
Whenever you use paths, take care of your path separators - the slashes.
On windows systems, the backslash is used for that:
C:\any\path\you\name
Most other systems use a normal, forward slash:
/the/path/you/want
In python, a forward slash could be used directly, without any problem:
path_var = '/the/path/you/want'
...as opposed to backslashes. A backslash is a special character in python strings. For example, it's used for the newline-command: \n
To clarify that you don't want to use it as a special character, but as a backslash itself, you either have to "escape" it, using another backslash: '\\'. That makes a windows path look like this:
path_var = 'C:\\any\\path\\you\\name'
...or you could mark the string as a "raw" string (or "literal string") with a proceeding r. Note that by doing that, you can't use special characters in that string anymore.
path_var = r'C:\any\path\you\name'
In your comment, you used the example root_dir = home + "\Test\\". The backslash in this string is used as a special character there, so python tries to make sense out of the backslash and the following character: \T. I'm not sure if that has any meaning in python, but \t would be converted to a tab-stop. Either way - that will not resolve to the path you want to use.
I'm wondering why your other example works. In "C:\Users\me\Test\\", the \U and \m should lead to similar errors. And you also mixed single and double backslashes.
That said...
When you take care of your OS path separators and trying around with new paths now, also note that python does a lot of path-concerning things for you. For example, if your script reads a directory, as os.walk() does, on my windows system the separators are already processed as double backslashes. There's no need for me to check that - it's usually just hardcoded strings, where you'll have to take care.
And finally: The Python os.path module provides a lot of methods to handle paths, seperators and so on. For example, os.path.sep (and os.sep, too) wil be converted in the correct seperator for the system python is running on. You can also build paths using os.path.join().
And finally: The home-directory
You use expanduser("~") to get the home-path of the current user. That should work fine, but if you're using an old python version, there could be a bug - see: expanduser("~") on Windows looks for HOME first
So check if that home-path is resolved correct, and then build your paths using the power of the os-module :-)
Hope that helps!

Maya python back slash replacing issue

I am Trying to add a custom path filed in my GUI but the problem is that when i use the command
cmds.fileDialog2(filemode=3,dialogStyle =1)
i get a file path like
C:\Users\anoorani\Desktop\Test
However Maya only seems to be reading paths like
C:/Users/anoorani/Desktop/Test
The backticks seem to be a problem
is there a way to replace "\" with "/" in python maya.....?
Acording to #ArgiriKotsaris note, you can use os.path.normpath(path):
Normalize a pathname by collapsing redundant separators and up-level references.
So that A//B, A/B/, A/./B and A/foo/../B all become A/B.
This string manipulation may change the meaning of a path that contains symbolic links.
On Windows, it converts forward slashes to backward slashes.
So your code be:
import maya.cmds as cmds
import os
path = cmds.fileDialog2(fm=3,dialogStyle =1)
path = path and os.path.normpath(path[0])
Or if you want to always using forward slashes, then no needs to os module and change last line to:
path = path and path[0].replace('\\', '/')
Note that name of file mode argument for fileDialog2 is fileMode or fm and not filemode.
Also fileDialog2 return a list of paths or None.

Categories