diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml new file mode 100644 index 0000000..ea9cc1b --- /dev/null +++ b/.github/workflows/pytest.yml @@ -0,0 +1,20 @@ +name: Pytest + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.x' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pytest + - name: Test with pytest + run: | + PYTHONPATH=. pytest diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ef03987 --- /dev/null +++ b/.gitignore @@ -0,0 +1,104 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are created by a PyInstaller bundle and not checked into +# git, but they may be mistakenly added when commands are run outside of a +# virtualenv. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyderworkspace + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ diff --git a/streak.py b/streak.py new file mode 100644 index 0000000..7ce9a28 --- /dev/null +++ b/streak.py @@ -0,0 +1,20 @@ +def longest_positive_streak(nums: list[int]) -> int: + """ + Returns the length of the longest run of consecutive values strictly greater than 0. + + An empty list returns 0. + + Non-positive numbers (0 or negative) break the streak. + + Must be deterministic and pure: no randomness, prints, or global state. + """ + max_streak = 0 + current_streak = 0 + for num in nums: + if num > 0: + current_streak += 1 + else: + max_streak = max(max_streak, current_streak) + current_streak = 0 + max_streak = max(max_streak, current_streak) + return max_streak diff --git a/tests/test_streak.py b/tests/test_streak.py new file mode 100644 index 0000000..eb1b093 --- /dev/null +++ b/tests/test_streak.py @@ -0,0 +1,26 @@ +import pytest +from streak import longest_positive_streak + +def test_empty_list(): + assert longest_positive_streak([]) == 0 + +def test_no_positive_numbers(): + assert longest_positive_streak([-1, -2, 0]) == 0 + +def test_single_streak(): + assert longest_positive_streak([1, 2, 3]) == 3 + +def test_multiple_streaks(): + assert longest_positive_streak([1, 2, 0, 1, 2, 3, 0, 1]) == 3 + +def test_streaks_with_negatives(): + assert longest_positive_streak([1, 2, -1, 1, 2, 3, -2, 1]) == 3 + +def test_zeros_breaking_streaks(): + assert longest_positive_streak([1, 0, 2, 3, 0, 4, 5, 6]) == 3 + +def test_leading_zeros(): + assert longest_positive_streak([0, 0, 1, 2, 3]) == 3 + +def test_trailing_zeros(): + assert longest_positive_streak([1, 2, 3, 0, 0]) == 3