Exception Handling, function attempting to convert a string into an integer - python

I am trying to write a function which turns a string into an integer, with an exception to catch anything which is not a digit and return a SyntaxError. The try here should take a string and return an integer if all characters in the string are digits. An example value of (sti) would be 12a34.
def string2int(sti):
try:
int(float(sti))
if sti.isdigit():
return sti
except Exception, e:
raise SyntaxError('not an integer')
Trying to iron it out in a python visualizer gives me an attribute error on line 4:
AttributeError: 'float' object has no attribute 'isdigit'
There is an all_digits function I can use that takes a string and returns True if all the characters of the string are digits and False otherwise, but I haven't been able to get the try to work using that either.
How can I write this so that if the string does represent a positive integer then that integer is returned?

def string2int(sti):
try:
return int(sti)
except ValueError:
raise SyntaxError('not an integer')
Or:
def string2int(sti):
if sti.isdigit():
return int(sti)
else:
raise SyntaxError('not an integer')

In your function if sti is an integer, this should simply work, but just for regular integers like 123 not even "+1" or "1e2":
def string2int(sti):
try:
if sti.isdigit():
return sti
So you can use regular expressions:
import re
matchInt = re.match("^\+?[0-9]+([eE][0-9]+)?$",sti)
if matchInt:
return sti
This regular expression matches against all (positive) integers shown regularly or in scientific notation.

Related

Building a function to capture non-blank 'Int' from the User in Python

I have a command line console game where I'm trying to capture integers from the User (the game is for learning times tables). I built a re-usable function to handle this which is working for blank answers, however will break if the User enters a string (e.g. "abc").
Can someone help me extend this function to filter out strings as well? (e.g. they should be asked to enter a number). I believe the error is being caused by the casting of int() in the return statement, however I need the input to be an Int for answer-checking comparison purposes (e.g. I compare their input to a stored answer, for which I need an Int == Int comparitor).
Function:
# gets a non-blank int from the User, printing a prompt and optionally displaying an error prompt
def get_int(prompt, err_prompt):
input_int = ""
# if entry is blank
while not input_int:
try:
# enter input
input_int = input(prompt)
if not input_int:
raise ValueError(err_prompt)
except ValueError as err:
print(err)
return int(input_int)
Calling the function example:
# get a non-blank int from the User as a guess
# note 'current_q' is a string from a list, e.g. "2 x 2 = " which acts as the prompt
guess = get_int(current_q, "You don't have a lot of other options. Try guessing a number...\n")
Example of the code working for blank answers:
Example of the code not working for strings:
Your if statement is wrong here:
if not input_int:
raise ValueError(err_prompt)
It will not raise an error if the value is not an empty string since its 'truthy'.
Instead you need to manually convert the input to an int and catch error:
def get_int(prompt, err_prompt):
input_int = ""
# if entry is blank
while not input_int:
try:
input_int = int(input(prompt)) # convert input to int
except ValueError:
print(err_prompt) # if the value can't be converted simply print your existing error prompt
return input_int
You could use isdigit on the input to check if it's an int before you cast it.
def get_int(prompt:str, error:str):
while not (u:=input(prompt)).isdigit():
print(error)
return int(u)

Restrict user from entering non-numeric value

I am writing a code which should use only def (). input() cannot be used inside def(). When a numeric value is passed, it is okay. When string (e.g. Five, ten, etc.) is provided, it returns NameError. How to fix this issue using try and except.
def num(n):
try:
return int(n)
except NameError:
print('Error: Enter numeric nalue')
return
num(Five)
output: NameError: name 'Five' is not defined
I am using Anaconda 2020.2 (Python3.7.6 64-bit)
Two issues:
When you are trying to test your routine with a string value, you are trying to code the string constant without the quotes, so that it is instead trying to look up the non-existent variable Five, hence the NameError. You need quotes around it (i.e. 'Five').
Inside your function, the relevant exception to look for in the case of non-numeric data is a ValueError.
Example with these corrected:
def num(n):
try:
return int(n)
except ValueError:
print('Error: Enter numeric value')
return
print(num('Five'))
below
(the idea is to return a tuple from the function call. first tuple element is a boolean that tells if we have a valid int. second tuple element can be the actual int or a string that explains why we cant convert the input to int)
def to_int(val):
try:
result = int(val)
return True,result
except ValueError:
return False,'{} is not a valid integer'.format(val)
print(to_int(7))
print(to_int('ttt'))
output
(True, 7)
(False, 'ttt is not a valid integer')
Try this :
def num(n):
try :
return int(n)
except:
raise NameError("Please provide an integer value")
num('five')

How to remove quotes from a single value in a list in python?

I have a list as :
a=[u'hello',u'well',u'1024']
I want to have it as :
a=[u'hello',u'well',1024]
So please suggest how will i have it.
Python Map and a conversion function with try catch will do
lst=[u'hello',u'well',u'1024']
def conversion(value):
try:
return int(value)
except Exception:
return value
map(conversion,lst)
[u'hello', u'well', 1024]

Raising an exception

This is a homework problem. I've been trying to solve it but couldn't get the right result.
This is the question:
Write a function string2int that attempts to convert a string to an integer. If the string does represent a positive integer then that integer should be returned. If the string does not represent a positive integer then you should raise a syntax exception (raise SyntaxError('not an integer')).
You may choose to use the (already defined) function all_digits that takes a string and returns True if all the characters of the string are digits and False otherwise.
What I've got so far is:
try all_digits is True:
return int(num)
except all_digits is False:
raise SyntaxError('not an integer')
Because I'm using an already defined function, I didn't define a function (or did I get it wrong?).
Can anyone have a look at my code please? Much appreciated.
I can guess, but you might want to tell us what kind of error you get when you execute the code (just a heads up for the next time you ask a question).
There's a couple of mistakes:
1) The syntax of
try all_digits is True:
is wrong. The "try" statement should look like this:
try:
<your code>
except <type of exception to catch>:
<error handling code>
2) You said "all_digits" is a function. Therefore, the code
all_digits is True
should be
if all_digits(num):
Putting it all together:
def string2int(num):
if all_digits(num):
return int(num)
raise SyntaxError('not an integer')
In addition to Rawing's excellent answer, note that the usual time to use try/except is when you can handle the error thrown in the try block and continue as usual. For instance:
def add_three(x) -> int:
try:
return x + 3
except TypeError:
# someone passed a non-int/float to the function!
# let's try and coerce it.
return int(x) + 3
# if this still throws an exception, we'll let it
# raise its own TypeError exception!
In your case it looks like you're just doing regular conditionals, so use if all_digits(num): return int(num) else: raise TypeError('not an integer')
all_digits(string) function:
First, it's good to understand what does the pre-defined all_digits(string) function do. Following is a sample implementation of that function, which works as desired by your description. It checks whether each letter of the string is a digit and returns a boolean, True or False, accordingly:
def all_digits(string):
''' only returns True if all characters of the string are Integers '''
for l in string:
if l.isdigit(): pass
else: return False
return True
string2num(string) function with raise statement:
Now, we can use this function in our error handling block of the string2num(string) function. Since your problem requires you to only raise a specific exception and not to continue with an alternate block of code, you do not need the try: ... except: block.
With the proper syntax of the raise statement, we can write:
def string2num( string = '-23'):
if all_digits(string):
return int('23')
raise SyntaxError("not an integer")
and we get:
>>> string2num()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 4, in string2num
SyntaxError: not an integer
with try: ... except: ... block:
But if you do want to execute an alternate block of code when the exception is raised, you can use the try: ... except: block syntax. You may need it, for instance, if you want to further check if the string is a negative integer and if so then return the negative integer:
def string2num( string = '-23'):
try:
if all_digits(string):
return int(string)
raise SyntaxError("not an integer")
except SyntaxError:
#alternate code goes here#
try:
return int(string)
except ValueError:
print "string contains an alphabet"
This will produce:
>>> string2num()
-23
>>> string2num('ab2')
string contains an alphabet
Style for if statement:
As a side note on your style, you don't have to explicitly write whether an expression evaluates to True or False in an if statement, like so:
if all_digits(string) is True:
Since all_digits(string) returns a boolean, you can equivalently just say if True, like so:
if all_digits(string):

Python type() function issue, str not callable

I am working on validating a certain piece of data, in this case the strin g 'five' should fail a certain piece of validation because it needs to be 5 (an int)
print ">>>>", value
bad_type = type(value).__name__
raise TypeError("expected numeric type for {0} but got '{1}'".format(column,bad_type))
prints:
.>>>> five
...
bad_type = type(value).__name__
TypeError: 'str' object is not callable
However I can do this from the command line:
python -c "print type('five').__name__"
prints
str
what am I doing wrong here? I want to print the type of the value that was passed and failed my custom validation.
Are you sure you haven't over-ridden type somewhere?
Also, that's not the Pythonic way for type checking - instead use:
try:
my_int = int(value)
except (ValueError, TypeError) as e:
# raise something

Categories

Resources