python3: how to enable strong typing? - python-3.x

Is there a way to get real strong typing in python3, such that one gets a runtime error, when the wrong type is used?
See following example:
def pick(k:int = None):
if k: print("value: ", k)
else: print("no value")
pick()
pick(1000)
pick("error")
this gives the following output:
no value <- can be accepted, and for this example it would be useful
value: 1000
value: error <- here should come a runtime error

Check this, hope will help. This is one of the way to force type checking.
def pick(k:int = None):
assert isinstance(k, int), 'Value Must be of Interger Type'
print("value: ", k) if k else print("no value") # Single Line Statement
In case of None or string it will raise AssertionError
AssertionError: Value Must be of Interger Type
However if you really need ValueError to be raise then
def pick(k:int = None):
if not isinstance(k, int):
raise ValueError('Value Must be of Interger Type')
print("value: ", k) if k else print("no value") # Single line statement
Exception
ValueError: Value Must be of Interger Type

Related

Why does having a return statement in my try block make the 'else' statement unreachable?

I'm learning exception handling in Python3 and can't seem to understand why the else statement in my if-else block is unreachable when using return in the try block.
def simple_division() -> float:
"""
:return: the quotient of a / b
"""
a, b = _git_int()
if a == 0:
return 0
else:
try:
return a / b
except ZeroDivisionError:
print("Uh, you can't divide by zero, bud.")
else:
print("This should execute if no exceptions are raised, right? but it doesn't")
finally:
print("This should execute either way.")
I spent some time debugging in order to figure out that the return statement in the try block was at fault... and I now understand that doing something like this circumvents the problem:
def simple_division() -> float:
"""
:return: the quotient of a / b
"""
a, b = _git_int()
if a == 0:
return 0
else:
try:
answer = a / b
except ZeroDivisionError:
print("Uh, you can't divide by zero, bud.")
else:
print("This DOES work")
return answer
finally:
print("This should execute either way.")
But I haven't yet found any documentation explaining why you can't have a return statement in a try block. Could someone explain this to me? What would be the best practice here?

Additional ValueError Exception

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")

TypeError: method() takes 0 positional arguments but 1 was given

I wrote an input function python program,
But when run that code , IDE show that, "this function need to pass argument"
Even though ,I didn't declare any argument enter image description here
please help me how to solve this problem , Thank you in advance
list_number = list()
def input():
while True:
try:
number = input("Enter your number in to list = ")
if number == "Quit":
break
number = int(number)
list_number.append(number)
print(list_number)
except ValueError as e:
print(e)
def diagram():
display = ""
for i in list_number:
for j in range(i):
display = display +"#"
print(display)
display = ""
input()
diagram()
Several errors are noticed at glance:
mixture of namespace
You declared list_number as a global variable, but you cannot set value to it
directly insides a function. Instead, you can let the function return a value,
or use global statement to temporary allow a function to set a value to
a global variable temperary.
Read more on offical document, or search keyword python namespace for
relative articles.
name collision on builtin keyword
Some special word are reserved by python and could not be used as variable or
function name, input is amoung them.
BTW: The title of your question and example code layout is confusion! Follow the
tour to learn how to ask a better question and improve layout, so that people
can help you out.
Example code: though the test part has some bug I don't solved...
# remove: move it to a main progress for future design
# list_number = list()
# rename: input is a reserved name of builtins, pick another word
def myinput(*pargs):
if pargs:
for arg in pargs:
try:
yield int(arg)
except ValueError:
pass
else:
count = 0
while True:
# move out of `try` statement as it won't raise any exceptions
# imply lowercase for easier string comparison
userinput = input("Enter your number in to list: ").lower()
if userinput in ['quit', 'q']:
# for interactive, give user a response
print("Quit input procedure. Preparing Diagram...")
break
try:
number = int(userinput)
except ValueError:
# raise a error and the output will print to output by default
# there is no need to `print` an error
# and, for improve, you can raise a more specific message
# and continue your program
msg = "The program wants a number as input, please try again.\n"
msg += "Type `Quit` to exit input procedure."
print(msg)
continue
except KeyboardInterrupt:
msg = "You pressed Interrupt Keystroke, program exit."
print(msg)
return 0
# print a message and pass the value intercepted
count += 1
print("%d: number %d is added to queue." % (count, number))
yield number
def diagram(numbers):
# there is no need to iter a list by index
# and I am **not** sure what you want from your origin code
# if what you wnat is:
# join number with "#" sign
# then just use the builtins str.join method
# valid: is_list_like
if is_list_like(numbers):
numstr = map(str, numbers)
ret = "#".join(numstr)
else:
ret = "Nothing to export."
return ret
def is_list_like(obj):
"""fork from pandas.api.types.is_list_like,
search c_is_list_like as keyword"""
return (
# equiv: `isinstance(obj, abc.Iterable)`
hasattr(obj, "__iter__") and not isinstance(obj, type)
# we do not count strings/unicode/bytes as list-like
and not isinstance(obj, (str, bytes))
)
def main(*pargs):
# get a generator of user input
# if passed in values, accept parameter as user input for test
msgout = ""
if pargs:
# bug: test input not filtered by int() function
list_number = list(myinput(pargs))
print("Run builtin test module.")
else:
list_number = list(myinput())
count = len(list_number)
# process your input by whatever means you need
if count == 1:
msgout += "Received %d number from user input.\n" % count
else:
msgout += "Received %d numbers from user input.\n" % count
msgout += "The diagram is:\n%s" % diagram(list_number)
print(msgout)
def test():
"""simulate user input"""
userinputs = [
['a', 1, 5, 4, 9, 'q'],
[999, 'Quit'],
['q'],
]
for userinput in userinputs:
main(*userinput)
# test bug:
# 1. charactor is printed as output, too
if __name__ == "__main__":
# remove test() if you don't need it
test()
main()
Well I would change your function name from input to something else because you cannot have any function named anything from base python named in your function, This is probably the reason for your error.
Like the others said, input() is a builtin function in Python. Try this following code:
list_number = list()
def input_func():
while True:
try:
number = input("Enter your number in to list = ")
if number == "Quit":
break
number = int(number)
list_number.append(number)
print(list_number)
except ValueError as e:
print(e)
def diagram():
display = ""
for i in list_number:
for j in range(i):
display = display + "#"
print(display)
display = ""
input_func()
diagram()
Also, nice to note that try should be used more precisely only where the exception is expected to be thrown. You could rewrite input_func with that in mind, such as:
def input_func():
while True:
number = input("Enter your number in to list = ")
if number == "Quit":
break
try:
number = int(number)
except ValueError as e:
print(e)
else:
list_number.append(number)
print(list_number)

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

Valid checking, Raising an exception

The code I'm trying to write take a string in the format 'command arg1 arg2', Right now, I'm stuck and not sure how to write a valid command check, where the valid command is 'add' or 'sub' or 'mul' or 'div'. If the command is not a valid command, it raises InvalidCommand().
Here's my code:
class InvalidCommand(Exception):
pass
def validate_input(string):
"""
validate_input(str) -> (str, [float])
If string is a valid command, return its name and arguments.
If string is not a valid command, raise InvalidCommand
Valid commands:
add x y
sub x y
mul x y
div x y
Arguments x and y must be convertable to float.
"""
li = []
if len(string.split(' ')) != 3:
raise InvalidCommand()
else:
try:
float(string.split(' ')[1])
float(string.split(' ')[2])
except ValueError:
raise InvalidCommand()
x = float(string.split(' ')[1])
y = float(string.split(' ')[2])
li.append(x)
li.append(y)
z = (string.split(' ')[0], li)
return z
I think this can do bro
VA=['add', 'sub', 'mul', 'div']
string=string.split()
if string[0] not in VA:
raise InvalidCommand()
elif len(string) !=3:
raise InvalidCommand()
else:
try:
return (string[0],[float(string[1]),float(string[2])])
except ValueError:
raise InvalidCommand()

Resources