Why ValueError is not displayed - python

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.

Related

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)

try/except block catching multiple exceptions

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.

Reading a file and converting it into a dictionary

I have this text file:
this is name_of_liquid(string)=amount(int)
liquid1=200
liquid2=20
liquid_X_= empty
liquid_3= 3000
now, the name does not really matter however the amount does. It has to be an int.
If it is any other type beside int the program would raise an exception
Here is my code/ pseudocode:
#opening the file
d={}
try:
dic = {}
with open('accounts.txt') as f:
for line in f:
(key , val) = line.split()
d[key] = int(val)
#except ValueError:
# print('The value for', key,'is', value,' which is not a number!')
the except block is commented because that is my pseudocode and how I planed in handling the
error, but when I run this code without using exception handling, I get an error of 'not enough values to unpack'
Can anyone please help me?
Try this
f = open("acounts.txt", "r")
dict = {}
try:
for line in f:
line = line.split("=")
dict[line[0]] = int(line[1])
except:
print("Invalid value for key.")
You should split the lines with = as delimiter and strip the list to get rid of extra whitespaces.
I personally think that the try catch block should be used while adding elements to the dictionary.
The following code should work for your problem.
d = {}
with open('accounts.txt', 'r') as f:
for line in f:
(key , val) = map(str.strip,line.split("="))
try:
d[key] = int(val)
except ValueError:
print('The value for', key,'is', val,' which is not a number!')

How can I make my function handle an exception?

I have a function which looks like this
def read_data(input_file_name):
""" (str) -> list, list
Read data from the path specified by the string input_file.
Data looks like:
18, 120
20, 110
22, 120
25, 135
Output two lists, one for each column of data.
"""
try:
with open(input_file_name) as input_file:
lines = input_file.readlines()
n = len(lines)
x = list(range(n))
for i in range(n):
x[i] = lines[i].strip()
a = []
b = []
if x is None:
raise TypeError
a = None
b = None
else:
for i in x:
c,d = i.split(",")
a.append(float(c))
b.append(float(d))
return a,b
except FileNotFoundError:
print("Unable to open and read '{}'".format(input_file_name))
except ValueError:
print("Unable to open and read '{}'".format(input_file_name))
When I make this function to handle the exception it gives me a Type Error.
For example:
e,f = read_data('lol')
Unable to open and read 'lol'
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
e,f = read_data('lol')
TypeError: cannot unpack non-iterable NoneType object
How can I make this function handle an exception if a file doesn't exist and make the function return a tuple of two Nones and output: 'Unable to open and read'?
after you catch the exception, you didn't return anything(it means you return NoneType). But you try to unpack return values(NoneType). So it throws exception.
so avoid this exception, you raise exception again or return a, b again.
except (FileNotFoundError, ValueError) as e:
print("Unable to open and read '{}'".format(input_file_name))
# throw exception again
raise e
or
# outside of try-except
a, b = [], []
try:
# ...
except (FileNotFoundError, ValueError) as e:
print("Unable to open and read '{}'".format(input_file_name))
# return a tuple of empty lists
return a, b

Program not recognizing conditional statements in for loop

I'm trying to print "None" if the input entered by the user is not found in a text file I created. It should also print if the lines if word(s) are found in the text file.
My problem right now is that it is not doing both conditionals. If I were to remove the "line not in user_pass" it would not print anything. I just want the user to be able to know if the strings entered by the user can found in the file and will print that line or "none" if it is not found.
I commented out the ones where I tried fixing my code, but no use.
My code below:
def text_search(text):
try:
filename = "words.txt"
with open(filename) as search:
print('\nWord(s) found in file: ')
for line in search:
line = line.rstrip()
if 4 > len(line):
continue
if line.lower() in text.lower():
print("\n" + line)
# elif line not in text: # the function above will not work if this conditional commented out
# print("None")
# break
# if line not in text: # None will be printed so many times and line.lower in text.lower() conditional will not work
# print("none")
except OSError:
print("ERROR: Cannot open file.")
text_search("information")
I think you need to change for line in search: to for line in search.readlines(): I don't think you're ever reading from the file... Have you tried to just print(line) and ensure your program is reading anything at all?
#EDIT
Here is how I would approach the problem:
def text_search(text):
word_found = False
filename = "words.txt"
try:
with open(filename) as file:
file_by_line = file.readlines() # returns a list
except OSError:
print("ERROR: Cannot open file.")
print(file_by_line) # lets you know you read the data correctly
for line in file_by_line:
line = line.rstrip()
if 4 > len(line):
continue
if line.lower() in text.lower():
word_found = True
print("\n" + line)
if word_found is False:
print("Could not find that word in the file")
text_search("information")
I like this approach because
It is clear where you are reading the file and assigning it to a variable
This variable is then printed, which is useful for debugging
Less stuff is in a try: clause (I like to not hide my errors, but that's not a huge deal here because you did a good job specifying OSError however, what if an OSError occured during line = line.rstrip() for some reason...you would never know!!)
If this helped I'd appreciate if you would click that green check :)
Try this:-
def find_words_in_line(words,line):
for word in words:
if(word in line):
return True;
return False;
def text_search(text,case_insensitive=True):
words = list(map(lambda x:x.strip(),text.split()));
if(case_insensitive):
text = text.lower();
try:
filename = 'words.txt'
with open(filename) as search:
found = False;
for line in search:
line = line.strip();
if(find_words_in_line(words,line)):
print(line);
found = True;
if(not found):
print(None);
except:
print('File not found');
text_search('information');
Didn't really understand your code, so making one on my own according to your requirement.

Categories