I posted a Python tidbit about checking if a string consists entirely of 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!
BTW, if you prefer Mastodon to BlueSky, the posts are there too: first and second.
Also BTW: Brian Okken adapted these tests to pytest, showing some interesting pytest techniques.
Comments
Here’s some timings from running the test cases 100 times:
And the modified code:
This is fun, and I learned a few basic Python tricks.
But I also wanted to try to get all of these tests to run with pytest. :)
Here’s my approach to testing these methods with pytest:
Testing some tidbits with pytest
Add a comment: