debugpythonMinor
Searching for files in a specified directory
Viewed 0 times
directorysearchingfilesforspecified
Problem
I am currently writing a program that allows me to search for files in a user-specified directory. My current code is as follows:
```
if os.path.exists(file_path)!= True:
print('\n Path does not exist. \n')
else:
while True:
aa = '''\nWhich search characteristics would you like to use? \n 1. Search by name: N \n 2. Search by extension: E \n 3. Search by size: S
\n Please enter your choice: '''
answer = input(aa).strip()
if answer not in 'NnEeSs' or answer=='':
print('\n Invalid choice. ')
elif answer in 'Nn':
while True:
try:
name = input ('\nEnter file name: ')
rr = search_by_name(name, file_path)
if not rr:
print('\n File not found \n')
else:
break
except WindowsError:
print('\n Oops! Access denied.\n')
continue
elif answer in 'Ee':
while True:
try:
ending = input ('\nEnter the file extension: ')
rr = search_by_extention(ending, file_path)
if not rr:
print('\n No File(s) found \n')
else:
break
except WindowsError:
print('\n Oops! Access denied. \n')
continue
elif answer in 'Ss':
while True:
try:
size = int(input('\nPlease enter file size: '))
rr = search_by_size(size, file_path)
if not rr:
print('\n No file(s) found \n')
else:
break
except ValueError:
print('\n* Enter an
```
if os.path.exists(file_path)!= True:
print('\n Path does not exist. \n')
else:
while True:
aa = '''\nWhich search characteristics would you like to use? \n 1. Search by name: N \n 2. Search by extension: E \n 3. Search by size: S
\n Please enter your choice: '''
answer = input(aa).strip()
if answer not in 'NnEeSs' or answer=='':
print('\n Invalid choice. ')
elif answer in 'Nn':
while True:
try:
name = input ('\nEnter file name: ')
rr = search_by_name(name, file_path)
if not rr:
print('\n File not found \n')
else:
break
except WindowsError:
print('\n Oops! Access denied.\n')
continue
elif answer in 'Ee':
while True:
try:
ending = input ('\nEnter the file extension: ')
rr = search_by_extention(ending, file_path)
if not rr:
print('\n No File(s) found \n')
else:
break
except WindowsError:
print('\n Oops! Access denied. \n')
continue
elif answer in 'Ss':
while True:
try:
size = int(input('\nPlease enter file size: '))
rr = search_by_size(size, file_path)
if not rr:
print('\n No file(s) found \n')
else:
break
except ValueError:
print('\n* Enter an
Solution
To improve readability I would try and break the code down into more functions and redefine your pre-determined text values as globals, such that you can save space in the actual function. Responses can be represented by a dictionary value with boolean/text key value pairs (or exception/text). Also certain UI options can be stored in a dictionary, with links to their associated functions.
Now that we have a collection of text values lets make a function to standardize print outputs, such that you don't have to write all those stars everywhere, and you can feel assured that they will produce even length lines.
Lets also make a simple yes/no function.
Now your main method boils down to..
Now for the actual important functions.. I'll just do one example to show the try catch responses,..
# using 3 quotes mean you don't need to specify newlines
dir_tools_menu = '''
Which search characteristics would you like to use?
1. Search by name: N
2. Search by extension: E
3. Search by size: S
\tPlease enter your choice: '''
dir_tools_options = {"n":ui_search_by_name,
"e":ui_search_by_extention,
"s":ui_search_by_size}
error_response = {WindowsError:"Oops! Access denied.",
ValueError:"Enter an numeric value."}
# add number of files for true
files_found_response = {False:"No file(s) found",
True:"{} file(s) found"}
# add filename
file_found_response = {False:"File {} not found",
True:"File {} found"}
file_exists_response ={ False:"Path does not exist.",
True:"Path Found"}
# add choice for true
valid_ui_response = {False:"Invalid choice.",
True:"You choose {}."}Now that we have a collection of text values lets make a function to standardize print outputs, such that you don't have to write all those stars everywhere, and you can feel assured that they will produce even length lines.
line_length = 40
# or you can have a funky pattern like "`-._.-'-._...
line_pad = "*"*line_length
def my_print(text, *params):
# len(params) must match the count of "{}" in the text so this will not crash
# Perhaps add a check to assert this case
message = text.format(*params)
offset = line_length/2 - len(message)/2
if offset > 0 and offset + len(message) < line_length:
print(line_pad[:offset] + message + line_pad[offset+len(message):])
# in the case that a line is larger than the formatting, you can just print the line.
# its gonna look gross regardless
else:
print(message)Lets also make a simple yes/no function.
yes = ("yes", "y","1")
no = ("no", "n", "0")
def ask_yes_no(question):
answer = ''
while not answer in yes + no:
answer = input(question).lower()
if not answer in yes + no:
my_print(valid_ui_response[False])
else:
my_print(valid_ui_response[True], return_to_menu)
# True - yes, False - no
return answer in yesNow your main method boils down to..
quit_question = "Quit Dir Tools? "
def dir_tools(file_path):
if os.path.exists(file_path):
my_print(file_exists_response[True] )
else:
my_print(file_exists_response[False])
return
quit_dir_tools = False
while not quit_dir_tools:
answer = input(dir_tools_menu).lower()
if answer not in dir_tools_options:
my_print(valid_ui_response[False])
else:
my_print(valid_ui_response[True],answer)
dir_tools_options[answer](file_path)
quit_dir_tools = ask_yes_no(quit_question)Now for the actual important functions.. I'll just do one example to show the try catch responses,..
ui_sbn_question = 'Enter file name: '
return_question = "Return to main menu? "
def ui_search_by_name(file_path):
return_to_menu = False
while not return_to_menu:
name = input(ui_sbn_question)
try:
sbn_response = search_by_name(name, file_path)
if not sbn_response:
my_print(file_found_response[False], name)
else:
my_print(file_found_response[True], name)
# assuming that this isnt a boolean
my_print(sbn_response)
except WindowsError:
my_print(error_response[WindowsError])
return_to_menu = ask_yes_no(return_question)Code Snippets
# using 3 quotes mean you don't need to specify newlines
dir_tools_menu = '''
Which search characteristics would you like to use?
1. Search by name: N
2. Search by extension: E
3. Search by size: S
\tPlease enter your choice: '''
dir_tools_options = {"n":ui_search_by_name,
"e":ui_search_by_extention,
"s":ui_search_by_size}
error_response = {WindowsError:"Oops! Access denied.",
ValueError:"Enter an numeric value."}
# add number of files for true
files_found_response = {False:"No file(s) found",
True:"{} file(s) found"}
# add filename
file_found_response = {False:"File {} not found",
True:"File {} found"}
file_exists_response ={ False:"Path does not exist.",
True:"Path Found"}
# add choice for true
valid_ui_response = {False:"Invalid choice.",
True:"You choose {}."}line_length = 40
# or you can have a funky pattern like "`-._.-'-._...
line_pad = "*"*line_length
def my_print(text, *params):
# len(params) must match the count of "{}" in the text so this will not crash
# Perhaps add a check to assert this case
message = text.format(*params)
offset = line_length/2 - len(message)/2
if offset > 0 and offset + len(message) < line_length:
print(line_pad[:offset] + message + line_pad[offset+len(message):])
# in the case that a line is larger than the formatting, you can just print the line.
# its gonna look gross regardless
else:
print(message)yes = ("yes", "y","1")
no = ("no", "n", "0")
def ask_yes_no(question):
answer = ''
while not answer in yes + no:
answer = input(question).lower()
if not answer in yes + no:
my_print(valid_ui_response[False])
else:
my_print(valid_ui_response[True], return_to_menu)
# True - yes, False - no
return answer in yesquit_question = "Quit Dir Tools? "
def dir_tools(file_path):
if os.path.exists(file_path):
my_print(file_exists_response[True] )
else:
my_print(file_exists_response[False])
return
quit_dir_tools = False
while not quit_dir_tools:
answer = input(dir_tools_menu).lower()
if answer not in dir_tools_options:
my_print(valid_ui_response[False])
else:
my_print(valid_ui_response[True],answer)
dir_tools_options[answer](file_path)
quit_dir_tools = ask_yes_no(quit_question)ui_sbn_question = 'Enter file name: '
return_question = "Return to main menu? "
def ui_search_by_name(file_path):
return_to_menu = False
while not return_to_menu:
name = input(ui_sbn_question)
try:
sbn_response = search_by_name(name, file_path)
if not sbn_response:
my_print(file_found_response[False], name)
else:
my_print(file_found_response[True], name)
# assuming that this isnt a boolean
my_print(sbn_response)
except WindowsError:
my_print(error_response[WindowsError])
return_to_menu = ask_yes_no(return_question)Context
StackExchange Code Review Q#47427, answer score: 2
Revisions (0)
No revisions yet.