diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e2e0dd9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,100 @@ +# 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/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Documentation builds (Doxygen writes to build/doxygen, see Doxyfile) +docs/_build/ +doxygen_warnings.log + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# Environments +.env +.envrc +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Type checkers and linters +.mypy_cache/ +.dmypy.json +dmypy.json +.pyre/ +.pytype/ +.ruff_cache/ + +# IDEs and editors +.idea/ +.vscode/ +*.swp +*.swo +.spyderproject +.spyproject +.ropeproject + +# Operating system files +.DS_Store +Thumbs.db +desktop.ini diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..da07083 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,48 @@ +[build-system] +requires = ["setuptools>=77"] +build-backend = "setuptools.build_meta" + +[project] +name = "turtle-challenges" +version = "0.1.0" +description = "Turtle graphics exercises from Udemy's 100 Days of Code Python bootcamp (day 18)." +readme = "README.md" +requires-python = ">=3.13" +license = "AGPL-3.0-only" +license-files = ["LICENSE"] +# Only the standard library is used at run time (turtle needs Tk, see README). +dependencies = [] +classifiers = [ + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.13", + "Topic :: Education", +] + +[project.optional-dependencies] +dev = [ + "mypy>=1.13", + "pytest>=8.3", + "ruff>=0.8", +] + +[tool.setuptools.packages.find] +where = ["src"] + +[tool.pytest.ini_options] +pythonpath = ["src", "."] +testpaths = ["tests"] + +[tool.ruff] +line-length = 88 +target-version = "py313" +src = ["src", "tests"] +# Only the project's own code: the framework submodule and agent skills are not ours. +include = ["src/**/*.py", "tests/**/*.py"] + +[tool.ruff.lint] +select = ["ANN", "B", "E", "F", "I", "N", "SIM", "UP", "W"] + +[tool.mypy] +strict = true +files = ["src", "tests"] +mypy_path = "src" diff --git a/src/turtle_challenges/__init__.py b/src/turtle_challenges/__init__.py new file mode 100644 index 0000000..fda5d58 --- /dev/null +++ b/src/turtle_challenges/__init__.py @@ -0,0 +1,7 @@ +"""! +@file __init__.py +@brief Solutions to the turtle graphics challenges of day 18 of Udemy's +100 Days of Code. + +The challenges are added one milestone at a time; see the README. +""" diff --git a/src/turtle_challenges/constants.py b/src/turtle_challenges/constants.py new file mode 100644 index 0000000..cb2fb0a --- /dev/null +++ b/src/turtle_challenges/constants.py @@ -0,0 +1,15 @@ +"""! +@file constants.py +@brief Every constant of the project, in one place. + +Numbers and names used by the challenges live here and nowhere else, so a +challenge can be tuned (for example the number of dashes) without touching its +drawing code. +""" + +## Title of the turtle window. +WINDOW_TITLE = "Turtle Challenges" + +## Largest value of one color channel; also the turtle color mode, so that +## colors can be given as RGB tuples from 0 to 255. +COLOR_MODE = 255 diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_package.py b/tests/test_package.py new file mode 100644 index 0000000..0470738 --- /dev/null +++ b/tests/test_package.py @@ -0,0 +1,14 @@ +import turtle_challenges +from turtle_challenges import constants + + +def test_package_can_be_imported_and_is_documented() -> None: + assert turtle_challenges.__doc__ + + +def test_color_mode_is_the_rgb_range_of_the_course() -> None: + assert constants.COLOR_MODE == 255 + + +def test_window_title_is_not_empty() -> None: + assert constants.WINDOW_TITLE