How to check arguments passed to the function call are empty? - python

I want the function to simply check if an argument is passed or not. If not, print something, else say some hello and that argument.
Here is sample of my code:
def say_name(name):
if name is None:
print("Hello there")
else:
print("Hello, "+ name + "!")
run code:
class Test(unittest.TestCase):
def test_should_say_hello(self):
self.assertEqual(say_name("Michael"), "Hello, Michael!")
I have tried using None, Kwargs and still not working. How can I check whether argument is passed to the function?

To make a parameter optional assign it a default value:
def say_name(name=None):
if name is None:
print("Hello there")
else:
print("Hello, "+ name + "!")
Addendum: As Barmar pointed out in the comments to your question, your function needs to return a string to make your check work.
def say_name(name=None):
if name is None:
return "Hello there"
else:
return "Hello, "+ name + "!"

To check whether "any" of the argument is passed with the function call
In general, in order to check whether any argument is passed or not, you may create your function using *args (for non-keyworded variable length argument list) and **kwargs (for keyworded variable length argument list). For example:
def check_argument(*args, **kwargs):
if args or kwargs: # check if any among the `args` or `kwargs` is present
return "Argument Passed!"
else:
return "Argument Not passed!"
Sample Run:
# For "non-keyworded" argument
>>> check_argument('something')
'Argument Passed!'
# For "keyworded" argument
>>> check_argument(some_param='some_value')
'Argument Passed!'
# For no argumenet
>>> check_argument()
'Argument Not passed!'
To check if any "specific" argument is passed with the function call
For your scenario, since you only care about one specific parameter name and perform operation based on the value passed, you may assign a default value to it's function definition as:
# v Default value as `None`
def say_name(name=None):
if name is None:
return "Hello, there!"
else:
return "Hello, "+ name + "!"
Above function could be simplified as:
# v setting default name as "there"
def say_name(name="there"):
return "Hello, {}!".format(name)
# Or you may also check it within the format as
def say_name(name=None):
return "Hello, {}!".format(name or "there")
Sample Run:
>>> say_name()
Hello, there!
>>> say_name('StackOverflow')
Hello, StackOverflow!

def say_hello(*name):
if name:
return "Hello, "+name[0]+"!"
else:
return "Hello there!"
This should work

Related

Can I set a default value for an arbitrary argument in python?

Can I set a default value for an arbitrary argument in python? If yes, how to do that...
I tried:
def printf(age, gender, *fave, name = "veronica"):
print(name, " ", gender, " ", age, " ")
print("favefood: ", end = "")
for i in fave:
print(i, end = " ")
printf(25, "f", "water", "grass")
and I got the output as:
veronica f 25
favefood: water grass
now I want to set a default value for *fave, something like
printf(age, gender, *fave = "grass", name = "veronica")
then I received an error message saying "invalid syntax". So I was wondering if I could really do this for an arbitrary argument...
No You Can't
The entire purpose of *args is so that you can send 0 arguments to it without an error:
def f(*args):
print(args)
for arg in args:
print(arg)
f("foo", "bar", "baz")
print("----------------")
f()
print("----------------")
f("Hello", "World")
Output:
('foo', 'bar', 'baz')
foo
bar
baz
----------------
()
----------------
('Hello', 'World')
Hello
World
How ever you can just use an if statement
def f(*args):
if args == (): args = ("default value") ## <--- Here
print(args)
for arg in args:
print(arg)
Not like that, but you can define your function like this:
def printf(age, gender, *fave, name = "veronica"):
fave = fave or ["grass"]
print(name, " ", gender, " ", age, " ")
print("favefood: ", end = "")
for i in fave:
print(i, end = " ")
The output would be:
printf(25, "m", name="john")
john m 25
favefood: grass
It's a 'No' and 'Yes' answer. Ideally you are not meant to have defaults for *args. This is because variable arguments are used when you are not sure of how many arguments are passed (could be 0 too, as suggested by Yash's answer).
If you seriously need a workaround you can check for a null value (None in python) and assign a value for that argument/variable using a simple ternary snippet like below
fave = fave if fave else "grass"
I do have couple of suggestions. It is always recommended to have varargs (*args,*kwargs) at the end of your argument list. In your case you are having another argument called 'name' at the end which is not recommended standard. You need to have your arguments something like below:
def my_func(arg1,arg2,arg3,*args,**kwargs)
Else you can have 'name' as a keyword argument instead of a normal argument. So you can have your function signature like either of the below ways:
def printf(age, gender, name = "veronica", *fave)
def printf(age, gender, *fave, **kwargs)
Please read more about python's variable arguments here

scanf() production problems in Python

I wanted to try writing functions of a language to a different one. I opt for C to Python, and here is what I've done so far.
Code:
def printf(text, *args):
print(text % args, end = '')
def scanf(text, *args):
args = input(text % args)
return args
name = None
scanf("What's your name? %s", name)
printf("Hello, %s.\n", name)
Result:
What's your name? NoneBoy
Hello, Boy.
I have 3 problems regarding this question:
scanf doesn't actually print out the variable to be inputted.
I have to implement a variable with no value, but unlike C, where you could just write int result;, you must write it as result = None and my function would print None as well.
It never returned any value.
Are there any solutions I can use to fix these?
You can use static variables for updating any value inside the function.
class Example:
name = "None"
def printf(text, args):
print(text % args, end = '')
def scanf(text, args):
Example.name = input(text)
scanf("What's your name? ", name)
printf("Hello, %s.\n", Example.name)
There are other pre-build functions to use.
This is the example of the user-defined functions.
If you want to use a pre-defined function. Please let me know.

Get variable from a parent function

I have a function that produces another function.
def make_func(greeting):
def func(name):
return greeting + " " + name
return func
>>> say_hello = make_func("Hello")
>>> say_hello("there")
"Hello there"
Elsewhere in the script, I have access to say_hello, but I have no idea what the greeting in that function actually is. I'd like to find out.
name, of course, isn't possible to get because it's specified when the function is called. But greeting is static, because it's defined outside of the function.
Is there some attribute of say_hello I can examine to get the original "Hello"?
You can find a good explanation of how inner functions are compiled in python here
Then the easiest way to get the variable is say_hello.__closure__[0].cell_contents
You can just store the attribute greeting in func:
def make_func(greeting):
def func(name):
return func.greeting + " " + name
func.greeting = greeting
return func
say_hello = make_func("Hello")
print(say_hello.greeting) # Hello
say_hello.greeting = 'Bye'
print(say_hello('there')) # Bye there

How to change function name dynamically in python

I want to change the function name according to result obtained from another function but the function definition remains same How can i do this i tried the following example but it didn't work
def f(text):
def x(text):
return text+"example"
name=x(text)
def name(y):
return y
return name
p=f("hi ")
print p("hello")
print p.__name__
OUTPUT
hello
name
But i want the function name p.__name__ as "hi example" not name
You can simply assign to __name__:
def f(text):
def r(y):
return y
r.__name__ = text + "example"
return r
p = f("hi ")
print (p("hello")) # Outputs "hello"
print (p.__name__) # Outputs "hi example"
Note that a function name does not have any influence on the function's behavior though, and does not have any meaning except as a part of the string representation or a debugging aid.

Real-world examples of nested functions

I asked previously how the nested functions work, but unfortunately I still don't quite get it. To understand it better, can someone please show some real-wold, practical usage examples of nested functions?
Many thanks
Your question made me curious, so I looked in some real-world code: the Python standard library. I found 67 examples of nested functions. Here are a few, with explanations.
One very simple reason to use a nested function is simply that the function you're defining doesn't need to be global, because only the enclosing function uses it. A typical example from Python's quopri.py standard library module:
def encode(input, output, quotetabs, header = 0):
...
def write(s, output=output, lineEnd='\n'):
# RFC 1521 requires that the line ending in a space or tab must have
# that trailing character encoded.
if s and s[-1:] in ' \t':
output.write(s[:-1] + quote(s[-1]) + lineEnd)
elif s == '.':
output.write(quote(s) + lineEnd)
else:
output.write(s + lineEnd)
... # 35 more lines of code that call write in several places
Here there was some common code within the encode function, so the author simply factored it out into a write function.
Another common use for nested functions is re.sub. Here's some code from the json/encode.py standard library module:
def encode_basestring(s):
"""Return a JSON representation of a Python string
"""
def replace(match):
return ESCAPE_DCT[match.group(0)]
return '"' + ESCAPE.sub(replace, s) + '"'
Here ESCAPE is a regular expression, and ESCAPE.sub(replace, s) finds all matches of ESCAPE in s and replaces each one with replace(match).
In fact, any API, like re.sub, that accepts a function as a parameter can lead to situations where nested functions are convenient. For example, in turtle.py there's some silly demo code that does this:
def baba(xdummy, ydummy):
clearscreen()
bye()
...
tri.write(" Click me!", font = ("Courier", 12, "bold") )
tri.onclick(baba, 1)
onclick expects you to pass an event-handler function, so we define one and pass it in.
Decorators are a very popular use for nested functions. Here's an example of a decorator that prints a statement before and after any call to the decorated function.
def entry_exit(f):
def new_f(*args, **kwargs):
print "Entering", f.__name__
f(*args, **kwargs)
print "Exited", f.__name__
return new_f
#entry_exit
def func1():
print "inside func1()"
#entry_exit
def func2():
print "inside func2()"
func1()
func2()
print func1.__name__
Nested functions avoid cluttering other parts of the program with other functions and variables that only make sense locally.
A function that return Fibonacci numbers could be defined as follows:
>>> def fib(n):
def rec():
return fib(n-1) + fib(n-2)
if n == 0:
return 0
elif n == 1:
return 1
else:
return rec()
>>> map(fib, range(10))
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
EDIT: In practice, generators would be a better solution for this, but the example shows how to take advantage of nested functions.
They are useful when using functions that take other functions as input. Say you're in a function, and want to sort a list of items based on the items' value in a dict:
def f(items):
vals = {}
for i in items: vals[i] = random.randint(0,100)
def key(i): return vals[i]
items.sort(key=key)
You can just define key right there and have it use vals, a local variable.
Another use-case is callbacks.
I have only had to use nested functions when creating decorators. A nested function is basically a way of adding some behavior to a function without knowing what the function is that you are adding behavior to.
from functools import wraps
from types import InstanceType
def printCall(func):
def getArgKwargStrings(*args, **kwargs):
argsString = "".join(["%s, " % (arg) for arg in args])
kwargsString = "".join(["%s=%s, " % (key, value) for key, value in kwargs.items()])
if not len(kwargs):
if len(argsString):
argsString = argsString[:-2]
else:
kwargsString = kwargsString[:-2]
return argsString, kwargsString
#wraps(func)
def wrapper(*args, **kwargs):
ret = None
if args and isinstance(args[0], InstanceType) and getattr(args[0], func.__name__, None):
instance, args = args[0], args[1:]
argsString, kwargsString = getArgKwargStrings(*args, **kwargs)
ret = func(instance, *args, **kwargs)
print "Called %s.%s(%s%s)" % (instance.__class__.__name__, func.__name__, argsString, kwargsString)
print "Returned %s" % str(ret)
else:
argsString, kwargsString = getArgKwargStrings(*args, **kwargs)
ret = func(*args, **kwargs)
print "Called %s(%s%s)" % (func.__name__, argsString, kwargsString)
print "Returned %s" % str(ret)
return ret
return wrapper
def sayHello(name):
print "Hello, my name is %s" % (name)
if __name__ == "__main__":
sayHelloAndPrintDebug = printCall(sayHello)
name = "Nimbuz"
sayHelloAndPrintDebug(name)
Ignore all the mumbo jumbo in the "printCall" function for right now and focus only the "sayHello" function and below. What we're doing here is we want to print out how the "sayHello" function was called everytime it is called without knowing or altering what the "sayHello" function does. So we redefine the "sayHello" function by passing it to "printCall", which returns a NEW function that does what the "sayHello" function does AND prints how the "sayHello" function was called. This is the concept of decorators.
Putting "#printCall" above the sayHello definition accomplishes the same thing:
#printCall
def sayHello(name):
print "Hello, my name is %s" % (name)
if __name__ == "__main__":
name = "Nimbuz"
sayHello(name)
Yet another (very simple) example. A function that returns another function. Note how the inner function (that is returned) can use variables from the outer function's scope.
def create_adder(x):
def _adder(y):
return x + y
return _adder
add2 = create_adder(2)
add100 = create_adder(100)
>>> add2(50)
52
>>> add100(50)
150
Python Decorators
This is actually another topic to learn, but if you look at the stuff on 'Using Functions as Decorators', you'll see some examples of nested functions.
OK, besides decorators: Say you had an application where you needed to sort a list of strings based on substrings which varied from time to time. Now the sorted functions takes a key= argument which is a function of one argument: the items (strings in this case) to be sorted. So how to tell this function which substrings to sort on? A closure or nested function, is perfect for this:
def sort_key_factory(start, stop):
def sort_key(string):
return string[start: stop]
return sort_key
Simple eh? You can expand on this by encapsulating start and stop in a tuple or a slice object and then passing a sequence or iterable of these to the sort_key_factory.

Categories