ELIF statements skipped in favor of ELSE - python-3.x

I am writing a few statements utilizing regular expressions to match an output to a given extension. My For loop seems to work fine, I get an answer back for each of the files and if I take one out or add one, I get a return.
What appears to happen though is that my first file is picked up, matched successfully, and the correct output given. The loop then grabs the next file, checks against the first statement, then skips the two ELIF's and gives and output based on my ELSE. Can anyone point out why or if I have it wrong, what is actually going on?
def extmatch():
global dircontents
for file in dircontents:
dircontents = re.search(".+\sbreakout.*\.ttx", file)
if dircontents:
print('File is for TIA')
elif dircontents:
dircontents = re.search('\w+\.csv+$', file)
if dircontents:
print('File is for NMFTA')
elif dircontents:
dircontents = re.search('\w+.\.txt+$', file)
if dircontents:
print('File is for NMFTA')
else:
print('File type not recognized.')
['061419license breakout_ibc_v3_0116.ttx', '2019-06-17_7-49-21.jpg', 'SampleCSV.csv', 'script_test.txt'] <--- these are the files in the dir indicated
File is for TIA
File type not recognized. <---Seems to match to ELSE for each file past the first
File type not recognized.
File type not recognized.

You probably want something like this:
def extmatch(dircontents):
for filename in dircontents:
if filename.lower().endswith(".ttx"):
print('File is for TIA')
elif filename.lower().endswith(".csv"):
print('File is for NMFTA')
elif filename.lower().endswith(".txt"):
print('File is for NMFTA')
else:
print('File type not recognized.')
or even like this:
EXT_ASSIGNMENTS = {
'ttx': 'TIA',
'csv': 'NMFTA',
'txt': 'NMFTA',
}
def extmatch(dircontents):
for filename in dircontents:
ext = filename.lower().split('.')[-1]
if ext in EXT_ASSIGNMENTS:
print('File is for ' + EXT_ASSIGNMENTS[ext])
else:
print('File type not recognized.')
Avoid global variables. If you need to pass information to a function, use an argument.

Related

List is empty when appending when using recursion

I have two functions. The first one is used to get a list of paths to text files, and the second one is used to iterate over this list of paths and then check if they include the word password. But because of the Try Except statement in the second function, I had to use recursion to make it continue running unless there's another way if possible to provide below. My problem is that the list returned in the second function is empty why and how to fix it?
def search_txt():
"""Function to search the C:\\ for .txt files -> then add them (including full path to file) to a list."""
list_of_txt = []
for dir_path, sub_dir, files in os.walk("C:\\"):
"""Method 1 -> checks the end of the file name (could be used for specific extensions)"""
for file in files:
if file.endswith(".txt"):
list_of_txt.append(os.path.join(dir_path, file))
return list_of_txt
def search_pass_file(list_of_files: list):
"""Function to iterate over each text file, searching if the word "password" is included -> Returns the text
file's path """
list_of_pass = []
if len(list_of_files) != 0:
for i in range(len(list_of_files)):
file = list_of_files.pop()
try:
with open(file, encoding="utf8") as f:
for line in f.readlines():
if "password" in line:
list_of_pass.append(file)
except UnicodeDecodeError:
return search_pass_file(list_of_files)
except PermissionError:
return search_pass_file(list_of_files)
else:
return list_of_pass
if __name__ == '__main__':
myList = search_txt()
print(search_pass_file(myList))
You're returning list_of_pass only if len(list_of_files) == 0 (it's in the else block). Your return statement should occur after the loop (which should be a while one btw)
You can except several errors in one line by putting them in parenthesis: except (UnicodeDecodeError, PermissionError) of except all exceptions (for instance, you're not handling FileNotFoundError).
I'd reduce your function to:
def search_pass_file(list_of_files: list):
"""Function to iterate over each text file, searching if the word "password" is included -> Returns the text
file's path """
list_of_pass = []
while list_of_files:
file = list_of_files.pop()
try:
with open(file, encoding="utf8") as f:
for line in f.readlines():
if "password" in line:
list_of_pass.append(file)
break
except Exception:
list_of_pass += search_pass_file(list_of_files)
return list_of_pass
Edit: also in your except block, you should append the returned value of the recursive function to list_of_pass otherwise you'll lose the files found after the error occurs.

Bad word filter also deletes embeds

So i have a problem with this code, it doesnt like embeds. It will automaticly delete any embeds from other bots. Is there anyway to stop this from happening.
#client.event
async def on_message(msg):
if msg.author == client.user:
return
with open('BadWords.txt', 'r') as f:
BadWords = f.readlines()
for line in BadWords:
if msg.content in line:
await msg.delete()
await client.process_commands(msg)
Thanks for the help in advance
This most likely happens because you have an empty line in your .txt file, which means that Python matches the empty string with the empty content. You have a few options... for clarity I include the surrounding code
You can check if the specific line is empty
for line in BadWords:
if line == '':
continue
if msg.content in line:
Or you can remove it before you start looping
BadWords = f.readlines()
try:
BadWords.remove('')
except ValueError:
pass
Lastly it's also possible you ignore the message if it has no content, as this can also happen if someone sends a file or attachment.
if msg.author == client.user:
return
if msg == '':
return

Continues variable not triggering while loop

Apologies if this is a repost. I am trying to write a while loop with a continue variable and if/else statement. My issue is that my continue variable is being ignored I cannot find the problem thus far. So far I have moved the while continues == 'y' condition into the else block now I am a bit flummoxed on why this var is being overlooked.
code:
def add_to_existing_file(data):
# data[0]-api response
# data[1]-city
# infile-file object returned from openFile()
# file_name- file name string. check filetype & report version.
continues = 'y' # set up continue variable
while continues == 'y':
file_name = input("Enter File Path to file to be appended: ") # get file from user
if file_name is False:
print("Now Creating Excel File..") # create condition for no user response.
return # if empty response exit function
else:
infile = appends.openFile(file_name) # open file to work with. Returns file object.
added_data = appends.journal_report_1_to_df(infile, file_name, data[0], data[1]) # append selected file to existing df
continues = input("Do you want to append another file? Y or N").lower() # check if new file
return added_data # return new df w/appended data
The problem happens on the last line. You're returning at the end of the first iteration, which exits the loop. This can be fixed by moving the return to the outer scope.
def add_to_existing_file(data):
# data[0]-api response
# data[1]-city
# infile-file object returned from openFile()
# file_name- file name string. check filetype & report version.
continues = 'y' # set up continue variable
while continues == 'y':
file_name = input("Enter File Path to file to be appended: ") # get file from user
if file_name is False:
print("Now Creating Excel File..") # create condition for no user response.
return # if empty response exit function
else:
infile = appends.openFile(file_name) # open file to work with. Returns file object.
added_data = appends.journal_report_1_to_df(infile, file_name, data[0], data[1]) # append selected file to existing df
continues = input("Do you want to append another file? Y or N").lower() # check if new file
return added_data # return new df w/appended data
It should work if you get the second return line (return added_data # return new df w/appended data) to have the same indentation as your while line. As a basic outline for a continue loop:
def function
continues = 'y'
while
if :
elif :
else :
print
continue ?
return

while loop and opening file in append mode. why does the order matter?

I am following the 'python crash course', one of the practice questions ask me to open/create the txt file 'guest_book' in append mode and create a while loop to ask user input their name, at the same time append their name into the 'guest_book' txt and print that they have been logged. I have wrote the following code.
filename = 'guest_book'
with open(filename, 'a') as f:
while True:
name = input('enter name ')
f.write(name + '\n')
print(f"You have been added to the guest book, {name}")
The problem: the while loop is successful and the final print is also successful, however when I check the guest_book txt. it does not record the inputted name. Interestingly, by simply switching the order of while loop and open txt command, it seems to work, like this:
filename = 'guest_book.txt'
while True:
with open(filename, 'a') as f:
name = input('enter name ')
f.write(name + '\n')
print(f"You have been added to the guest book, {name}")
the only difference between the two codes are switched order of the while loop and "with open" line. Can someone explain to me why this order matters? No matter how hard I tried, I can't seem to understand the logic behind this. Thanks
Short explanation
Since your
while True
loop never ends your changes to the file are never actually "committed".
Long explanation
The whole reason we use
with open(filename, 'a') as f:
f.write("write something")
instead of
f= open("myfile.txt","w+")
f.write("write something")
f.close()
is so we don't have to close the file-access manually - only upon "f.close()" are the changes actually written to the local file!
In your code, close() is called behind the scenes once your "with"-block ends:
with open(filename, 'a') as f:
while True:
name = input('enter name ')
f.write(name + '\n')
print(f"You have been added to the guest book, {name}")
# close() would be triggered behind the scenes here
# only after completing ALL statements in your with-block, the changes get saved to the file.
print("We never reach this point...")
Since your code never reaches that point as you have a "while true loop", the file never gets closed and the changes are never written to the file.
In your second code example, the file gets opened and closed in every iteration of the "while true"-loop as your with-block starts and ends in one iteration of the loop. This means all changes are commited every iteration of the loop.
Edit:
As MisterMiyagi has pointed out:
"f.close() releases the file handle. It also calls (the internal equivalent of) f.flush() to commit outstanding changes. The primary purpose is releasing the file handle, though."
So you can either close the entire file (as Python flushes files automatically when closing) or call f.flush() in your while-loop after writing to flush the internal buffer, but to keep the file-handle open in case you want to continue writing afterwards.
So here is a working adaption of your first code (with flush):
filename = 'guest_book'
with open(filename, 'a') as f:
while True:
name = input('enter name ')
f.write(name + '\n')
f.flush() # making sure the changes are in the file.
print(f"You have been added to the guest book, {name}")
looks like the problem is that the oppened txt file is not closed properly, the program ends by force, not alowing the closing code to run, or something like that. the reason why the:
filename = 'guest_book.txt'
while True:
with open(filename, 'a') as f:
name = input('enter name ')
f.write(name + '\n')
print(f"You have been added to the guest book, {name}")
works is because you are constantly closing and oppening the file.
if you want the file to close, I recomend adding a save funcion or an exit function. This will make the file close properly and save itself, kind of like this:
filename = 'guest_book'
with open(filename, 'a') as f:
while True:
name = input('enter name ')
if name == 'exit':
break
f.write(name + '\n')
print(f"You have been added to the guest book, {name}")

File won't open when being passed from a function

How come it's not opening the file I put into the function? It opens when I plug the file name directly into the main program, but not when I try to pass it through the function. It gives me a FileNotFoundError.
def get_valid_filename(prompt):
'''Use prompt (a string) to ask the user to type the name of a file. If
the file does not exist, keep asking until they give a valid filename.
Return the name of that file.'''
filename = input(prompt)
if os.path.isfile(filename) == False:
print ("That file does not exist.")
filename = input(prompt)
return filename
if __name__ == '__main__':
prompt = 'enter the name of the file with unknown author:'
mystery_filename = get_valid_filename(prompt)
# readlines gives us the file as a list of strings each ending in '\n'
text = open(mystery_filename, 'r').read()
print (text)
get_valid_filename should look like this:
def get_valid_filename(prompt):
while True:
filename = input(prompt):
if os.path.exists(filename):
return filename
print('that file does not exist')

Resources