Python - forcing function inputs [duplicate] - python

This question already has answers here:
Pythonic way to have a choice of 2-3 options as an argument to a function
(9 answers)
Closed 3 months ago.
I need to force function inputs to take specific values. Without writing if, else blocks inside the function, is there any way to specify certain inputs beforehand ?
def product(product_type = ['apple','banana']):
print(product_type)
But the function requires product_type as single string (product('apple') or product('banana')), and gives error when typed different values.

Without writing if, else blocks inside the function, is there any way to specify certain inputs beforehand ?
Not really.
You can use typing with an Enum or a Literal but that assumes a type checker is actually being run on the codebase in all cases.
Python is otherwise dynamically, it will not normally validate parameters, if you need that you must do it internally. Though you do not need an if: else: block inside the function, you can just use an assertion:
def product(product_type: Literal['apple', 'banana']):
assert product_type in ['apple','banana']
print(product_type)
This way the input will be
actually checked at runtime
documented for IDEs and friends
optionally checked at compile-time

Related

'Force' Python to evaluate all boolean expressions [duplicate]

This question already has answers here:
How to prevent short-circuit evaluation?
(3 answers)
Closed 4 years ago.
Most languages have a way to force 'fail early and often' through forcing all booleans in an if to be evaluate.
Suppose I have the following if statement in Python:
if(age>100 or patient_is_brain_dead or patient_lacks_left_arm):
do something...
The problem is I may have forgotten to set either boolean for 'patient_is_brain_dead or 'has_no_left_arm'.
Since most alive people are under 100, tests 2 and 3 happen rarely since Python, seeing the 'or' coming ahead, stops evaluating if age<100 to save time.
My code is heavily compute-bound, so the overhead of testing all three cases will not degrade performance, but would catch a lot of potential bugs that would happen potentially in one-in-500 cases.
Is there a way to force Python to evaluate them all? Don't suggest reversing the order, because any case could be the rare one(s) depending on user input.
In my opinion, you shouldn't want to do this in production code. If a couple of variables should be Boolean and you need to check if either of them are True, you should use short-circuiting logic.
So what are your options if, as you say, you want to make sure your code doesn't fail on edge cases? You can use unit testing to test all viable scenarios. But this may be overkill for your use case. You can just use an assert statement:
assert all(isinstance(i, bool) for i in [patient_is_brain_dead, patient_lacks_left_arm])
if age > 100 or patient_is_brain_dead or patient_lacks_left_arm:
# do something...
The benefit of such a solution is it's possible to turn off assert statements via command line -O for production code. While, for testing purposes, you can be sure your variables are of the correct type.
No, you will need to explicitly check for None. It is not a "roundabout" way, that is just how the language works.
If you want the conditional to fail if any of the variables are not set, you can use all() to check that they aren't None:
if(all(i is not None for i in [age, patient_is_brain_dead, patient_lacks_left_arm]) and
(age > 100 or patient_is_brain_dead or patient_lacks_left_arm)):
do something...

Functions in Python with or without parentheses? [duplicate]

This question already has answers here:
What does it mean when the parentheses are omitted from a function or method call?
(6 answers)
Closed 2 years ago.
In Python, there are functions that need parentheses and some that don't, e.g. consider the following example:
a = numpy.arange(10)
print(a.size)
print(a.var())
Why does the size function not need to be written with parentheses, as opposed to the variance function? Is there a general scheme behind this or do you just have to memorize it for every function?
Also, there are functions that are written before the argument (as opposed to the examples above), like
a = numpy.arange(10)
print(np.round_(a))
Why not write a.round_ or a.round_()?
It sounds like you're confused with 3 distinct concepts, which are not specific to python, rather to (object oriented) programming.
attributes are values, characteristics of an object. Like array.shape
methods are functions an object can run, actions it can perform. array.mean()
static methods are functions which are inherent to a class of objects, but don't need an object to be executed like np.round_()
It sounds like you should look into OOP: here is a python primer on methods.
Also, a more pythonic and specific kind of attributes are propertys. They are methods (of an object) which are not called with (). Sounds a bit weird but can be useful; look into it.
arrange returns an ndarray. size isn't a function, it's just an attribute of the ndarray class. Since it's just a value, not a callable, it doesn't take parenthesis.

Difference between functions that act alone and those with the "dot" operator [duplicate]

This question already has answers here:
What's the difference between a method and a function?
(41 answers)
Closed 7 years ago.
I am a little confused about functions in Python, and how they are classified. For one, we have functions like print(), that simply encode some instructions and act on input. But also, we have functions like 'str'.capitalize(), that can only act when they have an "executor" attached to them. This might not be a well-informed question, but what are the differences between these forms, and how are they classified?
print() is a function in python3 (in python2 it was a statement), and capitalize() is a method.
Please take a look at this answer to clear things up a little bit.
Python is a multi paradigm language that you can write structural and object oriented. Python has built-in functions and built-in classes; for example when you use sequence of characters between two quotation mark (') you instantiate string class.This instance called object. Objects may contain functions or/and other objects. you can access internal functions or object with DOT.
Python is object oriented. This means we have "objects", which basically enclose their own data, and have their own methods. a String is an example of an object. Another example would be if you have a Person object. You can't just do walk(), you have to do Miles.walk(). You could try walk(Miles). But not everything can walk, so we make the function walk() specific to Person objects.
So yes, Python creators could have made capitalize('str') legal, but they decided to make the capitalize function specific to String objects.
print() is a built in function, you can check that like below..
>>> type(print)
<class 'builtin_function_or_method'>
>>> hasattr(print, '__call__')
True
But capitalize() is method of a str class, you can only use this by using string objects.
>>> hasattr('string', 'capitalize')
True

Check python function signature without a call

My program derives a sequence args and a mapping kwargs from user input. I want to check that input, and then forward it to a python function f (which is chosen based on user input). In this case, a function signature mismatch between f and [kw]args is an input error; I must distinguish it from possible programming errors within the implementation of f, even though they might both raise TypeError.
So I want to check the signature before attempting the function call. Is there a way to do this other than to manually compare [kw]args to the result of inspect.getargspec (or .getfullargspec or .signature in later python versions)?
Related questions: Is there a way to check a function's signature in Python?
The method using inspect is probably the most straightforward way of doing this that exists - it's not something one would normally expect to be doing in Python.
(Typically, allowing end users to call arbitrary functions with arbitrary inputs is not what a programmer wants.)

Modify parameter as a side-effect in python [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Python: How do I pass a variable by reference?
I'm trying to write a function that modifies one of the passed parameters. Here's the current code:
def improve_guess(guess, num):
return (guess + (num/guess)) / 2
x = 4.0
guess = 2.0
guess = improve_guess(guess, x)
However, I want to write the code in such a way that I don't have to do the final assignment. That way, I can just call:
improve_guess(guess,x)
and get the new value in guess.
(I intentionally didn't mention passing-by-reference because during my net-searching, I found a lot of academic discussion about the topic but no clean way of doing this. I don't really want to use globals or encapsulation in a list for this.)
You can't do this directly since integer and floating-point types are immutable in Python.
You could wrap guess into a mutable structure of some sort (e.g. a list or a custom class), but that would get very ugly very quickly.
P.S. I personally really like the explicit nature of guess = improve_guess(guess, x) since it leaves no doubt as to what exactly is being modified. I don't even need to know anything about improve_guess() to figure that out.
But those are the only two ways to do it: either use a global, or use a mutable type like a list. You can't modify a non-mutable variable in Python: doing so just rebinds the local name to a new value.
If you really don't like wrapping in a list, you could create your own class and pass around an instance that will be mutable, but I can't see any benefit in doing that.

Categories