Python printing a procedure - python

I am trying to print a procedure in Python. How do I print it?
Here is my code
def proc(a,b):
if test(a):
return b
return a
print proc(a,b)
But I get this error:
NameError: name 'a' is not defined
Thanks in advance.

a is the name of the local variable used to hold the value of the first argument passed to the function when it is called. When actually calling it, you need an actual value, or a variable defined in the scope where the function is called. For example:
def proc(a,b):
if test(a):
return b
return a
x = 6
print proc(x, 7)
Now when proc is called, the value of the variable x and the value 7 are passed to proc. Inside proc, a will have the same value as x (at the time of the call) in the calling scope, and similarly b will have the value 7.

If you're trying to call proc and view the result, then there are two things you need to know:
You call a function by typing its name, followed by a pair of parentheses that contains the function's arguments: proc(23, 42)
You can print the result of an expression by typing print, followed by a pair of parentheses containing the expression: print(4 + 8 * sqrt(15) - 26).
Combine these two principles to view the result of a function call.
print(proc(23, 42))

Related

Trying to understand in Python 3.7 how to get a number returned from a function to the main program

In general terms, I cannot get any function to return a value inside a variable (an integer, back to the main program. I have included the variable name as one of 2 arguments in the function (in this case mod_stone_value), and am using the return command to hopefully return that integer value to the main program, where that value is then added to a total value.
The key lines of code in the function would be:
def calc_real_stone_value(base_stone_value, mod_stone_value):
return mod_stone_value
and then, back in the main program:
total_stone_value = total_stone_value + mod_stone_value
The variable total_stone_value ends up being 0, yet non-zero values of mod_stone_value do print inside the function. I know I am doing something fundamentally wrong, but have no idea what it is.
If I understand correctly, you want to use the number value returned by the function calc_real_stone_value and are confused as to why it is not changing after you call your function which supposedly "updates it's value".
The fundamental thing you are misunderstanding is that primitive data types (double, int, char, etc.) are passed by value, not by reference. Therefore, if you make changes to the local variable mod_stone_value within the function, the changes will not show in the variable that exists outside the function. If you want to use the value you are returning with the line return mod_stone_value you need to call the function with the variables you want to be used in the calculations and then assign that value to a variable (mod_stone_value in this case).
Example:
base_stone_value = 1
mod_stone_value = 4
def calc_real_stone_value(base_stone_value, mod_stone_value):
# calculations
# e.g. add the two integer arguments
mod_stone_value += base_stone_value
return mod_stone_value
# print the values for mod_stone_value
print(mod_stone_value)
# call function and assign value to mod_stone_value
mod_stone_value = calc_real_stone_value(base_stone_value, mod_stone_value)
print(mod_stone_value)
Output:
4
5
Conclusion:
Primitive variables are passed by value and in order to retrieve the value from a function that returns an integer for example, it needs to be re-assigned.
To reduce confusion, you can avoid using variable names that shadow variable names from an outer scope.
Using your code as a template, here is an example that illustrates passing a value from "inside" the function to the outer level (here, the outermost level of the program). I would recommend reading this part of the official Python tutorial (or from the beginning if it does not make sense) as it describes concepts (e.g. global vs. local variables) that are relevant to your problem.
c = 0
d = 5
e = 2
def foo(a, b):
# insert whatever code here
d = 10
print(f"Inside foo(), d has value {d}")
# to match your example
return b
# c has the value 0, d has the value 5
print(f"(c, d) has the value ({c}, {d})")
# call function and pass return value to c
c = foo(d, e)
# c has the value 2, d has the value 5
print(f"(c, d) has the value ({c}, {d})")
By the way, regarding your code, statements inside the body of the function should be indented. This includes the return statement.

Execute function based on function's name string

I want to call that function by extracting the first word from the string. For example my string is like:
"my_func arg_1 arg_2"
# ^ ^ ^ second argument of function
# ^ ^ first argument of function
# ^ name of the function
where my_func is a name of the function already defined.
Based on the above mention string, I want to dynamically execute the my_func function. So, my function call should be like:
my_func(arg_1, arg_2)
Currently I am trying to achieve this via using eval:
eval(command.split(' ', 1)[0])
How can I achieve this?
You may use locals() (or globals()) to fetch the reference of function based on string. Below is the sample example:
# Sample function
def foo(a, b):
print('{} - {}'.format(a, b))
# Your string with functions name and attributes
my_str = "foo x y"
func, *params = my_str.split()
# ^ ^ tuple of params string
# ^ function name string
Now, pass the function string as a key to the locals() dict with *params as argument to the function as:
>>> locals()[func](*params)
x - y # output printed by `foo` function
Regarding the split method, by default the delimiter is space so you don't actually need to define that your delimiter is space and as you want the first item in the list, you just need to type the index 0 [0].
locals returns a dictionary with a current local symbol table. globals returns a dictionary with global symbol table.
var = "my_func arg_1 arg_2"
print (locals()[var.split()[0]]())
Or
var = "my_func arg_1 arg_2"
print (globals()[var.split()[0]]())
If the function was part of an object you could use the getattr built-in function.
var = "my_func arg_1 arg_2"
getattr(object, var.split()[0])
getattr(object, name[, default])
Return the value of the named
attribute of object. name must be a string. If the string is the name
of one of the object’s attributes, the result is the value of that
attribute. For example, getattr(x, 'foobar') is equivalent to
x.foobar. If the named attribute does not exist, default is returned
if provided, otherwise AttributeError is raised.
If you define you functions up front you can have greater control over their name mapping.
def my_func(a):
print(a)
functions = {'my_func': my_func}
def exe(text):
command = text.split(" ")
f = command[0]
args = command[1:]
if f in functions:
functions[f](args)
exe("my_func arg_1 arg_2")
Something along the lines of:
Check if the function exists inside the local scope.
If it does exist then run it using eval().
def add():
print("do something")
def find_function(funct_name, defined_names):
if defined_names.get(funct_name) is None:
print("no function called {}".format(funct_name))
return
eval(funct_name + "()")
# access local user defined names.
defined_names = locals()
#print(defined_names)
function_name = 'add'
find_function(function_name ,defined_names)
Output:
do something

Scope of variable when passed to another function in python decorators

So I was reading this wonderful piece which tries to explain decorators in python.
My question is specific to this code snippet.
def surround_with(surrounding):
"""Return a function that takes a single argument and."""
def surround_with_value(word):
return '{}{}{}'.format(surrounding, word, surrounding)
return surround_with_value
def transform_words(content, targets, transform):
"""Return a string based on *content* but with each occurrence
of words in *targets* replaced with
the result of applying *transform* to it."""
result = ''
for word in content.split():
if word in targets:
result += ' {}'.format(transform(word))
else:
result += ' {}'.format(word)
return result
markdown_string = 'My name is Jeff Knupp and I like Python but I do not own a Python'
markdown_string_italicized = transform_words(markdown_string, ['Python', 'Jeff'],
surround_with('*'))
print(markdown_string_italicized)
What I don't understand is how did the function surround_with() get the variable word (when passed on by transform(word) inside transform_words()) in it's scope? I mean we have only declared a holding variable (as a function argument) for what the surrounding value should be and nothing else. Then how was word available to it?
What am I missing here?
The surround_with() function returns another function object with a closure:
def surround_with(surrounding):
"""Return a function that takes a single argument and."""
def surround_with_value(word):
return '{}{}{}'.format(surrounding, word, surrounding)
return surround_with_value
So surround_with_value is returned; it is this function that prepends and appends the value of surrounding to whatever is passed in:
>>> def surround_with(surrounding):
... """Return a function that takes a single argument and."""
... def surround_with_value(word):
... return '{}{}{}'.format(surrounding, word, surrounding)
... return surround_with_value
...
>>> function = surround_with(' foo ')
>>> function
<function surround_with_value at 0x108ac16e0>
>>> function('bar')
' foo bar foo '
The surround_with_value() function was returned and a reference to it was stored in the name function. That function object references surrounding as a closure:
>>> function.__closure__
(<cell at 0x108a8a590: str object at 0x1074c4060>,)
>>> function.__closure__[0].cell_contents
' foo '
and each time you call it that closure is dereferenced and the contents are used.
So surround_with() produces a function object, and such function (as the result of surround_with('*')), is passed to transform_words() as the 3rd argument:
transform_words(markdown_string, ['Python', 'Jeff'],
surround_with('*'))
so it is assigned to the variable transform:
def transform_words(content, targets, transform):
Thus, each time you call transform, you really are calling the nested surround_with_value() function with '*' as the surrounding closure, and word is being passed in:
result += ' {}'.format(transform(word))
I think I understood it,
When we call surround_with('*'), it returns the function surround_with_value() which is then returning the value '{}{}{}'.format('*', word, '*').
Now the very same function takes an argument (word here) which is then passed inside transform_words() and renamed as transform().
Inside it we finally pass the value for word.
Closure can be very confusing and this example might not be the best to show why surround_with_value() remembers surround with(surrounding) event if it's not in its scope.
I strongly advice you to read this excellent blog showing all concept you need to understand to understand decorators. Step1: Scope-->Step2: Closure-->Step3: Decorators
Take some time and read it from the beginning.
http://simeonfranklin.com/blog/2012/jul/1/python-decorators-in-12-steps/

Can anyone explain how this functional program work?

def apply_twice(func,arg):
return func(func(arg))
def add_five(x):
return x+5
print (apply_twice(add_five,10))
The output I get is 20.
This one is actually confusing me like how is it working.Can anybody explain me how this is working by breaking it down
The function apply_twice(func,arg) takes two arguments, a function object func and an argument to pass to the function func called arg.
In Python, functions can easily be passed around to other functions as arguments, they are not treated differently than any other argument type (i.e first class citizens).
Inside apply_twice, func is called twice in the line:
func(func(arg))
Which, alternatively, can be viewed in a more friendly way as:
res = func(arg)
func(res)
If you replace func with the name of the function passed in add_five you get the following:
res = add_five(arg) # equals: 15
add_five(res) # result: 20
which, of course, returns your expected result.
The key point to remember from this is that you shouldn't think of functions in Python as some special construct, functions are objects just like ints, listss and everything else is.
Expanding the code it executes as follows, starting with the print call:
apply_twice(add_five,10))
add_five(add_five(10)) # add_five(10) = 15
add_five(15) # add_five(15) = 20
Which gives you the result: 20.
When apply_twice is called, you are passing in a function object and a value. As you can see in the apply_twice definition, where you see func that is substituted with the function object passed to it (in this case, add_five). Then, starting with the inner func(arg) call, evaluate the result, which is then passed to add_five again, in the outer return func( ... ) call.
What you need to understand here is that
apply_twice(func,arg)
is a higher function which accepts two arguments (another function named func and an argument arg). The way it works is that it first evaluate the value of the other function, then use the value as an argument inside the higher function.
remember we have a function add_five(x) which add 5 to the argument supply in it...
then this function add_five(x) is then passed as an argument to another function called
apply_twice_(func,arg) which return func(func(arg)).
now splitting func(func(arg)) we have
func(arg) #lets called it a
then func(func(arg))==func(a) since a = func(agr)
and (a) is our add_five(x) function, after it add 5, then the value we got is re-used as another fresh argument to add another 5 to it, that is why we have 20 as our result.
Another example is:
def test(func, arg):
return func(func(arg))
def mult(x):
return x * x
print(test(mult, 2))
which give 16 as result.

Concatenation of strings in a default argument

This is a piece of my code...
def contactMaster(data="",url= str(chosenMaster)+"todolist"):
print "url: "+url
It prints only "todolist" instead of "http://www.mysite.com/blah/1234/todolist"
Why isn't it working??
Default arguments are evaluated when the function is defined not when it is executed. So if chosenMaster is empty when Python defines contactMaster, it will print only todolist.
You need to move str(chosenMaster) into the function.
See Default Argument Values in the Python Tutorial for more info. The example there is:
The default values are evaluated at the point of function definition in the defining scope, so that
i = 5
def f(arg=i):
print arg
i = 6
f()
will print 5.
The function definition captures the value of chosenMaster at the time the function is declared, not when the function is called.
Do this instead:
def contactMaster(data='', url=None):
if url is None:
url = str(chosenMaster) + 'todolist'
print 'url: ' + url
Because default function arguments are determined when the function is defined. Changing chosenMaster after the fact will have no effect.

Categories