# Buggy code
def watch(limit):
    """watch scan rates across the cluster"""
    period = 5.0
    prev = db.db()
    prev_totals = None

    while True:
        click.clear()
        time.sleep(period)
        cur = db.db()
        cur.data["gkrate"] = {}
        progress = []
        prev_buckets = {b.bucket_id: b for b in prev.buckets()}

        totals = {"scanned": 0, "krate": 0, "lrate": 0, "bucket_id": "totals"}

        for b in cur.buckets():
            if not b.scanned:
                continue

            totals["scanned"] += b.scanned
            totals["krate"] += b.krate
            totals["lrate"] += b.lrate

            if b.bucket_id not in prev_buckets:
                b.data["gkrate"][b.bucket_id] = b.scanned / period
            elif b.scanned == prev_buckets[b.bucket_id].scanned:
                continue
            else:
                b.data["gkrate"][b.bucket_id] = (
                    b.scanned - prev_buckets[b.bucket_id].scanned
                ) / period
            progress.append(b)

        if prev_totals is None:
            totals["gkrate"] = "..."
        else:
            totals["gkrate"] = (totals["scanned"] - prev_totals["scanned"]) / period
        prev = cur
        prev_totals = totals

        progress = sorted(progress, key=lambda x: x.gkrate, reverse=True)

        if limit:
            progress = progress[:limit]

        progress.insert(0, utils.Bag(totals))
        format_plain(
            progress,
            None,
            explicit_only=True,
            keys=["bucket_id", "scanned", "gkrate", "lrate", "krate"],
        )


# Traceback (AttributeError)
Traceback (most recent call last):
File "/usr/bin/c7n-salactus", line 11, in <module>
load_entry_point('c7n-salactus==0.3.0', 'console_scripts', 'c7n-salactus')()
File "/usr/lib/python2.7/site-packages/click/core.py", line 722, in __call__
return self.main(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/click/core.py", line 697, in main
rv = self.invoke(ctx)
File "/usr/lib/python2.7/site-packages/click/core.py", line 1066, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/usr/lib/python2.7/site-packages/click/core.py", line 895, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/lib/python2.7/site-packages/click/core.py", line 535, in invoke
return callback(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/c7n_salactus/cli.py", line 576, in watch
progress.insert(0, utils.Bag(totals))
AttributeError: 'module' object has no attribute 'Bag'

# Fixed code
def watch(limit):
    """watch scan rates across the cluster"""
    period = 5.0
    prev = db.db()
    prev_totals = None

    while True:
        click.clear()
        time.sleep(period)
        cur = db.db()
        cur.data["gkrate"] = {}
        progress = []
        prev_buckets = {b.bucket_id: b for b in prev.buckets()}

        totals = {"scanned": 0, "krate": 0, "lrate": 0, "bucket_id": "totals"}

        for b in cur.buckets():
            if not b.scanned:
                continue

            totals["scanned"] += b.scanned
            totals["krate"] += b.krate
            totals["lrate"] += b.lrate

            if b.bucket_id not in prev_buckets:
                b.data["gkrate"][b.bucket_id] = b.scanned / period
            elif b.scanned == prev_buckets[b.bucket_id].scanned:
                continue
            else:
                b.data["gkrate"][b.bucket_id] = (
                    b.scanned - prev_buckets[b.bucket_id].scanned
                ) / period
            progress.append(b)

        if prev_totals is None:
            totals["gkrate"] = "..."
        else:
            totals["gkrate"] = (totals["scanned"] - prev_totals["scanned"]) / period
        prev = cur
        prev_totals = totals

        progress = sorted(progress, key=lambda x: x.gkrate, reverse=True)

        if limit:
            progress = progress[:limit]

        progress.insert(0, Bag(totals))
        format_plain(
            progress,
            None,
            explicit_only=True,
            keys=["bucket_id", "scanned", "gkrate", "lrate", "krate"],
        )