Additional ValueError Exception - python-3.x

I am new with exceptions. Especially multiple exceptions.
I am able to excuse this code with positive numbers and raise the ValueError with negative numbers.
My issue is how to "add" an additional exception for ValueError if I were to use a non-integer.
I maybe making it hard than it is.
def findFirstEvenInteger(number_list):
"""Def even integer. The following rest of the function utilizes a modulo operator
that checks if the number is even."""
for element in number_list:
if element % 2 == 0:
return element
raise ValueError
nn = int(input("Please enter any length of elements: "))
meep = []
for x in range(nn):
x = int(input())
meep.append(x)
try:
print("The first even integer in the list: " + str(findFirstEvenInteger(meep)))
except ValueError:
print("All the number are odd")

Related

Unsupported operand type for sum() function

I was working on a simple project to get me more acquainted with Python since it's been a while and the new semester has started.
import math
count = input('Please enter the number of grades: ')
grade_list = []
while count != 0:
grade = input('What was the grade for the first test?: ')
grade_list.append(grade)
count = int(count) - 1
def mean(x):
grade_total = int(sum(x))
grade_count = int(len(x))
mean = int(grade_total) / int(grade_count)
return mean
print(mean(grade_list))
Here's the error I keep running into:
Traceback (most recent call last):
File "C:\Users\hattd\Documents\Python Projects\miniproject1.py", line 17, in <module>
print(mean(grade_list))
File "C:\Users\hattd\Documents\Python Projects\miniproject1.py", line 12, in mean
grade_total = int(sum(x))
TypeError: unsupported operand type(s) for +: 'int' and 'str'
I thought that turning the variables into integers would stop this from happening? What am I missing here?
You never "turn the variables into integers". You read a string from the user and append that to grade_list, and then you pass grade_list (a list of strings) to your mean function, where you eventually pass it to sum by calling int(sum(x)).
You can convert user input to integers by writing grade_list.append(int(grade)):
grade_list = []
count = int(input('Please enter the number of grades: '))
for _ in range(count):
grade = input('What was the grade for the first test?: ')
grade_list.append(int(grade))
This gives us a list of integers instead of a list of strings.
I've applied the same logic to the count variable as well; this simplifies the code in the while loop since we don't need to repeatedly cast count to an integer.
If you enter something that isn't an integer at either of these prompts, your code will fail with a ValueError exception:
Traceback (most recent call last):
File "/home/lars/tmp/python/grades.py", line 15, in <module>
count = int(input("Please enter the number of grades: "))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: invalid literal for int() with base 10: 'a'
If you'd like a friendlier response, you can write a function to read an integer from the user that will re-prompt if they enter an invalid value. Something like:
def get_int_with_prompt(prompt):
while True:
try:
val = int(input(prompt))
return val
except ValueError:
print("Please enter a valid integer.")
You would use it like:
count = get_int_with_prompt("Please enter the number of grades: ")
Note that with these changes, you have a bunch of calls to int in your mean function that are no longer necessary. A cleaned up version of your code might look like:
grade_list = []
count = int(input("Please enter the number of grades: "))
for _ in range(count):
grade = input("What was the grade for the first test?: ")
grade_list.append(int(grade))
def mean(x):
grade_total = sum(x)
grade_count = len(x)
mean = grade_total / grade_count
return mean
print(mean(grade_list))
Of course, there is a statistics.mean function, as well:
import statistics
grade_list = []
count = int(input("Please enter the number of grades: "))
for _ in range(count):
grade = input("What was the grade for the first test?: ")
grade_list.append(int(grade))
print(statistics.mean(grade_list))
And consider some of the answers here if you'd like to ask for something other than "the first test" every time.

Is there a possibility to add "less than" exception to this piece of code in Python?

I'm quite new to coding and I'm doing this task that requires the user to input an integer to the code. The function should keep on asking the user to input an integer and stop asking when the user inputs an integer bigger than 1. Now the code works, but it accepts all the integers.
while True:
try:
number = int(input(number_rnd))
except ValueError:
print(not_a_number)
else:
return number
You can do something like this:
def getPositiveInteger():
while True:
try:
number = int(input("enter an integer bigger than 1: "))
assert number > 1
return number
except ValueError:
print("not an integer")
except AssertionError:
print("not an integer bigger than 1")
number = getPositiveInteger()
print("you have entered", number)
while True:
# the input return value is a string
number = input("Enter a number")
# check that the string is a valid number
if not number.isnumeric():
print(ERROR_STATEMENT)
else:
if int(number) > 1:
print(SUCCESS_STATEMENT)
break
else:
print(NOT_BIGGER_THAN_ONE_STATEMENT)
Pretty simple way to do it, of course you must define ERROR_STATEMENT, SUCCESS_STATEMENT and NOT_BIGGER_THAN_ONE_STATEMENT to run this code as it is, I am using them as place-holder.

How to print the value only which is creating exception in python?

try:
a,b = map(int,input().split())
print(a//b)
except ZeroDivisionError:
print("invalid")
except ValueError:
print("this value _ is not allowed for division")
I need to print the value here _ which is caused for exceptions as "#" or "%"
It looks like you're trying to get something similar to the code showed below. This is possible by using regular expressions (through the search() function of the re module) to find the invalid argument that comes in the exception's (e) arguments (args).
e.args is a tuple that looks like the following when the ValueError is raised because of an invalid input entered:
("invalid literal for int() with base 10: '%'",)
Therefore, we could do something as follows:
import re
try:
a, b = map(int, input().split())
print(a // b)
except ZeroDivisionError:
print("Can't divide by zero")
except ValueError as e:
regex_groups = re.search('\'(.+)\'|\"(.+)\"', e.args[0]).groups()
invalid_arg = regex_groups[0] if regex_groups[0] else regex_groups[1]
print(f"This value: {invalid_arg} is not allowed for division")
Testing:
1 $
This value: $ is not allowed for division
Q 2
This value: Q is not allowed for division
% '
This value: % is not allowed for division
20 ?
This value: ? is not allowed for division
50 2
25

Python code skips try/except clause

I am working on a class assignment in which I need to raise two exceptions.
First Exception: I am supposed to raise and handle an exception if a user's entry is less than 0 or greater than 100. The code should then ask the user for the digit again.
Second Exception: If a particular file is not found, the exception requests the file name and then search happens again.
In both cases, I cannot make the exception happen. In other words, if in the first exception, I enter a digit greater than 100 or less 0, the program continues and simply doesn't record anything for this entry. If I print the user's entry, I get "none" rather than the error message that the except clause should display. Likewise in the second exception, if the file is not found, the code simply stops executing rather than firing the exception.
I have tried manually raising an exception (as in this question/answer), but that creates a traceback which I do not want-- I just want the first exception to print the error message and call a function and the second to request input and call a function.
First exception:
def grade():
#input student's average grade
avgGrade = int(input("Enter average grade: "))
try:
if avgGrade > 0 and avgGrade < 100:
return avgGrade
except ValueError:
print("Grade must be numeric digit between 0 and 100")
grade()
Second exception:
def displayGrades(allStudents):
try:
#open file for input
grade_file = open(allStudents, "r")
#read file contents
fileContents = grade_file.read()
#display file contents
print(fileContents)
grade_file.close()
except IOError:
print("File not found.")
allStudents = input("Please enter correct file name: ")
displayGrades(allStudents)
Sounds like the exercise is to raise the exception and handle it. You really need a loop for continuation rather than recursion, e.g.:
def grade():
while True:
try:
avgGrade = int(input("Enter average grade: "))
if avgGrade < 0 or avgGrade > 100:
raise ValueError()
except ValueError:
print("Grade must be numeric digit between 0 and 100")
continue # Loop again
break # Exit loop
return avgGrade
But this is contrived for the purpose of the exception, as exceptions are not really needed in this case.
For your other example this is less contrived because the downstream function raises the exception, e.g.:
def displayGrades(allStudents):
while True:
try:
with open(allStudents, "r") as grade_file:
...
except IOError:
allStudents = input("Please enter correct file name: ")
continue
break
Though I would caution mixing arg passing and user input in the same function - usually the exception would be caught and handled where the user is originally providing the file name. So in this example, it would probably be the calling function.
For your first one, you have to raise it manually as python won't guess your logic and raise it for you.
def grade():
#input student's average grade
avgGrade = int(input("Enter average grade: "))
try:
if avgGrade > 0 and avgGrade < 100:
return avgGrade
else:
raise ValueError()
except ValueError:
print("Grade must be numeric digit between 0 and 100")
return grade()
For the second one, You have to return the value in the second call.
use return displayGrades(allStudents) instead of displayGrades(allStudents)
Try this:
def get_value(data_list, index):
return data_list[index]
# Sample list data
my_list = ['a', 'b', 'c']

User input accepting str and int (python)

I am new to programming and trying to make the user input accept both integer and strings. I have tried the following coding.. but not sure where I am going wrong. Any suggestions?
noAdults = input("Please enter the number of adults:")
while noAdults.isalpha():
print("Number must be valid and >= 0")
if noAdults.isdigit() and noAdults < 0:
print("Error")
noAdults = input("Please enter the number of adults:")
ValueError: invalid literal for int() with base 10:
I am guessing there is a ValueError because I have used the variable noAdults with isalpha and is making an error because it is in an int?
You need to verify that the input string is valid integer before you can check if it is non-negative
while True:
noAdults = input("Please enter the number of adults:")
try:
noAdults = int(noAdults)
except ValueError:
print("Not a valid number")
continue
if noAdults >= 0:
break
else:
print("Number must be >= 0")
It's throwing the exception before you handle the bad case of string inputs, it fails on the first line. You can check isalpha() before attempting the int(), or you can catch the ValueError exception.
To expand on chepner's solution, with a few extra print lines to show you what is going on:
while True:
noAdults = input("Please enter the number of adults:")
try:
noAdults = int(noAdults)
except ValueError:
print("Not a valid number")
continue
if noAdults >= 0:
break
else:
print("Not greater than 0")
print(noAdults)
This is a fully working version in Python 3.

Resources