Why does this python code not swap the numbers? - python

Why does this python code not swap the numbers?
def swap(x, y):
'''THe swap function'''
print("INSIDE")
temp = x
x = y
y = temp
#Driver_code
x = 2
y = 3
swap(x, y)
print(x)
print(y)

In the Swap function add this one line:
global x,y;
The problem is when you are calling the swap() function it is making its own variable x and y,
not using the global variable x and y

Because the swap is inside the function.
You're swapping the values of the function parameters x and y, which are different from the x and y that are used below.
Just do this:
x, y = y, x

The swap function is not returning values
def swap(x, y):
'''THe swap function'''
print("INSIDE")
temp = x
x=y
y= temp
return x,y
#Driver_code
x = 2
y = 3
x,y=swap(x, y)
print(x)
print(y)
Here, you assign the returning values to x and y.

Related

I have a simple question about the logic behind this Python code

I'm a beginner in Python, and I'm stuck in a function code.
def max_of_two( x, y ):
if x > y:
return x
return y
def max_of_three( x, y, z ):
return max_of_two( x, max_of_two( y, z ) )
print(max_of_three(30, 25, 50))
Can someone explain to me the logic behind putting the first function (max_of_two()) inside the parameters of the second function (max_of_three())? I've seen a function inside a function code, and that's not a problem, but I've never seen a function inside the parameters of another function... I'm very confused. I know what the code does, it basically shows the greater number. The first function I understood perfectly, but the second one confused me...
x = 1
y = 2
z = 3
max_of_two( y, z )
> 3
max_of_two( x, max_of_two( y, z ) )
# is the same as
max_of_two( x, z )
# is the same as
max_of_two( x, 3 )
The result of the inner function is used as a parameter for the outer function because the inner function is evaluated first.
This is not putting a function inside parameters. First I recommend you understand parameter vs argument, here's a quote from "Parameter" vs "Argument" :
Old post, but another way of saying it: argument is the value/variable/reference being passed in, parameter is the receiving variable used w/in the function/block
def max_of_three( x, y, z ):
return max_of_two( x, max_of_two( y, z ) )
For example, (x, y, z) are parameters of max_of_three, and (y, z) are arguments passed to max_of_two
——————————————————————————————————————————
Then you should understand function calls. max_of_two( y, z ) is an example of a function call, where you call the function max_of_two, by making a function call, you get the return value corresponding to your arguments.
In this case, when you write:
max_of_two( x, max_of_two( y, z ) )
you first get the return value corresponding to (y, z) from max_of_two, and the pass x and the return value above to another max_of_two function, then you return the new return value from max_of_three. This is equivalent to:
retval = max_of_two( y, z )
retval2 = max_of_two( x, retval )
return retval2
It's like a nested if in other languages. You have three arguments to the second function. These are passed to the first function that verifies them in pairs.
If you wanted to use a single function max_of_three(x, y, z) it should look like a succession of if statements with an intermediary variable.
def max_of_three(x,y,z):
if x > y:
temp = x
else:
temp = y
if temp > z:
result = temp
else:
result = z
return result

What does this expression do: (x, y) = (y, x % y)? [duplicate]

This question already has answers here:
Multiple assignment and evaluation order in Python
(11 answers)
Closed 1 year ago.
I see below code but do not know what does it do.
(x, y) = (y, x % y)
At the beginning I thought it does below:
x=y
y=x%y
But I noticed I am not right.
Can someone explain what (x, y) = (y, x % y) does?
It's called tuple assignment/unpacking, and to reproduce it linearly, you need a temporary location to store the value of x.
It is more equivalent to:
temp=x
x=y
y=temp%y
You're right, it does what you think it does. x is assigned the value of y and y is assigned the value of x%y
Example:
>>> x=5
>>> y=10
>>> (x, y) = (y, x % y)
>>> x
10
>>> y
5
>>>
x becomes 10 (i.e., the value of y)
and y becomes x%y= 5%10 =5
It does this:
t1 = y
t2 = x % y
x = t1
y = t2
del t1, t2
except that the variables t1 and t2 never actually exist. In other words, it computes the new values to assign to both x and y based on their old values, and changes both at once.
I don't have the exact terminology here.
(x, y) = (y, x % y) is doing x=y, y=x%y and the same time. If you are running this two lines in sequence, you are pass the value of y to x the do the divide.

Test whole range of possible inputs for a given question

Is there a quick way to find the maximum value (float) from a function and the corresponding arguments x, y that are both integers between 0 and 100 (inclusive)? Do I need to use the assert function or something like that to get the range of all possible inputs?
def fun_A(x,y):
import math
if x == y:
return 0
first = math.cos((y%75)*(math.pi/180))
second = math.sin((x%30)*(math.pi/180))
return (first + second) / (abs(x - y))
For small problems like this it is probably fast enough to evaluate every possible combination and choose the maximum. The numpy library makes this easy to write and pretty fast as well:
import numpy as np
def fun_A(x, y):
first = np.cos((y%75)*(np.pi/180))
second = np.sin((x%30)*(np.pi/180))
return np.where(x == y, 0, (first + second) / (abs(x - y)))
x, y = np.mgrid[0:101, 0:101]
f = fun_A(x, y)
maxindex = np.argmax(f)
print('Max =', f.flat[maxindex], ' at x =', x.flat[maxindex], 'y =', y.flat[maxindex])
Output:
Max = 1.4591796850315724 at x = 89 y = 88
Things to note:
I've just replaced calls to math with calls to np.
x and y are matrices which allow us to evaluate every possible combination the two values in one function call.
I would do this for the tan function :
from math import tan
y = 0
x = 0
for x_iteration in range(0, 101):
if tan(x_iteration) > y :
x = x_iteration
y = tan(x_iteration)
x = int(x)
y = int(y)
It's fairly straightforward to write a program to solve this:
max_result = None
max_x = 0
max_y = 0
for x in range(0, 101):
for y in range(0, 101):
result = fun_A(x, y)
if max_result is None or result > max_result:
max_result = result
max_x = x
max_y = y
print(f"x={max_x} and y={max_y} produced the maximum result of {max_result}")

Optimization Function Inside a Loop and Another Function

I'm trying to solve for optimal values repeatedly with different random values. So the minimize function is included inside a loop and a function, then I call that function. However, it always gives me different answer.
import numpy as np
from scipy.optimize import minimize
def Ln(theta): # Every loop tries to minimize this value
error = Y - np.maximum(0, theta[0] + X.dot(theta[1:]))
error_total = np.absolute(error).sum()
return error_total
theta_true = np.array([-6,3,3,3])
Y = np.array(10)
def get_opt_x():
for i in range(10):
X = np.random.standard_normal([10,3]) # generate random values
u = X[:,0]**2*np.random.standard_normal(10)
Y_star = theta_true[0] + X.dot(theta_true[1:]) + u
Y = np.maximum(0, Y_star)
theta0 = np.ones(4)
result = minimize(Ln, theta0, method='BFGS')
print result.x
return
get_opt_x()
This is what it gives:
The correct answer is supposed to be different, since for every loop, a new set of random values are generated. If I get rid of the function, and just do the loop everything works fine:
for i in range(10):
X = np.random.standard_normal([10,3])
u = X[:,0]**2*np.random.standard_normal(10)
Y_star = theta_true[0] + X.dot(theta_true[1:]) + u
Y = np.maximum(0, Y_star)
theta0 = np.ones(4)
result = minimize(Ln, theta0, method='BFGS')
print result.x
There must be something wrong with using minimize function inside a loop and another function.
Variable X and Y within get_opt_x() are local to get_opt_x() and are different from X and Y in function Ln. The results from get_opt_x() are all the same because it is using the values from the last loop u ran (by getting rid of your function). To prove that try closing your session and run your first block of code before running the second block, you'll get an error saying X is not initialized.
Solution:
pass X and Y as extra arguments to the minimize routine
def Ln(theta, X, Y): # Every loop tries to minimize this value
error = Y - np.maximum(0, theta[0] + X.dot(theta[1:]))
error_total = np.absolute(error).sum()
return error_total
theta_true = np.array([-6,3,3,3])
Y = np.array(10)
def get_opt_x():
for i in range(10):
X = np.random.standard_normal([10,3]) # generate random values
u = X[:,0]**2*np.random.standard_normal(10)
Y_star = theta_true[0] + X.dot(theta_true[1:]) + u
Y = np.maximum(0, Y_star)
theta0 = np.ones(4)
result = minimize(Ln, theta0, (X, Y), method='BFGS')
print result.x
return
get_opt_x()
The problem is that you're defining the variable Y inside the function get_opt_x and then expecting it to be visible to the function Ln, which Python disallows. When you remove the get_opt_x function, the value Y is then available in the global scope and thus visible to the Ln function.
You need to tell Python that Y is a global variable at the beginning of get_opt_x:
def get_opt_x():
global Y

How do I generate test data for my Python script?

A equation takes values in the following form :
x = [0x02,0x00] # which is later internally converted to in the called function to 0x300
y = [0x01, 0xFF]
z = [0x01, 0x0F]
How do I generate a series of test values for this function ?
for instance I want to send a 100 odd values from a for loop
for i in range(0,300):
# where a,b are derived for a range
x = [a,b]
My question was a bit unclear so please let my clarify.
what I wanted to ask how I can do x =[a,b] generate different values for a,b
use generators:
def gen_xyz( max_iteration ):
for i in xrange( 0, max_iteration ):
# code which will generate next ( x, y, z )
yield ( x, y, z )
for x, y, z in gen_xyz( 1000 ):
f( x, y, z )
The hex() function?
import random
for i in range(10):
a1, a2 = random.randint(1,100), random.randint(1,100)
x = [hex(a1), hex(a2)]
print x
..outputs something similar to..
['0x21', '0x4f']
['0x59', '0x5c']
['0x61', '0x40']
['0x57', '0x45']
['0x1a', '0x11']
['0x4c', '0x49']
['0x40', '0x1b']
['0x1f', '0x7']
['0x8', '0x2b']
['0x1e', '0x13']

Categories