Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #101453 > unrolled thread

Confusing on bool data object or class function?

Started byRobert <rxjwg98@gmail.com>
First post2016-01-10 17:57 -0800
Last post2016-01-11 14:17 +1100
Articles 2 — 2 participants

Back to article view | Back to comp.lang.python


Contents

  Confusing on bool data object or class function? Robert <rxjwg98@gmail.com> - 2016-01-10 17:57 -0800
    Re: Confusing on bool data object or class function? Steven D'Aprano <steve@pearwood.info> - 2016-01-11 14:17 +1100

#101453 — Confusing on bool data object or class function?

FromRobert <rxjwg98@gmail.com>
Date2016-01-10 17:57 -0800
SubjectConfusing on bool data object or class function?
Message-ID<582101e1-bb8b-446b-8a47-ce7bd17f11d0@googlegroups.com>
Hi,

When I use an on line code snippet, see below please, I find that 
'converged' in class ConvergenceMonitor is seen as a data.






---------
class ConvergenceMonitor(object):
    """Monitors and reports convergence to :data:`sys.stderr`.

    Parameters
    ----------
    tol : double
        Convergence threshold. EM has converged either if the maximum
        number of iterations is reached or the log probability
        improvement between the two consecutive iterations is less
        than threshold.

    n_iter : int
        Maximum number of iterations to perform.

    verbose : bool
        If ``True`` then per-iteration convergence reports are printed,
        otherwise the monitor is mute.

    Attributes
    ----------
    history : deque
        The log probability of the data for the last two training
        iterations. If the values are not strictly increasing, the
        model did not converge.

    iter : int
        Number of iterations performed while training the model.
    """
    _template = "{iter:>10d} {logprob:>16.4f} {delta:>+16.4f}"

    def __init__(self, tol, n_iter, verbose):
        self.tol = tol
        self.n_iter = n_iter
        self.verbose = verbose
        self.history = deque(maxlen=2)
        self.iter = 0

    def __repr__(self):
        class_name = self.__class__.__name__
        params = dict(vars(self), history=list(self.history))
        return "{0}({1})".format(
            class_name, _pprint(params, offset=len(class_name)))

    def report(self, logprob):
        """Reports convergence to :data:`sys.stderr`.

        The output consists of three columns: iteration number, log
        probability of the data at the current iteration and convergence
        rate.  At the first iteration convergence rate is unknown and
        is thus denoted by NaN.

        Parameters
        ----------
        logprob : float
            The log probability of the data as computed by EM algorithm
            in the current iteration.
        """

    @property
    def converged(self):
        """``True`` if the EM algorithm converged and ``False`` otherwise."""
        # XXX we might want to check that ``logprob`` is non-decreasing.
        return (self.iter == self.n_iter or
                (len(self.history) == 2 and
                 self.history[1] - self.history[0] < self.tol))
/////////

Here is except of the online help content:

 |  Data descriptors defined here:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)
 |  
 |  __weakref__
 |      list of weak references to the object (if defined)
 |  
 |  converged
 |      ``True`` if the EM algorithm converged and ``False`` otherwise.


The data conclusion is verified by the following test code:


from hmmlearn.base import ConvergenceMonitor

class TestMonitor(object):
    def test_converged_by_iterations(self):
        print 'self test0'
        m = ConvergenceMonitor(tol=1e-3, n_iter=2, verbose=False)
        print 'self test1', m.converged
        assert not m.converged
        print 'self test2', m.converged
        m.report(-0.01)
        assert not m.converged
        print 'self test3', m.converged
        m.report(-0.1)
        assert m.converged
        print 'self test4', m.converged

tmp_obj=TestMonitor()
print 'ttt', tmp_obj.test_converged_by_iterations()
mm = ConvergenceMonitor(tol=1e-3, n_iter=2, verbose=False)
print 'self test mm', mm.converged

That is, I can only use:

mm.converged

If I use it in this way:
mm.converged()

it will have error:
TypeError                                 Traceback (most recent call last)
C:\Users\rj\Documents\PythonDocPrj0\hmmlearn-master\hmmlearn\tests\test_base1.py in <module>()
     27 print None
     28 mm = ConvergenceMonitor(tol=1e-3, n_iter=2, verbose=False)
---> 29 print 'self test mm', mm.converged()
     30 

TypeError: 'bool' object is not callable



On the other hand, 'play' in the following class is seen as a member
function:

class Engine(object):
    def __init__(self, scene_map):
        pass

    def play(self):
        print 'play'
        return True

a_game = Engine(scene_map=0.1)
a_game.play()


Why can 'converged' only be seen as a data, while 'play' can be seen as
a function?

Thanks,

[toc] | [next] | [standalone]


#101458

FromSteven D'Aprano <steve@pearwood.info>
Date2016-01-11 14:17 +1100
Message-ID<56931ead$0$1600$c3e8da3$5496439d@news.astraweb.com>
In reply to#101453
On Mon, 11 Jan 2016 12:57 pm, Robert wrote:

> Hi,
> 
> When I use an on line code snippet, see below please, I find that
> 'converged' in class ConvergenceMonitor is seen as a data.

That is because converged is a property. That makes it be seen as data.

>     @property
>     def converged(self):


Properties are computed attributes. Although they have a function deep
inside them, to perform the computation, they are seen from the outside as
data attributes.

See the documentation for "property" for more information, and google
for "descriptor" for the underlying mechanism that allows this to work.
(Warning: descriptors are considered very advanced material.)



-- 
Steven

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web