I am writing a program that prompts for the name of the directory and then saves all the file names in a list. How can I get a path to a specific directory obly knowing its name?
I tried os.path.dirname(os.path.realpath(__file__)) but it would only show me my current dir, where the file with the program is, not the searchable dir.
__file__ is a special variable in python that includes the current file's path. If understand your question correctly, then all you need is to pass the variable where you have stored user input from the prompt in place of __file__. So you will have something like:
print("what dir do you want to search?")
searchable_dir = input()
print(
"You selected " +
os.path.dirname(os.path.realpath( searchable_dir ))
)
This is good as a learning exercise, but note that to get a list of files in a directory the preferred method would be to use os.listdir.
Related
import os
print("enter folder name")
FolderName = input()
flag = os.path.isabs(FolderName)
if flag == False:
path = os.path.abspath(FolderName)
print("The absolute path is: " ,path)
What am I doing wrong here? Let's say the Folder name input is Neon.
The code output gives C:\Users\Desktop\Codes\Neon\Neon
Instead what I want is: C:\Users\Desktop\Codes\Neon\
The os.path.abspath function normalizes the users current working directory and the input argument and then merges them together.
So if your input is 'Neon' and your current working directory is C:\Users\Desktop\Codes\Neon, then the output is C:\Users\Desktop\Neon\Neon.
Likewise if your input is fkdjfkjdsk then the output would be C:\Users\Desktop\Neon\fkdjfkjdsk.
If you are looking for a way to get the absolute path of the current directory you can use:
os.getcwd()
For the official definition:
os.path.abspath(path)
Return a normalized absolutized version of the pathname path. On most platforms, this is equivalent to calling the function normpath() as follows: normpath(join(os.getcwd(), path)).
You are probably running your code when you are at the C:\Users\Desktop\Codes\Neon\ directory
Therefore, when you run os.path.abspath("Neon"), the function is assuming you are trying to refer to a file in the current directory, and returns C:\Users\Desktop\Codes\Neon\Neon.
If you want to have the absolute path of the current directory, use:
os.path.abspath(".")
Most of the function inside the path module of the os library doesn't perform file/directory presence checks before performing operations. i.e., It is probable that if you enter the path to a filesystem object that doesn't exist, the function would still return a result for it.
Your current working directory of the Python file is not the one you expect.
Previous answers have covered the liability of the abspath function. The following code would produce the desired output (only for your case).
import os
os.chdir(r"C:\Users\Desktop\Codes")
print("enter folder name")
FolderName = input()
flag = os.path.isabs(FolderName)
if flag == False:
path = os.path.abspath(FolderName)
print("The absolute path is: " ,path)
But if you want to be sure, first display the current working directory to assure that the parent directory is the correct one. Also, include some directory presence functions within the code (such as isdir) in the code to assure that the directory name provided as input is real.
We are creating a python program that executes specific macros within Polyworks based on user input into the program. Right now the code is:
roto.command.CommandExecute('MACRO EXEC("C:\\RotoWorks\\Macros\\CentrifugalCompressor")')
However this assumes that our program is always installed in C:\RotoWorks. Ideally, our app is portable. I'm sure theres a way to retrieve the filepath that Rotoworks is stored in, then just concatenate the rest of the filepath to the end. How do I do this?
You can retrieve the path from the __file__ attribute of the file. Use os.path.abspath on that attribute to retrieve the absolute path of the file and then os.path.dirname to retrieve the containing directory:
import os
file_directory = os.path.dirname(os.path.abspath(__file__))
path = os.path.join(file_directory, other_path) # join directory to an inner path
roto.command.CommandExecute('MACRO EXEC({})'.format(path))
Use os.path.dirname recursively to move out as many directories as you want.
I'm using Glob.Glob to search a folder, and the sub-folders there in for all the invoices I have. To simplify that I'm going to add the program to the context menu, and have it take the path as the first part of,
import glob
for filename in glob.glob(path + "/**/*.pdf", recursive=True):
print(filename)
I'll have it keep the list and send those files to a Printer, in a later version, but for now just writing the name is a good enough test.
So my question is twofold:
Is there anything fundamentally wrong with the way I'm writing this?
Can anyone point me in the direction of how to actually capture folder path and provide it as path-variable?
You should have a look at this question: Python script on selected file. It shows how to set up a "Sent To" command in the context menu. This command calls a python script an provides the file name sent via sys.argv[1]. I assume that also works for a directory.
I do not have Python3.5 so that I can set the flag recursive=True, so I prefer to provide you a solution which you can run on any Python version (known up to day).
The solution consists in using calling os.walk() to run explore the directories and the set build-in type.
it is better to use set instead of list as with this later one you'll need more code to check if the directory you want to add is not listed already.
So basically you can keep two sets: one for the names of files you want to print and the other one for the directories and their sub folders.
So you can adapat this solution to your class/method:
import os
path = '.' # Any path you want
exten = '.pdf'
directories_list = set()
files_list = set()
# Loop over direcotries
for dirpath, dirnames, files in os.walk(path):
for name in files:
# Check if extension matches
if name.lower().endswith(exten):
files_list.add(name)
directories_list.add(dirpath)
You can then loop over directories_list and files_list to print them out.
I'm doing a Python course on Udacity. And there is a class called Rename Troubles, which presents the following incomplete code:
import os
def rename_files():
file_list = os.listdir("C:\Users\Nick\Desktop\temp")
print (file_list)
for file_name in file_list:
os.rename(file_name, file_name.translate(None, "0123456789"))
rename_files()
As the instructor explains it, this will return an error because Python is not attempting to rename files in the right folder. He then proceeds to check the "current working directory", and then goes on to specify to Python which directory to rename files in.
This makes no sense to me. We are using the for loop to specifically tell Python that we want to rename the contents of file_list, which we have just pointed to the directory we need, in rename_files(). So why does it not attempt to rename in that folder? Why do we still need to figure out cwd and then change it?? The code looks entirely logical without any of that.
Look closely at what os.listdir() gives you. It returns only a list of names, not full paths.
You'll then proceed to os.rename one of those names, which will be interpreted as a relative path, relative to whatever your current working directory is.
Instead of messing with the current working directory, you can os.path.join() the path that you're searching to the front of both arguments to os.rename().
I think your code needs some formatting help.
The basic issue is that os.listdir() returns names relative to the directory specified (in this case an absolute path). But your script can be running from any directory. Manipulate the file names passed to os.rename() to account for this.
Look into relative and absolute paths, listdir returns names relative to the path (in this case absolute path) provided to listdir. os.rename is then given this relative name and unless the app's current working directory (usually the directory you launched the app from) is the same as provided to listdir this will fail.
There are a couple of alternative ways of handling this, changing the current working directory:
os.chdir("C:\Users\Nick\Desktop\temp")
for file_name in os.listdir(os.getcwd()):
os.rename(file_name, file_name.translate(None, "0123456789"))
Or use absolute paths:
directory = "C:\Users\Nick\Desktop\temp"
for file_name in os.listdir(directory):
old_file_path = os.path.join(directory, file_name)
new_file_path = os.path.join(directory, file_name.translate(None, "0123456789"))
os.rename(old_file_path, new_file_path)
You can get a file list from ANY existing directory - i.e.
os.listdir("C:\Users\Nick\Desktop\temp")
or
os.listdir("C:\Users\Nick\Desktop")
or
os.listdir("C:\Users\Nick")
etc.
The instance of the Python interpreter that you're using to run your code is being executed in a directory that is independent of any directory for which you're trying to get information. So, in order to rename the correct file, you need to specify the full path to that file (or the relative path from wherever you're running your Python interpreter).
1) The below statement works fine
test_suite_name = [name for name in os.listdir(".") if (os.path.isdir(name))]
but I need to see the directories inside "./squish".
test_suite_name = [name for name in os.listdir("./Squish") if (os.path.isdir(name))]
but this statement is not working... please tell me how can i correct it, i think some correction is needed for the if statement.
2) Also what script format i should use to display the folder which begins with "test_" say,
i have many folders, some are prifixed with "test_", these folders can be in folder structure above or below where the script is placed.
the "test_" folders can be any where under /xyz/abc folder which can be folder any where above or below where the python script is sitting
For question number one:
test_suite_name = [name for name in os.listdir("./Squish") if os.path.isdir(os.path.join("./Squish", name))]
As for your second question, there are two things you can do:
1) Use the full path; for example: r'C:\Windows\System32\calc.exe'
2) Say your script is located in C:\Documents and Settings\User\Desktop, and you want to specify file log.txt that is located in the C:\Documents and Settings folder.
You can use '..' to specify the parent direcotory of your current location. So if you are in C:\Documents and Settings\User\Desktop, then r'..\..\log.txt' will refer to C:\Documents and Settings\log.txt
1) The problem is, that name is just the name of the subdirectory, i.e. test and not ./Squish/test.
use os.path.isdir(os.path.join('.', 'Squish', name)) instead.
In case you look up folders in ., it is no proble because isdir looks in the current directory given a relative path.
2) you can extend your list comprehension to
[name for name in (...) if os.path.isdir(...) and name.startswith('test_')]
You see, the name variable in the iterator contains a particular file or directory name only, not the whole path. So,
path = './Squish'
dirs = [name for d in os.listdir(path)
if os.path.isdir(os.path.join(path, name))]
should do.
Note, that you have to sort the list manually (e.g. via sorted(dirs) ) due to the nature of os.listdir().