odd while loop behavior (python) - 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.

Related

Python open only one directory that starts with specific numbers

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

Adding in "else" makes my for loop not work

I am new to coding and have a list of lists that I need to search.
I want to see what lists contained in the larger list have the variable full_choice as the 3rd item in the sequence.
All lists that contain third_choice i need to print to a txt file.
the code below works and adds exactly what I need it to to the file, however I need the function to start again if there is no match for the variable full_choice.
def display_instructor_txt():
file_name = input('type in the name of the file you want to create do not include .txt')
file_name_full = file_name + '.txt'
new_file = open(file_name_full,'w')
first_choice = input('type in the first name of the instructor you want to filter by ')
last_choice = input('type in the last name of the instructor you want to filter by ')
full_choice = first_choice[0].upper() + first_choice[1:].lower() + last_choice[0].upper() + last_choice[1:].lower()
for course in all_courses_list:
if course[2].replace(" ","").replace(",","") == full_choice:
course_st = ''.join(course)
new_file.write(course_st.replace('[','').replace(']','').replace("'",'').replace('\\n','').replace(" ", ", "))
else:
print('please try again')
display_instructor_txt()
I have tried inserting an else: at the end of the code however while that has ends up creating the file it doesn't write anything to it.
Tried to fix your indentation. I'm guessing you wanted something like this:
def display_instructor_txt():
file_name = input('type in the name of the file you want to create do not include .txt')
file_name_full = file_name + '.txt'
new_file = open(file_name_full,'w')
first_choice = input('type in the first name of the instructor you want to filter by ')
last_choice = input('type in the last name of the instructor you want to filter by ')
full_choice = first_choice[0].upper() + first_choice[1:].lower() + last_choice[0].upper() + last_choice[1:].lower()
for course in all_courses_list:
if course[2].replace(" ","").replace(",","") == full_choice:
course_st = ''.join(course)
new_file.write(course_st.replace('[','').replace(']','').replace("'",'').replace('\\n','').replace(" ", ", "))
else:
print('please try again')
display_instructor_txt()
I just moved the else block forward to align with the if block you had a few lines before.
As #Haken Lid suspected, please fix indentation:
for course in all_courses_list:
if course[2].replace(" ","").replace(",","") == full_choice:
course_st = ''.join(course)
new_file.write(course_st.replace('[','').replace(']','').
replace("'",'').replace('\\n','').replace(" ", ", "))
else:
print('please try again')
display_instructor_txt()

Looping a Try/Except block until a file can be read

I have a try/except block in a function that asks the user to enter the name of a text file to open. If the file does not exist, I want the program to ask the user for the filename again either until it is located or the user hits ENTER.
Right now the try/except block just runs infinitely.
def getFiles(cryptSelection):
# Function Variable Definitions
inputFile = input("\nEnter the file to " + cryptSelection +\
". Press Enter alone to abort: ")
while True:
if inputFile != '':
try:
fileText = open(inputFile, "r")
fileText.close()
except IOError:
print("Error - that file does not exist. Try again.")
elif inputFile == '':
input("\nRun complete. Press the Enter key to exit.")
else:
print("\nError - Invalid option. Please select again.")
return inputFile
You need to break out of the while loop, this has to be done at 2 places:
After reading the file (when it is a correct file)
After the Enter key is pressed. because we want to end.
Also you need to prompt the question inside the loop so the question is asked again at every iteration and the inputFile value is updated with the latest user input
One last thing, I think your else clause can be removed as it is never accessed, the if and elif catch all the possibilities (ie, inputFile has a value or not).
def getFiles(cryptSelection):
while True:
inputFile = input("\nEnter the file to %s. Press Enter alone to abort:" % cryptSelection)
if inputFile != '':
try:
fileText = open(inputFile, "r")
fileText.close()
# break out of the loop as we have a correct file
break
except IOError:
print("Error - that file does not exist. Try again.")
else: # This is the Enter key pressed event
break
return inputFile
you have a while True but no break in your code you probably want to break after the fileText.close() like this:
try:
fileText = open(inputFile, "r")
fileText.close()
break
except IOError:
print("Error - that file does not exist. Try again.")
but really you should change this check to use os.path.isfile like this:
import os
def getFiles(cryptSelection):
inputFile = input("\nEnter the file to " + cryptSelection +\
". Press Enter alone to abort: ")
while True:
if inputFile != '':
if os.path.isfile(inputFile):
return inputFile
else:
print("Error - that file does not exist. Try again.")
elif inputFile == '':
input("\nRun complete. Press the Enter key to exit.")
else:
print("\nError - Invalid option. Please select again.")
That is because you don't assign a new value to inputFile within the while loop.
It will hold the same value forever...
EDIT
Once you will assign a new value to inputFile within the loop - make sure to break out when the exit condition is met ("user hits Enter")

File saving issue PYTHON - duplicate files?

I am developing a program, and one of the options is to save the data. Although there is a thread similar to this, it was never fully resolved ( Creating file loop ). The problem is, the program does not recognise duplicate files, and I don't know how to loop it so that if there is a duplicate file name and the user does not want to overwrite the existing one, the program will ask for a new name. This is my current code:
print("Exporting")
import os
my_file = input("Enter a file name")
while os.path.isfile(my_file) == True:
while input("File already exists. Overwrite it? (y/n) ") == 'n':
my_file = open("filename.txt", 'w+')
# writing to the file part
my_file = open("filename.txt", 'w+')
# otherwise writing to the file part
file_selected = False
file_path = ""
while not file_selected:
file_path = input("Enter a file name")
if os.path.isfile(file_path) and input("Are you sure you want to override the file? (y/n)") != 'y':
continue
file_selected = True
#Now you can open the file using open()
This holds a boolean variable file_selected.
First, it asks the user for a file name. If this file exists and the user doesn't want to override it it continues (stops the current iteration and continues to the next one), so the user is asked again to enter a file name. (pay attention that the confirmation will execute only if the file exists because of lazy evaluation)
Then, if the file doesn't exist or the user decided to override it, file_selected is changed to True, and the loop is stopped.
Now, you can use the variable file_path to open the file
Disclaimer: This code is not tested and only should theoretically work.
Although the other answer works I think this code is more explicit about file name usage rules and easier to read:
import os
# prompt for file and continue until a unique name is entered or
# user allows overwrite
while 1:
my_file = input("Enter a file name: ")
if not os.path.exists(my_file):
break
if input("Are you sure you want to override the file? (y/n)") == 'y':
break
# use the file
print("Opening " + my_file)
with open(my_file, "w+") as fp:
fp.write('hello\n')
This is how I advise to do it, especially when you have event driven GUI app.
import os
def GetEntry (prompt="Enter filename: "):
fn = ""
while fn=="":
try: fn = raw_input(prompt)
except KeyboardInterrupt: return
return fn
def GetYesNo (prompt="Yes, No, Cancel? [Y/N/C]: "):
ync = GetEntry(prompt)
if ync==None: return
ync = ync.strip().lower()
if ync.startswith("y"): return 1
elif ync.startswith("n"): return 0
elif ync.startswith("c"): return
else:
print "Invalid entry!"
return GetYesNo(prompt)
data = "Blah-blah, something to save!!!"
def SaveFile ():
p = GetEntry()
if p==None:
print "Saving canceled!"
return
if os.path.isfile(p):
print "The file '%s' already exists! Do you wish to replace it?" % p
ync = GetYesNo()
if ync==None:
print "Saving canceled!"
return
if ync==0:
print "Choose another filename."
return SaveFile()
else: print "'%s' will be overwritten!" % p
# Save actual data
f = open(p, "wb")
f.write(data)
f.close()

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