Please help me modify my code for max min value - python

def Goods(t):
max_n = t.index(max(t))
min_n = t.index(min(t))
return max_n,min_n
t = [-125,-164,1237,809,5634,1278,8431]
Goods(t, len(t))
Hello.
I'm trying to find two values ​​in a list and get an index tuple as the result.
The two values ​​are the maximum and the minimum.
(6, 1)
>>> print(Goods([-125,-164,1237,809,5634,1278,8431]))
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
print(Goods([-125,-164,1237,809,5634,1278,8431]))
TypeError: Goods() missing 1 required positional argument: 'n'
I found the value. But what I want is a way to get results when I type "print(Goods([-125,-164,1237,809,5634,1278,8431]))" like this.
I would really appreciate it if you could teach me how to modify the code for the answer I want.

You didn't provide all of the arguments to your function. Should be:
def Goods(t, n):
max_n = t.index(max(t))
min_n = t.index(min(t))
print((max_n,min_n))
buff_list = [-125,-164,1237,809,5634,1278,8431];
Goods(buff_list, len(buff_list))
If you would like to print the values, you have to ask the function to return something. I.e., modify your function to:
def Goods(t, n):
max_n = t.index(max(t))
min_n = t.index(min(t))
return (min_n, max_n)
print(Goods(buff_list, len(buff_list)))

Related

Python: calling inner() from outer()

I have looked around on SO and surprisingly not found an answer to this question. I assume this is because normally inner/nested functions are used for something in particular (eg. maintaining an environment variable, factories) as opposed to something trivial like I'm trying to use them for. In any case, I can't seem to find any information on how to properly call an inner function from an outer function without having to declare inner() above outer() in the file. The problem is from this problem on HackerRank (https://www.hackerrank.com/challenges/circular-array-rotation/problem).
def circularArrayRotation(a, k, queries):
def rotateArrayRightCircular(arr: list, iterations: int) -> list:
"""
Perform a 'right circular rotation' on an array for number of iterations.
Note: function actually moves last 'iterations' elements of array to front of array.
>>>rotateArrayRightCircular([0,1,2], 1)
[2,0,1]
>>>rotateArrayRightCircular([0,1,2,3,4,5], 3)
[3,4,5,0,1,2]
>>>rotateArrayRightCircular([0,1,2,3,4,5], 6)
[0,1,2,3,4,5]
"""
return arr[-1 * iterations:] + arr[0:-1 * iterations]
k = k % len(a)
a = rotateArrayRightCircular(a, k)
res = []
for n in queries:
res.append(a[n])
return res
The code above does what I want it to, but it's somehow inelegant to me that I have to put the inner function call after the inner function definition. Various errors with different attempts:
# trying 'self.inner()'
Traceback (most recent call last):
File "solution.py", line 52, in <module>
result = circularArrayRotation(a, k, queries)
File "solution.py", line 13, in circularArrayRotation
a = self.rotateArrayRightCircular(a, k)
NameError: name 'self' is not defined
# Removing 'self' and leaving the definition of inner() after the call to inner()
Traceback (most recent call last):
File "solution.py", line 52, in <module>
result = circularArrayRotation(a, k, queries)
File "solution.py", line 13, in circularArrayRotation
a = rotateArrayRightCircular(a, k)
UnboundLocalError: local variable 'rotateArrayRightCircular' referenced before assignment
Any idea how I could include def inner() after the call to inner() without throwing an error?
As a function is executed from top to bottom, and a function is put into existence as the function is processed, what you want is just not possible.
You could put the function before the outer one, making it outer itself, possibly adding some parameters (not necessary here). (BTW, it looks so generic that other parts of the code might want to use it as well, so why not outer?)
But otherwise, you are stuck. It is essetially the same situation as in
def f():
print(a) # a doesn't exist yet, so this is an error
a = 4
Well, you could do it this way:
def circularArrayRotation(a, k, queries):
def inner_code():
k = k % len(a)
a = rotateArrayRightCircular(a, k)
# BTW, instead of the following, you could just do
# return [a[n] for n in queries]
res = []
for n in queries:
res.append(a[n])
return res
def rotateArrayRightCircular(arr: list, iterations: int) -> list:
"""
Perform a 'right circular rotation' on an array for number of iterations.
Note: function actually moves last 'iterations' elements of array to front of array.
>>>rotateArrayRightCircular([0,1,2], 1)
[2,0,1]
>>>rotateArrayRightCircular([0,1,2,3,4,5], 3)
[3,4,5,0,1,2]
>>>rotateArrayRightCircular([0,1,2,3,4,5], 6)
[0,1,2,3,4,5]
"""
return arr[-1 * iterations:] + arr[0:-1 * iterations]
return inner_code()
but I don't see that you gain anything from it.
This is not possible in Python, but is possible in other languages like Javascript and PHP. It is called function hoisting.

Apply function to permutations of lists of arguments

I have the need to take a function of n parameters and n lists of values and apply the function to each possible permutation of arguments. I have looked in itertools and none of the functions are quite right. The following is my attempt. Can someone explain what I am doing wrong? Thanks.
def CrossReference(f, *args):
result = []
def inner(g, *argsinner):
rest = argsinner[1:]
a = argsinner[0]
if type(a) is not list:
a = [a]
for x in a:
h = partial(g, x)
if len(rest) > 0:
inner(h, rest)
else:
result.append(h())
inner(f, args)
return result
Here is my example test and error:
def sums(x,y,z):
return x+y+z
CrossReference(sums, [1,2,3], 4, [5,6,7])
Traceback (most recent call last): File "", line 1,
in File "", line 13,
in CrossReference File "", line 12, in inner
TypeError: sums() takes exactly 3 arguments (1 given)
The problem is in the way you call your inner function. You define your function header as:
def inner(g, *argsinner):
But you call your function like:
inner(f, args)
And:
inner(h, rest)
This means that you will end up with a single tuple (monotuple?) containing the tuple of your args. You can either change your function definition to:
def inner(g, argsinner):
Or change your calling to:
inner(h, *rest)
def sums(x,y=0,z=0):
return x+y+z
def apply(fn,*args):
for a in args:
try:
yield fn(*a)
except TypeError:
try:
yield fn(**a)
except TypeError:
yield fn(a)
print list(apply(sums,[1,2,3], 4, [5,6,7]))
is one way you might do it (not the only way though)

sqrt() argument after * must be a sequence

First of all, I'm super new to python and I actually search for my problem but the examples were to heavy to understand.
Here is my homework; I need a function which takes two functions as an argument and returns if the results of the two functions are same or not? Basically, it will give either TRUE of FALSE.
For that I wrote:
def f(x,y,z):
k=x(*z)
l=y(*z)
return k == l
The previos code I wrote for single function was working but when I modified it for two function as above, it gives an error as following :
import math
>>> f(math.sqrt,math.cos,5)
Traceback (most recent call last):
File "<pyshell#56>", line 1, in <module>
f(math.sqrt,math.cos,5)
File "D:/Users/karabulut-ug/Desktop/yalanmakinesi.py", line 2, in f
k=x(*z)
TypeError: sqrt() argument after * must be a sequence
>>>
I could not figured it out since the error giving function is normally does not take a sequence. So I dont think it makes a sense :) Any help is appreciated.. Thanks :)
z is just a single number, but the * argument expansion syntax requires that you pass in a sequence (like a list, tuple or str, for example).
Either remove the * (and make your function work for just single arguments), or use *z in the function signature to make z a tuple of 0 or more captured arguments:
def f(x, y, z):
k = x(z)
l = y(z)
return k == l
or
def f(x, y, *z):
k = x(*z)
l = y(*z)
return k == l
The latter now works for functions with more than one argument too:
f(math.pow, math.log, 10, 10)
If you added a **kw argument to the signature, then keyword arguments could be handled too:
def f(x, y, *args, **kwargs):
k = x(*args, **kwargs)
l = y(*args, **kwargs)
return k == l
Here I renamed z to args to better reflect its purpose.
The syntax *z invokes argument unpacking on z. When z is just an integer, there is no iterator behavior defined, and so you see this error. Try:
>>> f(math.sqrt, math.cos, [5])
You need to remove the *. Its for unpacking. So:
def f(x,y,z):
k=x(z)
l=y(z)
return k == l
You use the * operator when you want to pass in an iterable object, like a list or tuple as something thats split up. So, for example:
a = [1,2,3,4,5]
So, for an arbitrary function, f:
f(*a) = f(1,2,3,4,5)

"TypeError: 'function' object does not support item assignment"

I have two matrices
fi = [[f1], Nij = [[N11 N12 .......N1n],
[f2], [N21 N22 .......N2n],
. ...
. ...
[fn]] [Nn1 Nn2 .......Nnn]]
I want to multiply:
f1 to each element of the 1st row,
f2 to each element of the 2nd row,
and so on.
I.e. I want Xij = fi*Nij where fi is a column matrix and Xij & Nij is nxn matrix.
I tried using
import numpy as np
fi = np.linspace(1,5, num =5)
fi = np.asmatrix(fi)
def Xij(ai):
Nij = np.ones((5,5))
for i in range(len(fi)):
for j in range(len(fi)):
Xij[i,j] = ai[i] * Nij[i,j]
return Xij
Zij = Xij(fi)
It gives me this error TypeError: 'function' object does not support item assignment
Why? and how do I solve this?
Your problem is right here:
Xij[i,j] = ai[i] * Nij[i,j]
You named a variable Xij, but also a function. Furthermore, when you named the function, it overwrote the variable.
Because of this, when you try to index the function and assign its items, an error is generated because you can't do that on the function. Below is an example:
>>> def test(): print "Hi"
...
>>> test[1] = "yo!"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'function' object does not support item assignment
>>>
Does that error look familiar? It is the same one you generated because I did exactly what you did.
To fix this problem, change the name of you function to something other than Xij. Doing so will make Xij equal the matrice, which will support indexing and item assignment.

TypeError: 'int' object is not iterable?

I was implementing the dynamic programming algorithm and I got this error. This is my code:
def shoot(aliens):
s=[0]*10
s[0]=0
s[1]=0
for j in xrange(2,len(aliens)):
for i in xrange(0,j):
s[j]=max(s[i] + min(aliens[j],fib(j-i))) <---Error here
print s[len(aliens)-1]
return s[len(aliens)-1]
def fib(n):
if n == 0:
return 0
if n == 1:
return 1
return fib(n-1) + fib(n-2)
aliens=[1,10,10,1]
print shoot(aliens)
it says that:
Traceback (most recent call last):
File "module1.py", line 30, in <module>
print shoot(aliens)
File "module1.py", line 19, in shoot
s[j]=max(s[i] + min(aliens[j],fib(j-i)))
TypeError: 'int' object is not iterable
Please help me
UPDATE:
oh, I get it.
I mean
s[j]=max(s[i] + min(aliens[j],fib(j-i)))
But im wrong.
so, I edited it like that, but I do not know how to use max() to take out the largest in an array.
b=0
for j in xrange(2,len(aliens)):
for i in xrange(0,j):
a[b]=(s[i] + min(aliens[j],fib(j-i)))
b+=1
s[j]=Largest(a[b]); <--How can I do that with Max() function
max and min functions require several arguments or a range of elements. Your call to min() has two arguments (ok), but your call to max() has only one. Not sure what you want to maximize here...
You are doing something like following:
>>> max(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
Did you want to do this?
s[j] = max(s[i], min(aliens[j],fib(j-i)))
or
s[j] = max(s[j], s[i] + min(aliens[j],fib(j-i)))
max needs an iterable argument.
max(...)
max(iterable[, key=func]) -> value
max(a, b, c, ...[, key=func]) -> value
With a single iterable argument, return its largest item.
With two or more arguments, return the largest argument.
But what you passed to it by s[i] + min(aliens[j],fib(j-i)) is an int. What you want may be s[j]=max(s[i], min(aliens[j],fib(j-i)))
It means you cannot iterate over a single int object.
max() and min() want either a number of values of whose they return the largest resp. the smallest, or they want an objkect which can be iterated over.
Your max() call is executed with one single argument which, then, should be iterable, but isn't.
It should be, s[j] = max(s[i], min(aliens[j], fib(j-i))), isn't it?
http://docs.python.org/2/library/functions.html#max
max(iterable[, key])
max(arg1, arg2, *args[, key])
didn't you mean:
s[j] = max(s[i], min(aliens[j],fib(j-i)))

Categories