Testing some tidbits

Wednesday 4 December 2024

I posted a Python tidbit about checking if a string consists entirely of zeros and ones:

Python expressions checking if a string is only zeros and ones

I got a bunch of replies suggesting other ways. I wanted to post those, but I also wanted to check if they were right. A classic testing structure would have required putting them all in functions, etc, which I didn’t want to bother with.

So I cobbled together a test harness for them (also in a gist if you want):

GOOD = [
    "",
    "0",
    "1",
    "000000000000000000",
    "111111111111111111",
    "101000100011110101010000101010101001001010101",
]

BAD = [
    "x",
    "nedbat",
    "x000000000000000000000000000000000000",
    "111111111111111111111111111111111111x",
    "".join(chr(i) for i in range(10000)),
]

TESTS = """
    # The original checks
    all(c in "01" for c in s)
    set(s).issubset({"0", "1"})
    set(s) <= {"0", "1"}
    re.fullmatch(r"[01]*", s)
    s.strip("01") == ""
    not s.strip("01")

    # Using min/max
    "0" <= min(s or "0") <= max(s or "1") <= "1"
    not s or (min(s) in "01" and max(s) in "01")
    ((ss := sorted(s or "0")) and ss[0] in "01" and ss[-1] in "01")

    # Using counting
    s.count("0") + s.count("1") == len(s)
    (not (ctr := Counter(s)) or (ctr["0"] + ctr["1"] == len(s)))

    # Using numeric tests
    all(97*c - c*c > 2351 for c in s.encode())
    max((abs(ord(c) - 48.5) for c in "0"+s)) < 1
    all(map(lambda x: (ord(x) ^ 48) < 2, s))

    # Removing all the 0 and 1
    re.sub(r"[01]", "", s) == ""
    len((s).translate(str.maketrans("", "", "01"))) == 0
    len((s).replace("0", "").replace("1", "")) == 0
    "".join(("1".join((s).split("0"))).split("1")) == ""

    # A few more for good measure
    set(s + "01") == set("01")
    not (set(s) - set("01"))
    not any(filter(lambda x: x not in {"0", "1"}, s))
    all(map(lambda x: x in "01", s))
"""

import re
from collections import Counter
from inspect import cleandoc

g = {
    "re": re,
    "Counter": Counter,
}

for test in cleandoc(TESTS).splitlines():
    test = test.partition("#")[0]
    if not test:
        continue
    for ss, expected in [(GOOD, True), (BAD, False)]:
        for s in ss:
            result = eval(test, {"s": s} | g)
            if bool(result) != expected:
                print("OOPS:")
                print(f"   {s = }")
                print(f"   {test}")
                print(f"   {expected = }")

It’s a good thing I did this because a few of the suggestions needed adjusting, especially for dealing with the empty string. But now they all work, and are checked!

More Python expressions checking if a string is only zeros and ones

BTW, if you prefer Mastodon to BlueSky, the posts are there too: first and second.

Comments

Add a comment:

Ignore this:
Leave this empty:
Name is required. Either email or web are required. Email won't be displayed and I won't spam you. Your web site won't be indexed by search engines.
Don't put anything here:
Leave this empty:
Comment text is Markdown.