<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def wait(self, sensor_name, condition_or_value, timeout=5.0, quorum=None, max_grace_period=1.0):
 """Wait for sensor present on all group clients to satisfy a condition. Parameters sensor_name : string The name of the sensor to check condition_or_value : obj or callable, or seq of objs or callables If obj, sensor.value is compared with obj. If callable, condition_or_value(reading) is called, and must return True if its condition is satisfied. Since the reading is passed in, the value, status, timestamp or received_timestamp attributes can all be used in the check. timeout : float or None The total timeout in seconds (None means wait forever) quorum : None or int or float The number of clients that are required to satisfy the condition, as either an explicit integer or a float between 0 and 1 indicating a fraction of the total number of clients, rounded up. If None, this means that all clients are required (the default). Be warned that a value of 1.0 (float) indicates all clients while a value max_grace_period : float or None After a quorum or initial timeout is reached, wait up to this long in an attempt to get the rest of the clients to satisfy condition as well (achieving effectively a full quorum if all clients behave) Returns ------- This command returns a tornado Future that resolves with True when a quorum of clients satisfy the sensor condition, or False if a quorum is not reached after a given timeout period (including a grace period). Raises ------ :class:`KATCPSensorError` If any of the sensors do not have a strategy set, or if the named sensor is not present """

        if quorum is None:
            quorum = len(self.clients)
        elif quorum > 1:
            if not isinstance(quorum, int):
                raise TypeError('Quorum parameter %r must be an integer '
                                'if outside range [0, 1]' % (quorum,))
        elif isinstance(quorum, float):
            quorum = int(math.ceil(quorum * len(self.clients)))
        if timeout and max_grace_period:
            # Avoid having a grace period longer than or equal to timeout
            grace_period = min(max_grace_period, timeout / 2.)
            initial_timeout = timeout - grace_period
        else:
            grace_period = max_grace_period
            initial_timeout = timeout
        # Build dict of futures instead of list as this will be easier to debug
        futures = {}
        for client in self.clients:
            f = client.wait(sensor_name, condition_or_value, initial_timeout)
            futures[client.name] = f
        # No timeout required here as all futures will resolve after timeout
        initial_results = yield until_some(done_at_least=quorum, **futures)
        results = dict(initial_results)
        # Identify stragglers and let them all respond within grace period
        stragglers = {}
        for client in self.clients:
            if not results.get(client.name, False):
                f = client.wait(sensor_name, condition_or_value, grace_period)
                stragglers[client.name] = f
        rest_of_results = yield until_some(**stragglers)
        results.update(dict(rest_of_results))
        class TestableDict(dict):
            """Dictionary of results that can be tested for overall success."""
            def __bool__(self):
                return sum(self.values()) >= quorum
            # Was not handled automatrically by futurize, see
            # https://github.com/PythonCharmers/python-future/issues/282
            if sys.version_info[0] == 2:
                __nonzero__ = __bool__
        raise tornado.gen.Return(TestableDict(results))