How to compare values of mathematic functions in a python function (def) - python

I am writting a code to compare mathematic functions and say which one of them has the biggest value for given x and y
import math
def r(x,y):
r = 3 * math.pow(x, 2) + math.pow(y, 2)
return r
def b(x,y):
b = 2 * math.pow(x, 2) + 5 * math.pow(y, 2)
return b
def c(x,y):
c = -100 * x + math.pow(y, 3)
return c
def compare():
x = float(input("Type the value of x: "))
y = float(input("Type the value of y: "))
r(x,y)
b(x,y)
c(x,y)
if r > b and c:
print("r is the biggest.")
return
elif b > r and c:
print("b is the biggest.")
return
elif c > b and r:
print("c is the biggest.")
return
compare()
But I get the following error:
TypeError: '>' not supported between instances of 'function' and 'function'

You must assign the result of each function to a variable. Try the following:
import math
def r(x,y):
r = 3 * math.pow(x, 2) + math.pow(y, 2)
return r
def b(x,y):
b = 2 * math.pow(x, 2) + 5 * math.pow(y, 2)
return b
def c(x,y):
c = -100 * x + math.pow(y, 3)
return c
def compare():
x = float(input("Type the value of x: "))
y = float(input("Type the value of y: "))
R=r(x,y)
B=b(x,y)
C=c(x,y)
if R > B and R>C:
print("r is the biggest.")
return
elif B > R and B>C:
print("b is the biggest.")
return
elif C > B and C>R:
print("c is the biggest.")
return
compare()

There are two bugs here:
You need to compare the actual results of the function, not the function object itself.
You can't compare one numerical value to the and of two other values; what you're actually testing for in that case is a single comparison plus whether the other value is non-zero!
I'd use the max function to get the largest value rather than building a complicated chain of conditionals to do the same thing. That way if you add another function it's easy to just add it to the list:
import math
def r(x, y):
return 3 * math.pow(x, 2) + math.pow(y, 2)
def b(x, y):
return 2 * math.pow(x, 2) + 5 * math.pow(y, 2)
def c(x, y):
return -100 * x + math.pow(y, 3)
def compare():
functions = [r, b, c] # maybe this could be a parameter?
x = float(input("Type the value of x: "))
y = float(input("Type the value of y: "))
result, func_name = max((f(x, y), f.__name__) for f in functions)
print(f"{func_name} is the biggest.")
compare()
Type the value of x: 1
Type the value of y: 2
b is the biggest.
Type the value of x: 0
Type the value of y: 0
r is the biggest.
Type the value of x: -1
Type the value of y: -2
c is the biggest.

Related

TypeError float object cannot be interpreted as an integer

I'm trying to get the result in hex format, but I get the error "TypeError: 'float' object cannot be interpreted as an integer!"
39 d = chinese_remainder(a, n)
---> 40 number = hex(d)
41 print(number)
Code:
import functools
# Euclidean extended algorithm
def egcd(a, b):
if a == 0:
return b, 0, 1
else:
d, x, y = egcd(b % a, a)
return d, y - (b // a) * x, x
"""
Functions whcih calculate the CRT (
return x in ' x = a mod n'.
"""
def chinese_remainder(a, n):
modulus = functools.reduce(lambda a, b: a * b, n)
multipliers = []
for N_i in n:
N = modulus / N_i
gcd, inverse, y = egcd(N, N_i)
multipliers.append(inverse * N % modulus)
result = 0
for multi, a_i in zip(multipliers, a):
result = (result + multi * a_i) % modulus
return result
FN = 1184749
FM = 8118474
FL = 5386565
HN = 8686891
HM = 6036033
HK = 6029230
n = [FN, FM, FL]
a = [HN, HM, HK]
d = chinese_remainder(a, n)
number = hex(d)
print(number)
The result should be like this
FAB15A7AE056200F9
But it gives me
3.3981196080447865e + 19
How to fix this so that the result is in hex format ???
Normal division / operator returns float whereas you can use floor division // to get integers.
As others suggested, you have to use floor division to variable N like this N = modulus//N_i

How to make this float precision without using print

I'm working on assignment, it's about numerical method regarding to trapezoidal rule
def trapezoidalRule(F,a,b,n):
h = float(b-a)/n
f_sum = 0
for i in range(1, n, 1):
x = a + i * h
f_sum = f_sum + f(x)
return h * (0.5 * f(a) + f_sum + 0.5 * f(b))
def f(x):
return x**3
a = 2
b = 10
n = 512
print('%.16f' %trapezoidalRule(f, a, b, n))
And the output is
2496.0058593750000000
My question is, how do i get a precission like that.. without using print('%.16f' %trapezoidalRule(f, a, b, n)). I want to append the result to the list, with exact value like that..
I already tried to google it, but i found nothing related to this problem, can somebody tell me the solution if i want to it ?
Change your return statement in trapezoidalRule to be formatted with 16 points of precision, do note that this is going to cause it to become a string as if you cast it back to float you'll lose the trailing 0's.
def trapezoidalRule(F,a,b,n):
h = float(b-a)/n
f_sum = 0
for i in range(1, n, 1):
x = a + i * h
f_sum = f_sum + f(x)
return format((h * (0.5 * f(a) + f_sum + 0.5 * f(b))), '.16f')
def f(x):
return x**3
a = 2
b = 10
n = 512
See the return line in trapezoidalRule so now if I print the exact output of trapezoidalRule like so: print(trapezoidalRule(f, a, b, n)) with no formatting I get:
2496.0058593750000000
To increase precision try using decimal module
import decimal
def trapezoidalRule(F,a,b,n):
h = decimal.Decimal(float(b-a)/n)
f_sum = 0
for i in range(1, n, 1):
x = a + i * h
f_sum = f_sum + f(x)
return h * (decimal.Decimal(0.5) * f(a) + f_sum + decimal.Decimal(0.5) * f(b))
def f(x):
return decimal.Decimal(x**3)

Calculating derivative of trinomial using the function as a parameter

I need to calculate the derivative of a trinomial function in another function using the former as a parameter. This is my code so far:
def derivative(func):
num=func(a,b,c)
third=func(0,0,c)
first=func(a,0,0)
return (num-third)/x+first/x
def make_quadratic(a, b, c):
return lambda x: x*x*a+b*x+c
I suppose that by using the make_quadratic function I had to add 3 parameters (a,b,c) in func as well. What I am trying to do is remove c, divide with x and then add ax so that the resulting derivative is 2ax+b, I cannot however run the code since for some reason a,b,c are not defined even though I do give them values when I call the function.
Write yourself a class like the following one:
class TrigonomialFunction:
def __init__(self, a, b, c):
self.a, self.b, self.c = a, b, c
def calculate(self, x):
return self.a * x ** 2 + self.b * x + self.c
def derivate(self):
return TrigonomialFunction(0, 2 ** self.a, self.b)
def __str__(self):
return "f(x) = %s x**2 + %s * x + %s" % (self.a, self.b, self.c)
Which can then get used in the following way:
f = TrigonomialFunction(2, 3, -5)
print(f) # will return f(x) = 2 x**2 + 3 * x + -5
print(f.calculate(1)) # returns 0
print(f.calculate(-1)) # returns -6
derivateOfF = f.derivate()
print(derivateOfF) # returns f(x) = 0 x**2 + 4 * x + 3 which can be simplified to f(x) = 4*x + 3
print(derivateOfF.calculate(0)) # returns 3
derivateOfderivateOfF = derivateOfF.derivate()
print(derivateOfderivateOfF) # guess ;)
You can calculate the derivative of any function using sympy.
For your function, you can use:
import sympy
def get_derivative(func, x):
return sympy.diff(func, x)
def make_quadratic(a, b, c):
x = sympy.symbols('x')
func = a * x**2 + b * x + c
return func, x
func, x = make_quadratic(1, 2, 3)
print(get_derivative(func, x))
Which returns 2*x + 2

LCM using recursive?

Here is my code:
def lcm(a, b):
if b == 0:
return a
return a * b / lcm(a, b)
print lcm(5,3)
This is what I could manage so far, any idea on how to find the LCM (least common multiple) of two numbers using recursive and one function?
We have lcm(a, b) * gcd(a, b) = a * b. So we can write the following equation:
lcm(a, b) = a; if a % b == 0
lcm(a, b) ; if a % b != 0
= a * b / gcd(a, b)
= a * b / gcd(b, a % b)
= a * b / (b * (a % b) / lcm(b, a % b))
= a / (a % b) * lcm(b, a % b)
And translate to Python, we have:
def lcm(a, b):
t = a % b
if t == 0: return a
return a * lcm(b, t) / t
Edit: I didn't read the recursive / one function bit in your question cause I'm dumb. Incorporated now.
The lcm isn't a * b / lcm(a, b), it's a * b / gcd(a, b) (greatest common divisor).
So the cleanest way to do this is:
def gcd(x, y):
while y:
x, y = y, x % y
return x
def lcm(x, y):
return x * y / gcd(x, y)
If you are limited to recursion only (e.g. for an exam) then this doesn't have to be efficient, so you might as well just recursively count up until you find the lowest number that both x and y divide into:
def lcm(x, y, counter=1):
if (counter%x == 0 and counter%y == 0):
return counter
return lcm(x, y, counter+1)
That just increases counter until counter%x == 0 and counter%y == 0 is true, which is the LCM. Don't try it on large numbers though, you'll just get a stack overflow.
As stated in the other answers here lcm = a*b / gcd(a, b)but then you will need to define another function gcd(a, b) for it.
Since you needed only 1 function with recursion, maybe this piece of code will do.
N.B. : This function has one extra parameter c which should be always passed as 1 while calling it outside the function only :
def lcm(a, b, c):
d = c
m = min(a, b)
while m > 1 :
if a%m == 0 and b%m == 0 :
d*=m
return lcm(int(a/m), int(b/m), d)
else:
m-= 1
d*= a*b
return d
Using the mathematical relationship that the product of two numbers is equal to the product of the Greatest Common Divisor and the Least Common Multiplier of those two numbers: A * B = GCD(A,B) * LCM(A,B)
def gcd(a,b):
if a % b == 0: return b
return gcd(b, a % b)
def lcm(a, b):
return ((a*b) // gcd(a,b))
The first function is recursive and it's used to find the Greatest Common Divisor, it has cost O(log(n)).
This should do:
# Python Program to find the L.C.M. of two input number
# define a function
def lcm(x, y):
"""This function takes two
integers and returns the L.C.M."""
# choose the greater number
if x > y:
greater = x
else:
greater = y
while True:
if((greater % x == 0) and (greater % y == 0)):
lcm = greater
break
greater += 1
return lcm
# take input from the user
num1 = int(input("Enter first number: "))
num2 = int(input("Enter second number: "))
print("The L.C.M. of", num1,"and", num2,"is", lcm(num1, num2))
I created my own easy programme.
def lcm(greater,a,b):
# while(True):
if (greater % a == 0 and greater % b == 0):
lcm1 = greater
return lcm1
else:
lcm1=lcm(greater + 1,a,b)
return lcm1
a=int(input(" Enter 1st number :"))
b=int(input(" Enter 2nd number :"))
if(a>b):
greater=a
else:
greater=b
print(lcm(greater,a,b))

passing a value calculated from one function to another

I have been doing python programming for my project and I have just started. This might be another trivial question. I have this code in which I need to use a value calculated in the function poly_root() which is x. That value should be used as u in the bezier() function. After poly_root() function it should go to bezier() function with its calculated value. I dont know if I am doing it in the correct way. There is no error but it doesnt print t from the bezier() function. Thank you very much.
import copy
import math
poly = [[-0.8,3], [0.75,2], [-0.75,1], [0.1,0]]
def poly_diff(poly):
""" Differentiate a polynomial. """
newlist = copy.deepcopy(poly)
for term in newlist:
term[0] *= term[1]
term[1] -= 1
return newlist
def poly_apply(poly, x):
""" Apply values to the polynomial. """
sum = 0.0 # force float
for term in poly:
sum += term[0] * (x ** term[1])
return sum
def poly_root(poly, start, n, r_i):
""" Returns a root of the polynomial, with a starting value."""
poly_d = poly_diff(poly)
x = start # starting guess value
counter = 0
while True:
if (n >= 0) and (n < 1):
break
x_n = x - (float(poly_apply(poly, x)) / poly_apply(poly_d, x))
if x_n == x:
break
x = x_n # this is the u value corresponding to the given time which will be used in bezier equation
n -= 1
counter += 1
if r_i:
#print [x, counter])
return [x, counter]
else:
#print x
return x
bezier(x)
def bezier(value) :
""" Calculates control points using rational bezier curve equation"""
u = value
w = 5
t = math.pow(1-u,3) * points[0][0] + 3 * u * math.pow(1-u,2) * points[1][0] \
+ 3 * (1-u) * math.pow(u,2) * points[2][0] + math.pow(u,3) * points[3][0]
t = t * w
d = math.pow(1-u,3) * w + 3 * u * w * math.pow(1-u,2) + 3 * (1-u) * w \
* math.pow(u,2) + math.pow(u,3) * w
t = t / d
print t
if __name__ == "__main__" :
poly_root(poly, 0.42, 1, 0)
In this part of code:
if r_i:
#print [x, counter])
return [x, counter]
else:
#print x
return x
bezier(x)
bezier(x) is unreachable. You need to rewrite it.
It would be better for poly_root to return the same type of thing in both situations (i.e. a list with two elements) ...
if r_i:
return [x, counter]
else:
return [x, None]
Then at the bottom, you can have ...
if __name__ == "__main__" :
x, counter = poly_root(poly, 0.42, 1, 0)
if counter is None: # I don't know if this is what you intended with your code.
bezier(x)

Categories