Reputation: 43
I am learning Python and practice some problem on the book.
The problem asks me to write a function keeping the max value.
The function (foo) works like below:
if call foo(1) then print 1
call foo(5) print 5
call foo(3) print 5
call foo(10) print 10
call foo(8) print 10
I don't know what is the key point of this problem.
Upvotes: 1
Views: 524
Reputation:
In mathematics, if a function is given certain input, it always returns the same value. That is what pure(sorry about being vague in wording) functions do. It means, your function will forget every information it used once it's done its job. In this case, your functions is not likely to remember previous max value and you will not be able to solve your problem, right? That's why other people suggested somewhat complex solutions like global variables or class. They do different jobs but they are all about keeping previous state(or what happened in the past). I would suggest one more method to achieve your goal. This may seem harder for now, but you will appreciate this later.
# written in Python3, not Python2
def function_factory():
prev_max = None
def print_max(num):
nonlocal prev_max
# prev_max is None or smaller than num
if not (prev_max and prev_max > num):
prev_max = num
print(prev_max)
return print_max
# make an instacne of print_max and bind that
# new function to the name, my_func
my_func = function_factory()
my_func(3) # >> 3
my_func(5) # >> 5
my_func(3) # >> 5
I used what's called a closure, and if you are interested you can study functional programming. It's a bit involved but makes your code succinct.
Upvotes: 1
Reputation: 918
Another way (and much more correct in terms of encapsulation for the production code) to complete the task is to use classes
instead of functions and global variables:
class MaxPositiveValue:
def __init__(self):
self.max_value = 0
def __call__(self, new_value):
'''
This magic method will emulate function call
:param new_value: new value to compare
:return: max value
'''
if new_value > self.max_value:
self.max_value = new_value
return self.max_value
foo = MaxPositiveValue()
print(foo(1)) # Will print "1"
print(foo(5)) # Will print "5"
print(foo(2)) # Will print "5"
print(foo(10)) # Will print "10"
print(foo(4.6)) # Will print "10"
print(foo(12.8)) # Will print "12.8"
And if you want to properly compare both positive and negative numbers, you may use next code:
class MaxValue:
def __init__(self):
self.max_value = None
def __call__(self, new_value):
'''
This magic method will emulate function call
:param new_value: new value to compare
:return: max value
'''
if (self.max_value is None) or (new_value > self.max_value):
self.max_value = new_value
return self.max_value
foo = MaxValue()
print(foo(-10.4)) # Will print "-10.4"
print(foo(-30.1)) # Will print "-10.4"
print(foo(1)) # Will print "1"
print(foo(5.6)) # Will print "5.6"
print(foo(2)) # Will print "5.6"
print(foo(10)) # Will print "10"
Upvotes: 5
Reputation: 1531
Your question is about global variables. It is saying to create a variable that is not dependent upon that instance of the function. Instance is used (in this case) to describe when that function is being used. Setting the variable as a global keeps it as that value irrespective of being in a different time the function has been called.
This code would be the solution:
glob_max = 0 #This variable needs to be set before the function
#(assuming you're just using natural numbers otherwise set a smaller number)
def foo(numbr):
if numbr > glob_max: #This find if it is the max or not
glob_max = numbr #Sets the variable
global glob_max #Makes the variable global to remember it for other functions
print(glob_max) #Print the number as required
Upvotes: 0