try/except block catching multiple exceptions - python

I am trying to create a try except that catches 3 errors:
the first one if the user enters the name if the file which is not a txt file,
the second is if the file is empty then an error Is thrown and
the third is for if the file entered does not exist then an error is thrown as well.
I did try to do the first one where an error messages thrown if the file is not a txt file but I am also getting an error for that one saying 'str' object has no attribute 'contains'
try:
file_name = input("Enter file name: ")
assert not file_name.contains(".txt")
except AssertionError:
("Error, must be a txt file")
file_fh = open(file_name)
counter = 0
avg = 0
for line in file_fh:
if not line.startswith("X-DSPAM-Confidence:"): continue
avg += float(line[20:-1].strip())
counter = counter + 1
print("Average spam confidence:", round(avg / counter, 4))

If you want to be able to catch an exception anywhere in a large block of code, the entire thing needs to be within the same try block:
try:
file_name = input("Enter file name: ")
assert ".txt" in file_name, "Error, must be a txt file"
file_fh = open(file_name) # may raise FileNotFoundError
counter = 0
avg = 0
for line in file_fh:
if not line.startswith("X-DSPAM-Confidence:"): continue
avg += float(line[20:-1].strip())
counter = counter + 1
assert counter, "File is empty!"
print("Average spam confidence:", round(avg / counter, 4))
except (AssertionError, FileNotFoundError) as e:
print(e)
In this example, the assert statements will obviously raise an AssertionError with the given message if the condition is not met. The open call will raise FileNotFoundError if the file is missing, so to handle that case all you need to do is make sure your except block includes FileNotFoundError.

Related

How to check if a file is empty? python

I have a code that i am writing to read a txt file and report sum, average, ect... but I also need it to recognize when the txt file is empty or has no numbers in it, and not crash. i have tried os.stat(f).st_size == 0, and os.path.getsize(f) == 0:, and reading the first character too. for some reason my code is not picking up on the exception and keeps continuing on with the rest of the code and then crashes when trying to divide by zero to find the average. I am also not using any external libraries.
#the below code asks for the file name and opens the file :)
while (True):
try:
filename = input("What file would you like to acess?: ")
f = open(filename, "r")
except IOError:
print("File", filename, "could not be opened")
except:
if os.path.getsize(f) == 0:
print("There are no numbers in", filename)
else:
break
#the below line displays the file name :)
print("File Name: ", f.name)
#the below code calculates the sum and prints it :)
sum=0
for n in f:
n=n.strip()
sum=sum+int(n)
print("Sum: ", sum)
#the below code calculates the number of lines and prints it :)
with open(filename, "r") as f:
count = 0
for line in f:
if line != "\n":
count += 1
print("Count: ", count)
#the below code calculates the average and prints it :)
avg = sum/count
print("Average: ", avg)

Try except function skipping text after first word?

I am trying to create a block of code that scans a .txt file (first book of LOTR) and tallys the frequency of each letter into a dictionary. (say for instance if theres 500 3 letter words appearing in the book, the output will be displayed as 3:500, and so on).
I seemed to have gotten the code right as I have tried it on test documents before adding the dict() function, and it works by printing each word as a string in a list, though when I go to run it now, it prints the first word then outputs file not found (which is what ive coded for an exception), even though the file is present in my jupyter notebook.
Is there any way to fix this? what is the default directory that jupyter scans for?
All of your help is appreciated!
Code:
fname= input('Enter file: ')
#if len(fname) < 1: fname = 'LOTR.txt'
try:
fhand = open(fname)
d = dict()
for line in fhand:
words = line.split()
print(words)
for word in words:
d1[word] = d1.get(word, 0) + 1
print (d1)
except:
print("File not found")
output:
Enter file: LOTR.txt
['PROLOGUE']
File not found
Your problem is that you are accessing d1 before defining it.
Also you should catch specific exceptions instead of using a bare except. The following should solve your problem:
fname= input('Enter file: ')
#if len(fname) < 1: fname = 'LOTR.txt'
try:
fhand = open(fname)
d = dict()
for line in fhand:
words = line.split()
print(words)
for word in words:
d[word] = d.get(word, 0) + 1
print(d)
except FileNotFoundError:
print("File not found")
except Exception as e:
print("Other error occurred", e)

Exception Error Handling in python spits out error after specifying not to

I'm trying to stop this code from giving me an error about a file I created called beloved.txt I used the FillNotFoundError: to say not to give me the error and to print the file thats not found but instead its printing the message and the error message. How can I fix it ?
def count_words(Filenames):
with open(Filenames) as fill_object:
contentInFill = fill_object.read()
words = contentInFill.rsplit()
word_length = len(words)
print("The file " + Filename + " has " + str(word_length) + " words.")
try:
Filenames = open("beloved.txt", mode="rb")
data = Filenames.read()
return data
except FileNotFoundError as err:
print("Cant find the file name")
Filenames = ["anna.txt", "gatsby.txt", "don_quixote.txt", "beloved.txt", "mockingbird.txt"]
for Filename in Filenames:
count_words(Filename)
A few tips:
Don't capitalize variables besides class names.
Use different variable names when referring to different things. (i.e. don't use Filenames = open("beloved.txt", mode="rb") when you already have a global version of that variable, and a local version of that variable, and now you are reassigning it to mean something different again!! This behavior will lead to headaches...
The main problem with the script though is trying to open a file outside your try statement. You can just move your code to be within the try:! I also don't understand except FileNotFoundError as err: when you don't use err. You should rewrite that to except FileNotFoundError: in this case :)
def count_words(file):
try:
with open(file) as fill_object:
contentInFill = fill_object.read()
words = contentInFill.rsplit()
word_length = len(words)
print("The file " + file + " has " + str(word_length) + " words.")
with open("beloved.txt", mode="rb") as other_file:
data = other_file.read()
return data
except FileNotFoundError:
print("Cant find the file name")
filenames = ["anna.txt", "gatsby.txt", "don_quixote.txt", "beloved.txt", "mockingbird.txt"]
for filename in filenames:
count_words(filename)
I also do not understand why you have your function return data when data is read from the same file regardless of that file you input to the function?? You will get the same result returned in all cases...
The "with open(Filenames) as fill_objec:" sentence will throw you the exception.
So you at least must enclose that sentence in the try part. In your code you first get that len in words, and then you check for the specific file beloved.txt. This doubled code lets you to the duplicated mensajes. Suggestion:
def count_words(Filenames):
try:
with open(Filenames) as fill_object:
contentInFill = fill_object.read()
words = contentInFill.rsplit()
word_length = len(words)
print("The file " + Filename + " has " + str(word_length) + " words.")
except FileNotFoundError as err:
print("Cant find the file name")

Why ValueError is not displayed

so basically my code is :
def process_contacts(contacts_file):
f = None
sections = []
ret_dic = {}
try:
f = open(contacts_file, 'r')
content = f.readlines()
for line in content:
if "#" in line:
continue
line = line.rstrip("\n")
sections = line.split(',') # section = categories of information on origin file
if sections[1] == '' or len(sections) != 4:
raise ValueError('Invalid input file')
if sections[3] in ret_dic:
if sections[1] not in ret_dic[sections[3]]:
ret_dic[sections[3]].append(sections[1])
else:
ret_dic[sections[3]] = [sections[1]]
except IOError:
print 'Cannot process due to an IO error'
except ValueError:
raise ValueError('Invalid input file')
finally:
if f != None:
f.close()
if sections != []:
return ret_dic
I'm having problem with ValueError raising. I need the ValueError to be raised as an error, but my code just skips over it and I don't understand why, I searched the whole internet about it, but perhaps I just don't get it.
Anyways the csv file that I open is :
Avi,Levi,Kushnir 7,Jerusalem
Moshe,,Hamakabim 4,Tel Aviv
Michael,Cohen,Herzel 70
Eli,Cohen,Haroe 6,Jerusalem
Moti,Cohen,shalom 5,Tel Aviv
It's because of your finally block. You raise your ValueError in the except and then say "oh never mind" and finish out with the finally. finally blocks will always be the last thing that runs if an error is encountered.

How to get my python code to go back into the loop after the exception is thrown

I'm a beginner in python & am having some problems with the structure of my homework assignment; my assignment is: "Write a program that asks the user for a filename, opens the file and reads through the file just once before reporting back to the user the number of characters (including spaces and end of line characters), the number of words, and the number of lines in the file.
If the user enters the name of a file that doesn't exist, your program should give her as many tries as she needs in order to type a valid filename. Obtaining a valid filename from the user is a common operation, so start by writing a separate, reusable function that repeatedly asks the user for a filename until she types in a file that your program is able to open."
And, I didn't start that way (& now I'm wondering if with the way I've structured it with "with/as", there's a way to even do that but my problem right now is getting it to go back into the try section of code after the error is thrown (I missed the class where this was explained so I've only ever read about this so I Know I'm not doing something right). I can get it to work as long as it's a filename that exists, if it's not, it prints nothing to the screen. Here's my code:
filename = input("please enter a file name to process:")
lineCount = 0
wordCount = 0
charCount = 0
try:
with open(filename, 'r') as file:
for line in file:
word = line.split()
lineCount = lineCount + 1
wordCount = wordCount + len(word)
charCount = charCount + len(line)
print("the number of lines in your file is:", lineCount)
print("the number of words in your file is", wordCount)
print("the number of characters in your file is:", charCount)
except OSError:
print("That file doesn't exist")
filename = input("please enter a file name to process:")
And, I'm not sure what I should do- if I should scrap this whole idea for a simple try: open(filename, 'r') / except: function of it=f there's anyway to salvage this.
So, I thought to fix it this way:
def inputAndRead():
"""prompts user for input, reads file & throws exception"""
filename = None
while (filename is None):
inputFilename = input("please enter a file name to process")
try:
filename = inputFilename
open(filename, 'r')
except OSError:
print("That file doesn't exist")
return filename
inputAndRead()
lineCount = 0
wordCount = 0
charCount = 0
with open(filename, 'r') as file:
for line in file:
word = line.split()
lineCount = lineCount + 1
wordCount = wordCount + len(word)
charCount = charCount + len(line)
print("the number of lines in your file is:", lineCount)
print("the number of words in your file is", wordCount)
print("the number of characters in your file is:", charCount)
But, I'm getting error: NameError: name 'file' is not defined
I would reorganize this code so that the file is opened in a loop. No matter how many times the user enters an invalid filename, the code will just ask for a new one and try again.
lineCount = 0
wordCount = 0
charCount = 0
f = None
while f is None:
filename = input("please enter a file name to process:")
try:
f = open(filename)
except OSError:
print("That file doesn't exist")
for line in file:
word = line.split()
lineCount = lineCount + 1
wordCount = wordCount + len(word)
charCount = charCount + len(line)
print("the number of lines in your file is:", lineCount)
print("the number of words in your file is", wordCount)
print("the number of characters in your file is:", charCount)
Write an infinite loop while True. When the file name is correct, at the end of the try, add a break.
Glad that helps

Categories