why is there this TypeError? - python

i am trying to find the square root a number through the function sqrt(a). fixedPoint(f, epsilon) is a helper function. the problem is that i get a this TypeError: 'float' object is not callable. i am new to programming, so if anybody can help and find were is the bug and explain what does this error mean ??
def fixedPoint(f, epsilon):
"""
f: a function of one argument that returns a float
epsilon: a small float
returns the best guess when that guess is less than epsilon
away from f(guess) or after 100 trials, whichever comes first.
"""
guess = 1.0
for i in range(100):
if abs(f(guess) - guess) < epsilon:
return guess
else:
guess = f(guess)
return guess
def sqrt(a):
def tryit(x):
return 0.5 * (a/x + x)
return fixedPoint(tryit(a), 0.0001)

In sqrt function, the code is passing the return value of the tryit (which is a float value), not tryit itself.
Passing the function itself will solve the problem.
def sqrt(a):
def tryit(x):
return 0.5 * (a/x + x)
return fixedPoint(tryit, 0.0001)

Related

Problem in my program of bisection method

I am getting an error when running the following code:
def f(x):
return x**3-x-2
def bisection(f,a,b,app=0.3):
Fa,Fb=f(a),f(b)
if Fa*Fb>0:
raise Exception('Fails')
for i in range(a,b):
x=(a+b)/2
if f*Fa>0:
a=x
else:
b=x
return x
print(bisection(f,{'a':1,'b':2},0.00003))
Below the output I get when running the script above:
TypeError: unsupported operand type(s) for ** or pow(): 'dict' and 'int'
Any ideas on how to solve this?
There are a couple of issues here. In the bisection function you are supposed to give 4 arguments, f which is a function, a and b which are numbers, and a fourth argument app which is not used in your function currently.
The first issue is that you are giving a dictionary instead of the a and b arguments. The following will work better.
bisection(f=f,a=1,b=2,app=0.00003)
I do not know the bisection method, but from what I can tell from a quick scan on the bisection method from Wikipedia, it should be an N_MAX variable which tells how many iterations you will allow before breaking.
Therefore you should not use a for loop and use a while loop instead.
The new algorithm is then
def f(x):
return x**3-x-2
def bisection(f,a,b,app=0.3, N_MAX=10):
Fa,Fb=f(a),f(b)
if Fa*Fb>0:
raise Exception('Fails')
n = 0
while n < N_MAX:
x=(a+b)/2
if f(x)==0 or ((a-b)/2) < app:
return x
n += 1
if f(x) > 0:
a = x
else:
b = x
return x
print(bisection(f,1,2,0.00003, 10))
>>> 1.5

Is there a way to do something only in non-recursive function?

If I have some function like that:
def function(some number, steps):
if steps == 1: return 1
result = some calculation + function(some number, steps - 1)
return round(result, 2)
which returns some float number.
My question is: Is there a way to return rounded result only when I return result from whole function but not from recursive call (to save precision to calculation).
I hope you understand my question.
Thanks in advance.
Generally speaking, if you want to detect that you are inside a recursive call in Python, you can add a default parameter to the function like so:
def my_func(arg1, arg2, _inside_recursion=False):
# Default calls will have _inside_recursion as False
# Make sure that your recursive calls set the parameter
recursive_result = my_func(arg1, arg2, _inside_recursion=True)
Yes! You can provide a flag that will get triggered for consecutive calls:
def function(some number, steps, do_rounding=True):
if steps == 1:
return 1
result = some calculation + function(some number, steps - 1, False)
if do_rounding:
return round(result, 2)
else:
return result
There's no way you can distinguish whether your current function is being invoked as part of the recursion or as it's first step. You can, however, just introduce a new function which will call the existing one and do any extra rounding.
def internal_function(some number, steps):
if steps == 1: return 1
return some calculation + function(some number, steps - 1)
def function(some_number, steps):
return round(internal_function(some_number, steps), 2)
Edit: while true that the approach with adding an optional argument to the function can serve as well it has two downsides:
pollutes the public interface of the function - your users are now wondering whether they should give the argument a value and what value should they give exactly
makes the computational part longer to read and can also potentially destroy tail-call optimizations.
Maybe you want something like this? This is not equivalent to OP code, but makes sense. It applies some_calculation recursively steps times and rounds the final value.
def function(x, steps):
if steps == 1: return round(x, 2)
return function(some_calculation(x), steps - 1)

Decorators in PyMC

I have three question regarding decorators which I am not able to find answer to :
Q1)What do the arguments to decorators in PyMC (#Deterministic, #Stochastic) denote ?
Q2)
#pymc.stochastic(dtype=int)
def switchpoint(value=10, t_l=0, t_h=110):
def logp(value, t_l, t_h):
if value > t_h or value < t_l:
return -np.inf
else:
return -np.log(t_h - t_l + 1)
def random(t_l, t_h):
from numpy.random import random
return np.round( (t_l - t_h) * random() ) + t_l
1)print switchpoint.logp #prints log-probability as expected
2)print switchpoint.random #does not generate the random number
3)print switchpoint.random() # generates a random number
4)print switchpoint.logp() #error
If 2 did not work and 3 worked then 1 should not have worked and instaed 4 should have worked (which is opposite of what I observed). Can someone explain what is going on ?
Q3)
#pymc.stochastic(dtype=int)
def switchpoint(value=1900, t_l=1851, t_h=1962):
if value > t_h or value < t_l:
# Invalid values
return -np.inf
else:
# Uniform log-likelihood
return -np.log(t_h - t_l + 1)
Here it is not specified that it is logp still if I type switchpoint.logp, this piece of code is executed ?
Q1) The meaning of all the arguments to stochastic is documented here. The arguments to deterministic are the same, plus the additional ones documented here.
Q2) The difference in behavior is that there is some magic inside PyMC that actually executes the switchpoint.logp function and turns it into a Python property, while switchpoint.random doesn't get this treatment, and is kept as a function.
If you're curious about what's actually going on, here's some of the relevant the source:
def get_logp(self):
if self.verbose > 1:
print '\t' + self.__name__ + ': log-probability accessed.'
logp = self._logp.get()
if self.verbose > 1:
print '\t' + self.__name__ + ': Returning log-probability ', logp
try:
logp = float(logp)
except:
raise TypeError, self.__name__ + ': computed log-probability ' + str(logp) + ' cannot be cast to float'
if logp != logp:
raise ValueError, self.__name__ + ': computed log-probability is NaN'
# Check if the value is smaller than a double precision infinity:
if logp <= d_neg_inf:
if self.verbose > 0:
raise ZeroProbability, self.errmsg + ": %s" %self._parents.value
else:
raise ZeroProbability, self.errmsg
return logp
def set_logp(self,value):
raise AttributeError, 'Potential '+self.__name__+'\'s log-probability cannot be set.'
logp = property(fget = get_logp, fset=set_logp, doc="Self's log-probability value conditional on parents.")
There's some other stuff going on there, like during the logp function into something called a LazyFunction, but that's the basic idea.
Q3) The stochastic decorator has some (more) magic in it that uses code introspection to determine if random and logp sub functions are defined inside switchpoint. If they are, it uses the logp sub-function to compute logp, if not, it just uses switchpoint itself. That source code for that is here:
# This gets used by stochastic to check for long-format logp and random:
if probe:
# Define global tracing function (I assume this is for debugging??)
# No, it's to get out the logp and random functions, if they're in there.
def probeFunc(frame, event, arg):
if event == 'return':
locals = frame.f_locals
kwds.update(dict((k,locals.get(k)) for k in keys))
sys.settrace(None)
return probeFunc
sys.settrace(probeFunc)
# Get the functions logp and random (complete interface).
# Disable special methods to prevent the formation of a hurricane of Deterministics
cur_status = check_special_methods()
disable_special_methods()
try:
__func__()
except:
if 'logp' in keys:
kwds['logp']=__func__
else:
kwds['eval'] =__func__
# Reenable special methods.
if cur_status:
enable_special_methods()
for key in keys:
if not kwds.has_key(key):
kwds[key] = None
for key in ['logp', 'eval']:
if key in keys:
if kwds[key] is None:
kwds[key] = __func__
Again, there's some more stuff going on, and it's fairly complicated, but that's the basic idea.

Maximum recursion depth exceeded while comparing two objects

I am currently new to Python and I'm not sure why i'm getting the error:
a<r raised exception RuntimeError: maximum recursion depth exceeded while calling a Python object
when I do this:
a = Rational(1,3)
r = Rational(0,5)
print(a<r)
My current code is:
class Rational:
def _gcd(x,y):
while y != 0:
x, y = y, x % y
return x
def __init__(self, num = 0, denom = 1):
gcd = Rational._gcd(num, denom)
self.num = int(num / gcd)
self.denom = int(denom / gcd)
def __lt__(self, right):
return Rational(self.num, self.denom) < Rational(right.num, right.denom)
It also happens for all the other relational operators when I do the same thing.
Can someone enlighten me on this particular matter? How do I approach or fix this?
Thanks!
This line:
Rational(self.num, self.denom) < Rational(right.num, right.denom)
… is calling the __lt__ method again, leading to an infinite recursion. Try a different approach, assuming that we're using Python 3.x (or in Python 2.x, that from __future__ import division was executed beforehand), this should work:
self.num/self.denom < right.num/right.denom

Improving Newton's Method Recursion

I have solved a previous problem and now I am stuck with this one.
It is asking for an improvement of the previous solution which I posted below, but can't quite understand what the problem is asking. (Also, can't really figure out how to solve it.)
Please help
thanks.
Problem:
Elena complains that the recursive newton function in Project 2 includes
an extra argument for the estimate. The function’s users should not have to
provide this value, which is always the same, when they call this function.
Modify the definition of the function so that it uses a keyword parameter
with the appropriate default value for this argument, and call the function
without a second argument to demonstrate that it solves this problem.
Here is my code:
def newtonSquare(x, estimate):
if abs(x-estimate ** 2) <= 0.000001:
return estimate
else:
return newtonSquare(x, (estimate + x / estimate) / 2)
def main():
num = int(raw_input('Enter a positive number >> '))
print newtonSquare(num, 1.0)
main()
The problem is a complaint that when somebody calls newtonSquare, they always do so with an initial estimate of 1.0. To set it as the default value, unless you explicitly provide it, you only have to modify the definition of the function to:
def newtonSquare(x, estimate = 1.0):
An alternative to the default value solution of Michael's is defining the recursive function local to the newtonSquare function:
def newtonSquare(x):
def f(x, estimate):
if abs(x-estimate ** 2) <= 0.000001:
return estimate
else:
return f(x, (estimate + x / estimate) / 2)
return f(x, 1.0)
def main():
num = int(raw_input('Enter a positive number >> '))
print newtonSquare(num)
main()
In this case having the default value is nicer and more flexible though, but this can still be a useful pattern.

Categories