<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def get_client(self, shard_key):
 """Get the client for a given shard, based on what's available. If the proper client isn't available, the next available client is returned. If no clients are available, an exception is raised. """

        self._prune_penalty_box()

        if len(self.active_clients) == 0:
            raise ClusterEmptyError("All clients are down.")

        # So that hashing is consistent when a node is down, check against
        # the initial client list. Only use the active client list when
        # the desired node is down.
        # N.B.: I know this is not technically "consistent hashing" as
        #       academically defined. It's a hack so that keys which need to
        #       go elsewhere do, while the rest stay on the same instance.
        if not isinstance(shard_key, bytes):
            shard_key = shard_key.encode("utf-8")
        hashed = mmh3.hash(shard_key)
        pos = hashed % len(self.initial_clients)
        if self.initial_clients[pos] in self.active_clients:
            return self.initial_clients[pos]
        else:
            pos = hashed % len(self.active_clients)
            return self.active_clients[pos]