Skip to content

Instantly share code, notes, and snippets.

@abeyer
Created April 9, 2017 09:11
Show Gist options
  • Save abeyer/6a6630a1c53e77ca9c213795ea34365d to your computer and use it in GitHub Desktop.
Save abeyer/6a6630a1c53e77ca9c213795ea34365d to your computer and use it in GitHub Desktop.
Quick demo running pytest, hypothesis, and doctest together
[pytest]
addopts = --doctest-modules
import hypothesis
from hypothesis.strategies import integers
import pytest
from tidy import max_tidy, tidy
def test_max_tidy():
"""simple pytest"""
assert max_tidy(9) == 9
@pytest.mark.parametrize("test_input,expected", [
(132, 129),
(1000, 999),
(1111111111111111110, 999999999999999999),
])
def test_max_tidy_cases(test_input, expected):
"""pytest parameterization"""
assert max_tidy(test_input) == expected
@hypothesis.given(integers(min_value=1))
def test_max_tidy_props(n):
"""hypothesis givens"""
t = max_tidy(n)
assert t <= n
assert tidy(t)
import sys
def tidy(n):
"""Test if n is tidy.
A tidy number is a positive integer with nondecreasing digits as read from
left to right.
Any one digit number is tidy.
>>> tidy(1)
True
>>> tidy(9)
True
A number with decreasing digits is not tidy.
>>> tidy(21)
False
A number with repeated digits is ok, though.
>>> tidy(112233)
True
"""
if n < 1:
return False
chars = list(str(n))
for i in range(1, len(chars)):
if chars[i] < chars[i-1]:
return False
return True
def max_tidy(n):
"""Find the largest tidy number <= n
"""
chars = list(str(n))
while True:
for i in range(1, len(chars)):
if chars[i] >= chars[i-1]:
continue
else:
split = i
break
else:
return int(''.join(chars))
left = list(str(int(''.join(chars[:split])) - 1))
right = ['9'] * len(chars[split:])
chars = left+right
def main():
t = int(sys.stdin.readline())
for case in range(1, t+1):
n = int(sys.stdin.readline())
print("Case #{}: {}".format(case, max_tidy(n)))
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment