Python open only one directory that starts with specific numbers - python

I want to be able to open directories by only typing first digits of the directory number.
In C:/Orders/ I have a couple of directories:
40_0
125_15
4012_0
4040_127
5445_0
4_67
If I type in the input "4012" it opens the 4012 directory, but when I type "4" it opens all directories that start with 4, I need to open only one.
Also, when I type some numbers that don't match any existing directory, it prints("Nothing found") as many times as many directories are in current directory. I have no clue how to solve this.
This is what I tried:
os.chdir("C:/Orders")
while True:
orderNo = input("Type order number: ")
for filename in os.listdir():
if filename.startswith(orderNo):
os.startfile(filename)
else:
print("Nothing found.")

The following should print the first one that match and print only once in case of non match the "Nothing found."
while True:
orderNo = input("Type order number: ")
for filename in os.listdir():
if filename.startswith(orderNo):
os.startfile(filename)
break
else:
print("Nothing found.")
#Pay attention to where the else is put. This is a nice feature of python (the for else)

you may use:
from pathlib import Path
from glob import glob
subfolders = list(map(Path, glob('"C:/Orders/*/')))
name_subfolder = {p.name : p for p in subfolders}
orderNo = input("Type order number: ")
while orderNo != 'exit':
f = (e for e in name_subfolder.keys() if e.startswith(orderNo))
try:
os.startfile(next(f))
except StopIteration:
print("Nothing found.")
orderNo = input("Type order number: ")
you are taking all the subfolders and build a dict name_subfolders who has as key the name of each subfolder and the absolute path, then you can take input and check if any subfolder name starts with a given input if is the case then will open your folder for you if not will give you a not found message

Related

Why os.path.isdir() or os.path.existis() always return False

I am using a function to test if a directory entered by user is valid or not. The user input doesn't go to the file name, it only goes to the folder name e.g. "C:/Users/username/Desktop/folder". So I wrote the following function to get the path/directory:
def get_path():
while True:
file_path = input("Please enter file path (up to folder level); q to quit:> ")
print(repr(file_path))
if os.path.isdir(file_path):
return file_path
elif file_path.lower() == 'q':
sys.exit()
else:
print("The path you entered is invalid.")
continue
However, it always shows The path you entered is invalid. even though the path/string I entered is valid when running the os.path.isdir() in cmd.
Running the function on my Win10 cmd generates the following results
>>> import sys
>>> import os
>>> import pathlib
>>> def get_path():
... while True:
... file_path = input("Please enter file path (up to folder level); q to quit:> ")
... print(repr(file_path))
... if os.path.isdir(file_path):
... return file_path
... elif file_path.lower() == 'q':
... sys.exit()
... else:
... print("The path you entered is invalid.")
... continue
...
>>> path = get_path()
Please enter file path (up to folder level); q to quit:> "C:/Users/myname/Desktop/"
'"C:/Users/myname/Desktop/"'
The path you entered is invalid.
Please enter file path (up to folder level); q to quit:> "C:/Users/myname/Desktop/randomprojects"
'"C:/Users/myname/Desktop/randomprojects"'
The path you entered is invalid.
Please enter file path (up to folder level); q to quit:>

Python 3.5 OS.Walk for selected folders and include their subfolders

I'm writing a python script where I search a specific string across a tree directory. I ask the end-user to define which folders they would like to include in the search, and once the script finds one of the folders that the user would like to scan, the script is supposed to also scan all the sub-folders for this selected folder.
I'm trying to do a couple of for loops, but I can't get it to work.
The beginning of the script looks like:
startTime = datetime.datetime.now()
option = input("Do you want to scan: A) Excel B) PDF C) Both Q) Quit: ")
option = option.lower()
if (option == "b") or (option == "b") or (option == "c"):
stringToSearch = input("Which string do you want to search? ")
folderToSearch = input("Which top folder to search from(i.e. Z:\S 15\BOMs)? ")
subfoldersToSearch = input("Which subfolders(i.e. BOMs, Catalogs? <NO ANSWER = ALL) ")
print("Press CTRL + C to stop the search")
for foldername, subfolders, filenames in os.walk(folderToSearch):
for filename in filenames:
if (subfoldersToSearch == "") or (subfoldersToSearch in foldername):
print(subfoldersToSearch, "+++", foldername)
for x_foldername, x_subfolders, x_filenames in os.walk(foldername):
totalFiles += 1
for x_filename in x_filenames:
if (x_filename.endswith('.pdf') and option == "b") or (x_filename.endswith('.pdf') and option == "c"):
[Do remaining stuff]
The problem is that it gets into a continuous loop because as soon as it's done walking through one of the selected folders, it comes back to the first for loop and it tries to walk the same selected folder again.
Is there a better way to do this os.walk?
Basically, I would like the script to find a specific folder and then scan the contents of that folder (including folders), and then to keep going to the next folder without starting all over again.
I figured it out and it actually works well with just one for loop. Here is how the new code looks and hope it will help someone in the future...Best
startTime = datetime.datetime.now()
option = input("Do you want to scan: A) Excel B) PDF C) Both Q) Quit: ")
option = option.lower()
if (option == "b") or (option == "b") or (option == "c"):
stringToSearch = input("Which string do you want to search? ")
folderToSearch = input("Which top folder to search from(i.e. Z:\S 15\BOMs)? ")
subfoldersToSearch = input("Which subfolders(i.e. BOMs, Catalogs? <NO ANSWER = ALL) ")
print("Press CTRL + C to stop the search")
for foldername, subfolders, filenames in os.walk(folderToSearch, topdown=True):
print(subfolders)
for filename in filenames:
if (subfoldersToSearch == "") or (subfoldersToSearch in foldername):
print(subfoldersToSearch, "+++", foldername)

How can I perform an action if a users input is the name of a file in a directory. Python

I am currently trying to make a program where the user can create sets of data, but I am having a difficult time figuring out how to handle the user picking the user picking a name out of a list of files to edit or view.
Here is how I display the files they can choose from. How can I easily allow them to choose any one of the available files without hardcoding each individual one?
available_files = os.listdir('./DSC_Saves/')
print(available_files)
user_input = input('File Name: ')
What I would like to avoid doing is the following:
if user_input == available_files[0]:
#do action
elif user_input == available_files[1]:
#do action 2
elif user_input == available_files[2]:
#do action 3
As mentioned, you can do this by using in on the list of available files as follows:
available_files = os.listdir('./DSC_Saves/')
print(available_files)
while True:
user_input = input('File name: ')
if user_input in available_files:
break
print("You have selected '{}'".format(user_input))
Alternatively, to make it easier to type, you could present the user with a numeric menu to choose from as follows:
available_files = os.listdir('./DSC_Saves/')
for index, file_name in enumerate(available_files, start=1):
print('{:2} {}'.format(index, file_name))
while True:
try:
user_input = int(input('Please select a file number: '))
if 1 <= user_input <= len(available_files):
selected_file = available_files[user_input-1]
break
except ValueError as e:
pass
print("You have selected '{}'".format(selected_file))
Both solutions will continue prompting until a valid file name has been entered.
So for example you could see the following output:
1 test1.txt
2 test2.txt
Please select a file number: 3
Please select a file number: 2
You have selected 'test2.txt'

odd while loop behavior (python)

I have this code:
class CleanUp:
def __init__(self,directory):
self.directory = directory
def del_items(self,*file_extensions):
"""deletes specified file extensions in specificied directory"""
removed_files = [file for file in os.listdir(self.directory) for ext in file_extensions if ext in file]
for index ,file in enumerate(removed_files):
print(str(index + 1) + ": " + file + "\n")
confirm_delete = input("are you sure you want to delete all {0} files? y|n ".format(len(removed_files)))
while confirm_delete.lower() not in ("y","n"):<--------- this while loop
confirm_delete = input("are you sure you want to delete all {0} files? y|n ".format(len(removed_files)))
if confirm_delete.lower() == "y":
for file in removed_files:
try:
os.remove(os.path.join(self.directory,file))
except:
pass
print("successfully deleted {0} files".format(len(removed_files)))
else:
print("deletion cancelled goodbye")
pass
directory = input("please enter a directory ")
while not os.path.exists(directory):
print("{0} is not a valid directory \n".format(directory))
directory = input("please enter a directory ")
file_extensions = input("please put in file extensions of files that need deleting. seperate them by one space ")
file_extensions = file_extensions.split()
desktop = CleanUp(directory)
deleted_files = desktop.del_items(*file_extensions)
This line works
while confirm_delete.lower() not in ("y","n"):
however, when I try to do
while confirm_delete.lower() != "y" or confirm_delete.lower() != "n":
the while loop never passes.
I'm sure it has something to do with the or but
why doesn't it work when done like that?
Because that condition will always be true; there is no string value which is both "y" and "n" at the same time. Use and instead.

How to write "No file ends with" a user-defined extension

I was wondering if there was a way to tell the user that no file in a directory they specified has the file extension they are looking for. The only way I could think of uses an if/else, but would be tripped up if any other file extension exists in the directory. I was able to find something but it was bash: Listing files in a directory that do not end with vXXX and not exactly what I was looking for.
Here is an example of a directory:
out-30000000.txt.processed
out-31000000.txt.processed
out-32000000.txt.processed
out-33000000.txt.processed
out-34000000.txt.processed
nope.csv
If I use the following code:
def folder_location():
location = raw_input("What is the folder containing the data you like processed located? ")
#location = "C:/Code/Samples/Dates/2015-06-07/Large-Scale Data Parsing/Data Files"
if os.path.exists(location) == True: #Tests to see if user entered a valid path
print "You entered:",location
if raw_input("Is this correct? Use 'Y' or 'N' to answer. ") == "Y":
print ""
file_extension(location)
else:
folder_location()
else:
print "I'm sorry, but the file location you have entered does not exist. Please try again."
folder_location()
def file_extension(location):
file_extension = raw_input("What is the file type (.txt for example)? ")
print "You entered:", file_extension
if raw_input("Is this correct? Use 'Y' or 'N' to answer. ") == "Y":
print ""
each_file(location, file_extension)
else:
file_extension(location)
def each_file(location, file_extension):
try:
column = (raw_input("Please enter column name you want to analyze: ")) #Using smcn
print "You entered:",column
if raw_input("Is this correct? Use 'Y' and 'N' to answer. ") == "Y":
print ""
sort_by(location,file_extension,column)
else:
each_file(location,file_extension)
except TypeError:
print "That is not a valid column name. Please try again."
each_file(location,file_extension)
def sort_by(location, file_extension, column):
content = os.listdir(location)
for item in content:
if item.endswith(file_extension):
data = csv.reader(open(os.path.join(location,item)),delimiter=',')
col_position = get_columnposition(data.next(),column)
to_count = sorted(data, key=operator.itemgetter(col_position))
count_date(to_count, location)
else:
print "No file in this directory ends with " + file_extension
I get:
No file in this directory ends with .processed
and then the rest of my output (code not posted here).
Is there a way for me to say (I'm going to put it in a code block just to show how it works in my mind):
def file_extension(location):
file_extension = raw_input("What is the file type (.txt for example)? ")
print "You entered:", file_extension
if raw_input("Is this correct? Use 'Y' or 'N' to answer. ") == "Y":
print ""
each_file(location, file_extension)
else:
file_extension(location)
def each_file(location, file_extension):
try:
column = (raw_input("Please enter column name you want to analyze: ")) #Using smcn
print "You entered:",column
if raw_input("Is this correct? Use 'Y' and 'N' to answer. ") == "Y":
print ""
sort_by(location,file_extension,column)
else:
each_file(location,file_extension)
except TypeError:
print "That is not a valid column name. Please try again."
each_file(location,file_extension)
def sort_by(location, file_extension, column):
content = os.listdir(location)
for item in content:
if item.endswith(file_extension):
data = csv.reader(open(os.path.join(location,item)),delimiter=',')
col_position = get_columnposition(data.next(),column)
to_count = sorted(data, key=operator.itemgetter(col_position))
count_date(to_count, location)
if no item.endswith(file_extension):
print "No file in this directory ends with " + file_extension
Any help would be greatly appreciated. If it would help, I could edit in the rest of my code I have at the moment.
Thanks!
Your logic should be the following:
Ask for the directory
Ask for the extension
Check if any file ends with that extension
If there is at least one file, then ask for the column
To make all this easier, use csv and glob:
import glob
import csv
import os
directory = input('Please enter the directory: ')
extension = input('Please enter the extension (.txt, .csv): ')
files = list(glob.glob(os.path.join(directory, extension)))
if not files:
print('Sorry, no files match your extension {} in the directory {}'.
format(extension, directory))
else:
for file_name in files:
col = input('Enter the column number for {}'.format(file_name))
with open(file_name, 'r') as thefile:
reader = csv.reader(thefile, delimiter=',')
for row in reader:
try:
do_something(row[col])
except IndexError:
print('Column {} does not exist'.format(col))

Categories

Resources