In my exception handling, I'm trying to catch ZeroDivisionError's but for some reason, the code is still doing the division by 0 and not bringing back an error. I must be doing something wrong but I can't seem to place it.
I have tried to move the division elsewhere in the function, and move the division error catch as well.
filename = "numbers.txt"
def main():
total = 0.0
number = 0.0
counter = 0
average = 0
#Open the numbers.txt file
try:
infile = open(filename, 'r')
#Read the values from the file
for line in infile:
counter = counter + 1
number = float(line)
total += number
average = total / counter
#Close the file
infile.close()
except IOError:
print('An error occurred trying to read the file', end=' ')
print(filename, '.', sep='')
except ValueError:
print('Non-numeric data found in the file', end=' ')
print(filename, '.', sep='')
except Exception as err:
print('A general exception occurred.')
print(err)
except ZeroDivisionError:
print('Cannot devide by zero.')
else:
print('Average:', average)
print('Processing Complete. No errors detected.')
# Call the main function.
main()
I'm expecting the result to return the error message when dividing by zero, but it's returning zero as the answer instead.
You need to change the order that you catch exceptions. Since all exceptions in Python inherit from the Exception base class, you are never getting the ZeroDivision exception since it is caught by handling of Exception. Try this:
except IOError:
print('An error occurred trying to read the file', end=' ')
print(filename, '.', sep='')
except ValueError:
print('Non-numeric data found in the file', end=' ')
print(filename, '.', sep='')
except ZeroDivisionError:
print('Cannot devide by zero.')
except Exception as err:
print('A general exception occurred.')
print(err)
else:
print('Average:', average)
print('Processing Complete. No errors detected.')
It seems like there is no ZeroDivisionError in your file. Because in your for loop, you have incremented counter variable by 1 already. Unless, the for loop is iterating into an empty object.
Hence, your average = total / counter will always start as:
average = total / 1 (since counter = counter + 1)
Hope it helped.
Related
So, I'm doing this assignment and I can't seem to figure out how to continue on to the next step.
assignment output example
The file numbers.txt contains the following numbers all on separate lines (25, 15, 5, six, 35, one, 40).
My problem is that I can only print out one ValueError message (six), but I need to be able to print out both messages (invalid literal for int() with base 10: 'six\n', invalid literal for int() with base 10: 'one\n').
Since I can't get the codes to move on to the next iteration, my average only adds 25, 15, and 5.
I've only been learning Python for a month so I don't know if there's a simple way to solve all these problems.
Below is the code I am working on.
def main():
while True:
try:
filename = input("Enter a file name: ")
infile = open(filename, "r")
except IOError:
print("[Error No. 2] No such file or directory:", filename)
continue # continue to next iteration
else:
break
data = infile.readline().strip()
numbers = data.split()
total = 0
count = 0
try:
infile = open(filename, "r") #somehow without this, the first line won't print
for line in infile:
num = int(line)
print(num)
total += num
count += 1
print("The average is: ", total/count)
except ValueError as err:
print(err)
finally:
print(total/count)
main()
You can repositioning your try statement in the second loop like so:
data = infile.readline().strip()
numbers = data.split()
total = 0
count = 0
infile = open(filename, "r")
for line in infile:
try:
num = int(line)
print(num)
total += num
count += 1
except ValueError as err:
print(err)
print("The average is: ", total/count)
This way, you won't exit the loop once you encounter an error message, and will simply print it and move on to the next line.
Try the below
# open the file using 'with' - it will make sure that the file will be closed
with open('input.txt') as f:
values = []
# read the lines into a list
lines = [l.strip() for l in f.readlines()]
for line in lines:
# try to convert to int
try:
x = int(line)
values.append(x)
except ValueError as e:
print(e)
# calculate the average
print(f'Avg: {sum(values)/len(values)}')
input.txt
25
15
5
six
35
one
40
output
invalid literal for int() with base 10: 'six'
invalid literal for int() with base 10: 'one'
Avg: 24.0
You need to indent your while True as currently the main function is causing an error.
You should also do an if line == ‘six’:
line = 6
You can set the try-except block inside the for loop which should produce the correct results.
data = infile.readline().strip()
numbers = data.split()
total = 0
count = 0
infile = open(filename, "r")
for line in infile:
try:
num = int(line)
total += num
count += 1
except ValueError as err:
print(err)
print("The average is: ", total/count)
How can I optimize this code for large amount of input? Out of 5, 3 test case are failing because code is taking too long to execute.
n = int(input())
phonebook=dict([map(str,raw_input().split()) for x in range(n)])
while True:
try:
name = raw_input()
except EOFError as e:
break
if name not in phonebook.keys():
print("Not found")
else:
print(name +"="+phonebook[name])
You can turn the phonebook's keys into a set, sets are faster at lookup than lists
last 4 line in one
print(name +"="+phonebook[name]) if phonebook.get(name) else print("Not found")
This line is probably taking too much time:
if name not in phonebook.keys():
Because you are going over all the keys in the dictionary and compare it with input. You can use in keyword to check if a key exists directly without iterating over keys
n = int(input())
phonebook=dict([map(str,raw_input().split()) for x in range(n)])
while True:
try:
name = raw_input()
except EOFError as e:
break
if name not in phonebook:
print("Not found")
else:
print(name +"="+phonebook[name])
Or you can use exception handling on key error like so, it is better practice:
n = int(input())
phonebook=dict([map(str,raw_input().split()) for x in range(n)])
while True:
try:
name = raw_input()
print(name +"="+phonebook[name])
except EOFError as e:
break
except KeyError as e:
print ("Not found")
I am beginner to python and I have doubt in one program when using try except part
I try to take input from user and add that number by 1 like if you enter 5 then 6 will be printed but if you enter string then except would come in role and print enter only number
I've written code but except is not working there, code is working like if I enter 5 then 6 gets printed but except statement is not working
Here is the code that I've written
def increment(num):
try:
return num + 1
except Exception as e:
print("ufff error occured :", e)
n = int(input("enter your num: "))
a = increment(n)
print(a)
You would have to change to the following:
def increment(num):
try:
return int(num) + 1
except Exception as e:
print("ufff error occured :", e)
n = input("enter your num: ")
a = increment(n)
print(a)
The reason for that is that the exception was raised by the int() functions, because it couldn't convert your input to int. The call to int() was before the increment function. Therefore the exception was unhandled.
You tried converting the input to int before going into the try/except block. If you just put it in the try block it will work.
def increment(num):
try:
num = int(num)
return num + 1
except Exception as e:
print("ufff error occured :", e)
n = input("enter your num: ")
a = increment(n)
print(a)
You have to use the type conversion within the try block so that if num is not a number, the controller would move to expect portion.
The problem here is you are using type conversion outside of try-catch block.
Another point to note, convert e to string as a good practice.
Third point to note,the last line print(a) will itself cause trouble in cases of exception as you have returned nothing from the exception part and directly printed the error. Use a return statement in there else it would return None type and which itself will mess up the flow.
def increment(num):
try:
return int(num) + 1 #Updated Line
except Exception as e:
return "ufff error occurred :" + str(e) #Updated Line
n = input("enter your num: ")
a = increment(n)
print(a)
Might I recommend the following?
def increment(num):
try:
return int(num) + 1
except Exception as e:
print("ufff error occurred:", e)
n = input("enter your num: ")
a = increment(n)
print(a)
The only difference here is that the attempt to convert the user's input to an int occurs within the try-except block, rather than outside. This allows the type conversion error to be caught and your message ("ufff error occurred: ...") to be displayed.
Edit: regarding your comment:
yes it worked out thanks everyone, but can anyone tell what should i have to do if i use int with input line what changes i've to make
Optionally, you could do the following:
def increment(num):
return num + 1
try:
n = int(input("enter your num: "))
a = increment(n)
print(a)
except Exception as e:
print("ufff error occurred:", e)
In this case, I would recommend removing the try-except block in the increment function, because you can safely assume that all values passed to that function will be numeric.
The only code that would raise an exception is the int(...) conversion - and it is not protected under a try/except block. You should put it under the try:
def increment():
try:
return int(input("enter your num: ")) + 1
except ValueError as e:
return f"ufff error occured: {e}"
print(increment())
You should always try to catch the narrowest exception. In this case, a ValueError.
Task1
Write a script that reads a string from STDIN and raise ValueError
exception if the string has more than 10 characters or else prints the
read string.
I wrote the code like this
a = input("Enter a string")
if(len(a) > 10):
raise ValueError
else:
print(a)
Task2
Use try ... except clauses. Print the error message inside except
block.
I am now confused about how to use try-except here because to print any message in except block the program has to fail at try block.
My input will be PythonIsAmazing
You can just wrap the whole thing in try ... except as follows:
a = input("Enter a string: ")
try:
if(len(a) > 10):
raise ValueError
print(a)
except ValueError:
print("String was longer than 10 characters")
Alternatively, if you had lots of different ValueErrors that might be raised, you could give each a separate error message:
a = input("Enter a string: ")
try:
if(len(a) > 10):
raise ValueError("String was longer than 10 characters")
print(a)
except ValueError as e:
print(e)
Eg:
Enter a string: test
test
Enter a string: PythonIsAmazing
String was longer than 10 characters
I am trying to complete this assignment but I get the error:
[Errno 13] Permission denied: 'D:\Temperatures.txt'
is there something I am doing wrong here?
I have tried multiple changes and keep getting the same result.
Create Class
class tempearutefile:
def __init__(self, filename):
self.__filename = filename
def set_filename(self, filename):
self.__filename = filename
def get_filename(self):
return self.__filename
def calculateAverage(self, num1,num2,num3):
try:
total = num1+ num2+ num3
average = total/3
return average
# exception errors
except ValueError as err:
print(err)
except IOError as err:
print(err)
except Exception as err:
print(err)
def main():
try:
#Getting input from the users
num1=float(input("Please enter your first value: "))
num2=float(input("Please enter your second value: "))
num3=float(input("Please enter your third value: "))
#Creating temperatue file
test_file = open('D:\\Temperatures.txt', 'w')
#writing input informatin to the file
test_file.write(str(num1) + '\n')
test_file.write(str(num2) + '\n')
test_file.write(str(num3) + '\n')
#closing file
test_file.close()
temp1 = tempearutefile(test_file)
average = temp1.calculateAverage (float(num1),float(num2),float(num3))
print("your average temperature is:", average)
# exception errors
except ValueError as err:
print(err)
except IOError as err:
print(err)
except Exception as err:
print(err)
#Call to main
main()
Expecting an average temperature from 3 inputs.