I'm a noob at coding Python and I've run into something that no amount of Googling is helping me with.
I'm trying to write a simple Directory listing tool and I cannot seem to deal with Spaces in the directory name in OSX.
My code is as follows:
def listdir_nohidden(path):
import os
for f in os.listdir(path):
if not f.startswith('.'):
yield f
def MACListDirNoExt():
import os
MACu = PCu = os.environ['USER']
MACDIR = '/Users/'+MACu+'/Desktop//'
while True:
PATH = raw_input("What is the PATH you would like to list?")
if os.path.exists(PATH):
break
else:
print "That PATH cannot be found or does not exist."
NAME = raw_input ("What would you like to name your file?")
DIR = listdir_nohidden(PATH)
DIR = [os.path.splitext(x)[0] for x in DIR]
f = open(''+MACDIR+NAME+'.txt', "w")
for file in DIR:
f.write(str(file) + "\n")
f.close()
print "The file %s.txt has been written to your Desktop" % (NAME)
raw_input ("Press Enter to exit")
For ease of trouble shooting though I think this could essentially be boiled down to:
import os
PATH = raw_input("What is the PATH you would like to list")
os.listdir(PATH)
When supplying a directory path that contains spaces /Volumes/Disk/this is a folder it returns
"No such file or Directory: '/Volumes/Disk/this\\ is\\ a\\ folder/'
It looks like its escaping the escape...?
Check the value returned from raw_input() for occurences of '\\' and replace them with ''.
a = a.replace('\\', '')
I just ran into this, and I'm guessing that what I was hastily doing is also what you were trying. In a way, both #zwol and #trans1st0r are right.
Your boiled down program has nothing wrong with it. I believe that if you put in the input /Volumes/Disk/this is a folder, everything would work fine.
However, what you may have been doing (or at least, what I was doing) is dragging a folder from the Finder to the Terminal. When you drag to the Terminal, the OS automatically escapes spaces for you, so what ends up getting typed into the Terminal is /Volumes/Disk/this\ is\ a\ folder.
So either you can make sure that what you "type in" doesn't have those backslashes, or you can use #trans1st0r's suggestion as a way to support the dragging functionality, though the latter will cause issues in the edge case that your desired path actually has backslashes in it.
Related
I made a Python program that reads all the files in a directory who's path is inputted and then does some things to them and outputs some things into a .txt file.
I used os.walk to read the files in the directory
def dir_read(pathName = str(), fileList=[]): #fileList is output
cur_dir = [i[2] for i in os.walk(pathName)] #current directory
for i in cur_dir:
for j in i:
fileList.append(j)
and then checking for correctly inputted paths like this
fileList=[]
while True:
dir_read(pathName, fileList) #FUNCTION CALL
if not fileList: #if it is empty
print("The path is written incorrectly, is empty or does not exist. Please re-enter now or "
"close the program and enter it inside PATH.txt:")
pathName = str(input())
else:
break #if the list is not empty (the path is entered correctly) the while loop breaks
However if I enter something like This PC\Nokia 6.1\Card SD it keeps giving me the error message. Also I noticed same thing happens with things like Desktop or Documents. But if I enter something like C:\Program Files (x86)\Notepad++ it works perfectly.
I tried replacing \ with / as well and it doesn't work.
My phone doesn't have a specific drive like F: as you can see here: https://imgur.com/a/Educ5RJ
I am using Windows 10.
How do I fix this?
I believe your directory should be like this:
on Linux:
media/This PC/Nokia 6.1/Card SD
on Windows:
You need to know the drive letter you can run this command:
C:\>wmic logicaldisk where drivetype=2 get deviceid, volumename, description
let's say it returned X:
then your directory should be something like this:
X:\Nokia 6.1\Card SD
I'm not sure if you are supposed to remove the Nokia 6.1 or not
try Using subst command and if you have spaces on your device's name put it on quotes
Ex:
subst E: "The Name Goes Here"
I have a program that relies on user input to enter files for the program to open in Python 2.7.11. I have all of those files in a sub-directory called TestCases within the original directory Detector, but I can't seem to access the files in TestCases when running the program from the super-directory. I tried to use os.path.join but to of no avail. Here is my code:
import os.path
def __init__(self):
self.file = None
os.path.join('Detector', 'TestCases')
while self.file == None:
self.input = raw_input('What file to open? ')
try:
self.file = open(self.input, 'r')
except:
print "Can't find file."
My terminal when I run the program goes as follows:
>>> What file to open? test.txt # From the TestCases directory
>>> Can't find file.
>>> What file to open? ...
Am I using os.path.join incorrectly? I thought it was supposed to link the two directories so that files could be accessed from the sub-directory while running the program from the super-directory.
You are using os.path.join('Detector', 'TestCases'), that should return 'Detector/TestCases', but you aren't storing that variable anywhere.
I suppose that you are in Detector directory and you want to open files in TestCases. I that case you can use path join (It concatenates its arguments and RETURNS the result):
import os.path
file = None
while not file:
input = raw_input('What file to open? ')
try:
filepath = os.path.join('TestCases', input)
file = open(filepath, 'r')
except IOError:
print "Can't find " + input
I have stored the result of os.path.join so you could see that it doesn't change the directory, it just concatenates its arguments, maybe you was thinking that function will change the directory, you can do it with os.chdir.
Try it first in a simple script or in the terminal, it will save many headaches.
The documentation about os.path.join
Join one or more path components intelligently. The return value is the concatenation of path...
It seems like you expect it to set some kind of PATH variable or affect the current working directory. For a first start it should be sufficient to add something like this to your code:
open(os.path.join("TestCases",self.input), 'r')
import os
searchFolder = input('Which folder would you like to search?')
def search(folder):
for foldername, subfolders, filenames in os.walk(folder):
for filename in filenames:
if os.path.getsize(filename) > 1000:
print(str(os.path.abspath(filename)) + 'is ' + str(os.path.getsize(filename)))
else:
continue
search(searchFolder)
This program is meant to ask the user for a string, iterate over the files in that directory, and print the abs path and file size of every item over a certain size. I'm getting a FileNotFoundError: [WinError 2] when I run this code, on any directory. I'm inputting the directory with escaped backslashes. I think this is such a rudimentary error on my part that this is all the info anyone would need but let me know if there's anything else that would be helpful. Thanks!
In the filename for loop you have only passed the filename but not the complete path. If you write:
if os.path.getsize(foldername+"/"+filename) > 1000:
This works for linux. For Windows you need to use \ or \\instead of /. So now you understand why it isn't working. You should use the full filepath or relative path while adding a path.
Working code in linux:
import os
searchFolder = input('Which folder would you like to search? ')
def search(folder):
for foldername, subfolders, filenames in os.walk(folder):
for filename in filenames:
if os.path.getsize(foldername+"/"+filename) > 1000:
print(str(os.path.abspath(filename)) + ' is ' + str(os.path.getsize(foldername+"/"+filename)))
else:
continue
search(searchFolder)
Input() will return the string that the user writes. You don't have to escape backslashes. So just input it as C:\path\to\my\folder\. It's when you write windows paths in your python source code that you must escape your backslashes or use r"raw string".
You can use os.path.isdir() to check that python actually accepts the path, and print an error if the path could not be found.
searchFolder = input('Which folder would you like to search?')
if os.path.isdir(searchFolder):
search(searchFolder)
else:
print("the folder %s was not found" % searchFolder)
I tested the code and it works fine, I used for my test. ./
Python accepts both path types:
path = "C:/" # unix
and
path = "C:\\" # windows
for input try ./ , which will search the directory the program is in.
So, you have two options, relative pathing or absolute pathing.
More on pathing.
Although as was mentioned, for anything outside of the programs directory you need to correct the line
if os.path.getsize(filename) > 1000:
to
if os.path.getsize(foldername+"/"+filename) > 1000:
Whenever you want to insert any path, just add an r before the path. This is Python's raw string notation. i.e; backslashes are not handled in any special way in a string literal prefixed with r
So, if you want to add a path to a file called foo in C:\Users\pep\Documents
Just give your path as
my_path = r'C:\Users\pep\Documents\foo'
You don't need to bother escaping any backslashes now.
I'm writing a script to save a file and giving the option of where to save this file. Now if the directory entered does NOT exist, it breaks the code and prints the Traceback that the directory does not exist. Instead of breaking the code I'd love to have have a solution to tell the user the directory they chose does not exist and ask again where to save the file. I do not want to have this script make a new directory. Here is my code:
myDir = input('Where do you want to write the file?')
myPath = os.path.join(myDir, 'foobar.txt')
try:
f = open(myPath, 'w')
except not os.path.exists(myDir):
print ('That directory or file does not exist, please try again.')
myPath = os.path.join(myDir, 'foobar.txt')
f.seek(0)
f.write(data)
f.close()
This will get you started however I will note that I think you need to tweak the input statement so the user does not have to put quotes in to not get an invalid syntax error
import os
myDir = input("Where do you want to write the file ")
while not os.path.exists(myDir):
print 'invalid path'
myDir = input("Where do you want to write the file ")
else:
print 'hello'
I do not know what your programming background is - mine was SAS before I found Python and some of the constructions are just hard to think through because the approach in Python is so much simpler without having a goto or similar statement but I am still trying to add a goto approach and then someone reminds me about how the while and while not are simpler, easier to read etc.
Good luck
I should add that you really don't need the else statement I put it there to test/verify that my code would work. If you expect to do something like this often then you should put it in a function
def verify_path(some_path_string):
while not os.path.exists(some_path_string):
print 'some warning message'
some_path_string = input('Prompt to get path')
return some_path_string
if _name_ == main:
some_path_string = input("Prompt to get path")
some_path_string = verify_path(some_path_string)
I wrote my first program in Python for my dad to convert about 1000 old AppleWorks files that he has (the AppleWorks format, .cwk, is no longer supported) to .docx. To clarify, the program does not actually convert anything, all it does is copy/paste whatever text is in the documents you specify to another document of any file-type you want.
The program works fine on my Windows Laptop, however it encounters problems in my dad's Mac laptop.
File-path in Windows is indicated with a \ whereas in Mac it's /. So when the program reaches the copy and paste variables it stops working if the slash in the respective string is the wrong way around.
Is there a way to get Python to dynamically add on the Input and Output folders to my copy and paste variables depending on the OS without the use of strings?
If there are any other improvements you can see, feel free to say so, I am interested in releasing this as Freeware, possibly with the tKinter GUI and want to make as user friendly as possible.
As it stands the program does have some problems (converting apostrophe's into omega symbols and the like). Feel free to try the program and see if you can improve it.
import os, os.path
import csv
from os import listdir
import sys
import shutil
path, dirs, files = os.walk(os.getcwd() + '/Input').next()
file_count = len(files)
if file_count > 0:
print "There are " + str(file_count) + " files you have chosen to convert."
else:
print "Please put some files in the the folder labelled 'Input' to continue."
ext = raw_input("Please type the file extension you wish to convert to, making sure to preceed your selection with '.' eg. '.doc'")
convert = raw_input("You have chosen to convert " + str(file_count) + " files to the " + ext + " format. Hit 'Enter' to continue.")
if convert == "":
print "Converter is now performing selected tasks."
def main():
dirList = os.listdir(path)
for fname in dirList:
print fname
# opens files at the document_input directory.
copy = open(os.getcwd() + "\Input\\" + fname, "r")
# Make a file called test.docx and stick it in a variable called 'paste'
paste = open(os.getcwd() + "\Output\\" + fname + ext, "w+")
# Place the cursor at the beginning of 'copy'
copy.seek(0)
# Copy all the text from 'copy' to 'paste'
shutil.copyfileobj(copy,paste)
# Close both documents
copy.close()
paste.close()
if __name__=='__main__':
main()
else:
print "Huh?"
sys.exit(0)
Please let me know if I wasn't clear or left out some info...
Use os.path.join
For example, you could get the path of the Input subdirectory with
path = os.path.join(os.getcwd(), 'Input')
os.path.join is the platform-independent way to join paths:
>>> os.path.join(os.getcwd(), 'Input', fname)
'C:\\Users\\Blender\\Downloads\\Input\\foo.txt'
And on Linux:
>>> os.path.join(os.getcwd(), 'Input', fname)
'/home/blender/Downloads/Input/foo.txt'