Lambda function doesn't return float - python

I've written the following code for computing the in-center of a triangle. This code is supposed to be for code-golf. Any help would be appreciated.
d = lambda x,y: ((x[0]-y[0])**2+(x[1]-y[1])**2)**0.5
e = lambda w,x,y,z: float(d(y,z)*x[w]+d(z,x)*y[w]+d(x,y)*z[w])/(d(x,y)+d(y,z)+d(z,x))
a,b,c=eval(input())
px,py=e(0,a,b,c),e(1,a,b,c)
print('[%f,%f]' % (px,py))
Input:
([1,2],[2,2],[1,2])
Expected Output:
[1.2928932188134525, 1.7071067811865475]
Actual Output:
[1.000000,2.000000]

Python is doing the maths correctly. Either your logic is wrong or your input is wrong or your expected output is wrong. Given your input, the only possible output for d is 0 or 1 (the Cartesian distance between two points). Doing this, we can simply e to see what it might output for the first function call.
Given:
w = 0
x = [1, 2]
y = [2, 2]
z = [1, 2]
result = float(d(y,z)*x[w]+d(z,x)*y[w]+d(x,y)*z[w])/(d(x,y)+d(y,z)+d(z,x))
becomes:
result = float(d([2, 2],[1, 2])*[1, 2][0]+d([1, 2],[1, 2])*[2, 2][0]+d([1, 2],[2, 2])*[1, 2][0])/(d([1, 2],[2, 2])+d([2, 2],[1, 2])+d([1, 2],[1, 2]))
becomes:
result = float((1.*1 + 0.*2 + 1.*1) / (1. + 1. + 0))
becomes:
result = float(2. / 2.)
result = float(1.)
result = 1. # not 1.2928932188134525
After that, it's up to you to figure out what's wrong as you haven't specified why the expected output is the expected output.

Are you sure that [1.000000,2.000000] isn't a correct answer? This code:
d = lambda x,y: round(((x[0]-y[0])**2.0+(x[1]-y[1])**2.0)**0.5, 12)
e = lambda w,x,y,z: float(round((d(y,z)*x[w]+d(z,x)*y[w]+d(x,y)*z[w])/(d(x,y)+d(y,z)+d(z,x)),12))
a,b,c= input()
px,py=e(0,a,b,c),e(1,a,b,c)
print px, py
return floating numbers, for example:
in: ([1.25325,2.34346], [2.25325,4.34346], [22.25325,22.34346])
out: 2.559632791 4.11015248488

Related

Python prints arrays twice

I have written the following implementation of the Extended Euclidean Algorithm:
def extended_euclid(a, b):
x_k = 1 # read x_k
x_k1 = 0 # read x_(k+1)
y_k = 0 # read y_k
y_k1 = 1 # read y_(k+1)
sign = 1
while b != 0:
q = a//b
r = a - q*b
a = b
b = r
xx = x_k1
yy = y_k1
x_k1 = q*x_k1 + x_k
y_k1 = q*y_k1 + y_k
x_k = xx
y_k = yy
sign = -sign
x = sign*x_k
y = sign*y_k
return [a, x, y]
It works as exptected but when I try to print out the result of a function call using the standard function "print" the output gets printed twice. So when I do
print(extended_euclid(15,10))
I get the output
[5, 1, 1]
[5, 1, 1]
I do not understand why the output gets printed twice, could you explain that to me.
Also when I do
a = extended_euclid(15,10)
print(a[1])
I get
1
1
which I do not understand either.
EDIT: The problem was that I mistakenly imported a file twice, which led to some unexpected results. Maybe this helps somebody.
Check the rest of your code, if you print this euclid function somewhere, delete that print and just call function instead. On my machine this code prints only one result.

Why are lists created by a function not iterable

I'm new to python and don't understand much. I created a function that takes a number and puts all the integers which lead up to that number, including that number, into a list. Or so I thought, turns out I cant actually use the created list as a list. Any ideas on how I can make it useable?
def break_up(x):
"""breaks up the the integers adding up to a number x, starting at 1. Works for any positive number or 0"""
y = 1
b = 1
a = []
while y <= x:
n = x - x + b
b = b + 1
y = y + 1
a.append(n)
print(a)
As people have commented, your indentation is incorrect, but in addition you are not actually calling the function.
The function needs to return an object. An object created in a function stays there and is not visible outside (unless it is global) - this is called encapsulation and is an important programming technique which enables functions to be used anywhere.
Note that even the multi-line comment has to be indented (and I have made it multi-line)
Here is my version of your program:
def break_up(x):
"""
breaks up the the integers adding up to a number x, starting at 1.
Works for any positive number or 0
"""
y = 1
b = 1
a = []
while y <= x:
n = x - x + b
b = b + 1
y = y + 1
a.append(n)
return a # <<<< added
# At this point, the name 'a' is not visible
thing = break_up(5)
print(thing)
# or
print(break_up(5))
Just for fun, try this:
$ python3 -i gash.py
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
>>> help(break_up)

python - enter the correct number of variables based on function handle

I have a list of variables, and a function object and I would like to assign the correct number of variable depending on the function.
def sum2(x,y):
return x + y
def sum3(x,y,z):
return x + y + z
varList = [1,2,3]
so if f = sum2 , I would like it to call first 2 elements of varList, and if f = sum3 , to call it with 3 elements of the function.
This can be done in a single function, if you are always returning the sum of all the passed arguments.
def sum1(*args):
return sum(args)
This is just utilizing positional arguments, as you don't appear to need to explicitly set individual values. It is also most flexible than the solution provided by ZdaR, as you don't need to know ahead of time the maximum number of arguments you can receive.
Some examples:
>>> print sum1(1, 2, 3)
6
>>> print sum1(1)
1
>>> print sum1(-1, 0, 6, 10)
15
Use the inspect module as follows:
import inspect
n2 = len(inspect.getargspec(sum2)[0])
n3 = len(inspect.getargspec(sum3)[0])
sum2(*varList[0:n2])
sum3(*varList[0:n3])
getargspec returns a 4-tuple of (args, varargs, keywords, defaults). So the above code works if all your args are explicit, i.e. not * or ** args. If you have some of those, change the code accordingly.
You may use default initialization, You should keep in mind the maximum number of variables that could be passed to this function. Then create a function with that number of parameters but initializing them with 0, because a+0 = a(in case some parameters are missing it will replace then with 0 which won't affect the results.)
def sum1(a=0, b=0, c=0, d=0):
return a+b+c+d
print sum1(1)
>>> 1
print sum1(1, 2)
>>> 3
print sum1(1, 2, 3)
>>> 6
print sum1(1, 2, 3, 4)
>>> 10
However, if you call the function with more than 4 arguments, it would raise error statement
Also as suggested by #CoryKramer in the comments you can also pass your varlist = [1, 2, 3, 4] as a parameter :
print sum1(*varlist)
>>> 10
Keeping in mind that the len(varlist) should be less than the number of parameters defined.
A general solution:
To get the number of argument, you can use f.func_code.co_argcount and than pass the correct elements from the list:
def sum2(x,y):
return x + y
def sum3(x,y,z):
return x + y + z
varlist = [2,5,4]
[f(*varlist[:f.func_code.co_argcount]) for f in [sum2,sum3]]
>> [7, 11]
You can check if f is a function with the is keyword
def sum2(x, y):
return x + y
def sum3(x, y, z):
return x + y + z
varList = [1, 2, 3]
f = sum2
if f is sum2:
sum = f(varList[0], varList[1])
print('Sum 2: ' + str(sum))
# Prints: 'Sum 2: 3'
f = sum3
if f is sum3:
sum = f(varList[0], varList[1], varList[2])
print('Sum 3: ' + str(sum))
# Prints: 'Sum 3: 6'
A dict of functions:
def two(l):
return l[0] + l[1]
def three(l):
return l[0] * l[1] + l[2]
funcs = {2:two, 3:three}
l = [1, 2, 3]
print len(l)
print funcs[len(l)](l)

Can't get SymPy to numerically evaluate results of solving a system of equations

***** EDIT *****
Adding a simplified example to show the problem more clearly. Original post below the edit.
I'm trying to get the big mass of ugly code in the original post to produce a simple numerical result. In this reduced example, I have three equations, EqA, EqB, and EqC. EqA and EqB both take numeric inputs. EqC then takes the output from EqA and adds it to the output from EqB. After doing a solve() and an evalf(), I expected to receive a value of 11 as the result, but it just gives me an expression. How would I properly evaluate a system of equations like this?
from sympy import *
from sympy.printing.mathml import print_mathml
init_printing()
Fa,Fb,a,b,c,d,T = symbols('F_a F_b a b c d T')
EqA = Eq(a+b,Fa)
print(EqA)
EqB = Eq(c+d,Fb)
print(EqB)
EqC = Eq(Fa + Fb,T)
print(EqC)
results = (solve([EqA,EqB,EqC],T))
print(results)
print('printing results')
print(results[T].evalf(subs={a:1,b:3,c:3,d:4}))
This produces the following output:
-F_a + a + b
-F_b + c + d
F_a + F_b - T
{T: F_a + F_b}
printing results
F_a + F_b
The expected output for the evalf() statement is 11.
***** /EDIT *****
Can't seem to get this code to produce any numerical output. I'm trying to build up a more complex equation by breaking it into smaller pieces, to make troubleshooting easier. The desired output is to solve for T. However, when I run the solver and then try to evalf() on the output, it just pumps the same expression back out at me. The behavior is identical to when I fail to define all necessary numerical inputs, but I think I have all the relevant ones defined in the evalf() call. Any ideas as to what I'm doing wrong?
from sympy import *
init_printing()
periodOfInterest = symbols('P') #constant
modDensity = symbols('D_m') # result of calculation
floorDensity = symbols('D_f') # result of calculation
distanceTraveledPerPickMod = symbols('x_m') # result of calculation
distanceTraveledPerPickFloor = symbols('x_f') # result of calculation
travelTimePerPickMod = symbols('t_modTravel') # result of calculation
travelTimePerPickFloor = symbols('t_floorTravel') # result of calculation
timePerPickMod = symbols('t_totalMod') # result of calculation
timePerPickFloor = symbols('t_totalFloor') # result of calculation
T = symbols('Total_picks') # result of calculation
unitsMod = symbols('U_m') #constant
zonesMod = symbols('Z_m') #constant
pathLengthMod = symbols('L_m') #constant
travelRate = symbols('R_p') #constant
pickTime = symbols('k_p') #constant
unitsFloor = symbols('U_f') #constant
zonesFloor = symbols('Z_f') #constant
pathLengthFloor = symbols('L_f') #constant
floorPickers = symbols('N_floor') #constant
modPickers = symbols('N_mod') #constant
modDensityEq = Eq(unitsMod/zonesMod , modDensity)
floorDensityEq = Eq(unitsFloor/zonesFloor , floorDensity)
distanceTraveledPerPickModEq = Eq(pathLengthMod/modDensity , distanceTraveledPerPickMod)
distanceTraveledPerPickFloorEq = Eq(pathLengthFloor/floorDensity , distanceTraveledPerPickFloor)
travelTimePerPickModEq = Eq(distanceTraveledPerPickMod/travelRate , travelTimePerPickMod)
travelTimePerPickFloorEq = Eq(distanceTraveledPerPickFloor/travelRate , travelTimePerPickFloor)
timePerPickModEq = Eq(travelTimePerPickMod+pickTime , timePerPickMod)
timePerPickFloorEq = Eq(travelTimePerPickFloor + pickTime , timePerPickFloor)
totalPicksEq = Eq(floorPickers*periodOfInterest/timePerPickFloor + modPickers*periodOfInterest/timePerPickMod, T)
results = (solve([totalPicksEq,timePerPickFloorEq,timePerPickModEq,travelTimePerPickFloorEq,
travelTimePerPickModEq,distanceTraveledPerPickModEq,distanceTraveledPerPickFloorEq,
floorDensityEq,modDensityEq],T))
(results)
results[T]
(results[T]).evalf(subs={
periodOfInterest:60*60,
unitsMod:5000*2/3,
zonesMod:4,
pathLengthMod:3000,
travelRate:1.34,
pickTime:10,
unitsFloor:5000/3,
zonesFloor:2,
pathLengthFloor:3000,
floorPickers:15,
modPickers:35
})
This produces the following output:
N_floor*P/t_totalFloor + N_mod*P/t_totalMod
What you want is for SymPy to update all the pertinent variables and give you the result: you want the equations you have defined and the values for a - d to be simultaneously true. The way to do this is give the values as additional simultaneous equations which must be true:
>>> solve((EqA,EqB,EqC,Eq(a,1),Eq(b,3),Eq(c,3),Eq(d,4)))
{c: 3, F_a: 4, a: 1, d: 4, F_b: 7, b: 3, T: 11}
And this shows your T=11 value that you were seeking.
How about:
results[T].subs({floorPickers: 15, modPickers: 35, periodOfInterest: 60*60, timePerPickMod: 1.0, timePerPickFloor: 1.0})

function that takes in and returns multiple values

Say I have a function that calculates and returns an value:
h = 4.13566733*10**-15
c = 2.99792458*10**(8+9)
def func(x):
for i in w:
A = h*c/i
return A
w = [1]
print func(w)
Fine. But if w is a larger array, say:
w = [1 ,2, 3, 4]
The func returns for the last value in w (4). Understandebly as that is the last item in the for-loop.
But how can I make the func return an array with all 4 values, something like:
[1239, 619, 413, 309]
??
Python supports passing multiple arguments, and returning multiple values. That said, you can change your code to:
def func(w):
return [h*c/i for i in w]
If you now call this, you can get the required array:
>>> w = [1 ,2, 3, 4]
>>> func(w)
[1239.8418743309974, 619.9209371654987, 413.2806247769991, 309.96046858274934]
As for calling with multiple arguments and returning multiple examples, consider the following example method, which takes 2 inputs and returns 3 outputs:
>>> def get_product_modulo_dividend(x, y):
... return x*y, x%y, x/y
>>> get_product_modulo_dividend(100, 10)
(1000, 0, 10)
Make your A a list and append each result to that list
h = 4.13566733*10**-15
c = 2.99792458*10**(8+9)
def func(x):
A = []
for i in w:
A.append(h*c/i)
return A
w = [1,2,3,4]
print func(w)
This outputs:
[1239.8418743309974, 619.92093716549869, 413.2806247769991, 309.96046858274934]
this is similar to what at #mu posted, but it seems like your function is operating on single values that are not connected together and might be more flexible implemented as only taking a number as a param.
h = 4.13566733*10**-15
c = 2.99792458*10**(8+9)
def func(x):
return h*c / x
w = [1,2,3,4]
print([func(x) for x in w])
You can use map, for example.
h = 4.13566733*10**-15
c = 2.99792458*10**(8+9)
def func(x):
return h*c/x
w = [1,2,3]
print map(func, w)
Will return [1239.8418743309974, 619.9209371654987, 413.2806247769991]
And you can use more elegant way (as for me):
h = 4.13566733*10**-15
c = 2.99792458*10**(8+9)
w = [1,2,3]
result = map(lambda (x): h*c/x, w)
Is returns also [1239.8418743309974, 619.9209371654987, 413.2806247769991].

Categories

Resources