Nine
A Python command-line application that recursively calculates the digital root of an integer after multiplying it by nine.
Nine was created as a practical project to explore recursion, package structure, automated testing, Python packaging, and production-style development.
Features
- Accepts whole numbers, including positive and negative integers
- Handles zero as a special case
- Multiplies the supplied number by 9
- Recursively calculates the digit sum
- Continues recursively until the digital root is reached
- Validates invalid user input
- Provides a command-line interface
- Includes automated tests using
pytest - Distributed as a standard Python package
For every positive integer n, the digital root of n × 9 is 9. Zero returns 0.
For example:
27 × 9 = 243
2 + 4 + 3 = 9
Tech Stack
- Language: Python
- Testing: pytest
- Packaging: setuptools
- Build: Python Build
- Distribution: PyPI / TestPyPI
- Interface: Command-line application
Getting Started
Prerequisites
- Python 3.10 or later
Installation
The package can be installed from PyPI using:
python -m pip install nine-recursive-calculator
Run the application
After installation, run:
nine
You will be prompted to enter an integer.
Example:
Enter a number: 27
Number entered: 27
Product: 243
Digital root: 9
Development Installation
To work with the source code locally, clone the repository:
git clone https://github.com/bistudio/codeplay.git
cd codeplay/python/nine-project
Create a virtual environment:
python -m venv .venv
Windows PowerShell
.\.venv\Scripts\Activate.ps1
macOS / Linux
source .venv/bin/activate
Install the package in editable mode:
python -m pip install -e .
Run the application:
nine
Usage
Enter a whole number when prompted.
Positive integer
Enter a number: 37
Number entered: 37
Product: 333
Digital root: 9
Zero
Enter a number: 0
Number entered: 0
Product: 0
Digital root: 0
Negative integer
Negative numbers are converted to their absolute value before calculation.
Enter a number: -27
Number entered: -27
Product: -243
Digital root: 9
Invalid input
Invalid or blank input is rejected:
Enter a number:
Invalid input. Please enter a whole number.
How It Works
The project uses recursion in two functions.
digit_sum(n)
digit_sum() recursively calculates the sum of the individual digits of an integer.
For example:
digit_sum(243)
The recursive calculation is:
243 % 10 = 3
24 % 10 = 4
2 % 10 = 2
Therefore:
2 + 4 + 3 = 9
nine(n)
nine() multiplies the supplied number by 9 and recursively processes the resulting digit sum until the digital root is reached.
For example:
nine(27)
27 × 9 = 243
digit_sum(243) = 9
nine(9) = 9
The recursion stops when the base case is reached.
API Reference
digit_sum(n)
Purpose: Recursively calculates the sum of the digits of an integer.
Parameter:
n: int
Returns:
int
Returns the sum of the digits. 0 returns 0.
Example:
digit_sum(243)
Returns:
9
nine(n)
Purpose: Multiplies an integer by 9 and recursively calculates its digital root.
Parameter:
n: int
Returns:
int
Returns the digital root. Positive integers return 9; zero returns 0.
Example:
nine(27)
Calculation:
27 × 9 = 243
2 + 4 + 3 = 9
Returns:
9
Testing
The project uses pytest.
Run the complete test suite with:
pytest
The current test suite contains 13 tests covering:
- Positive integers
- Negative integers
- Zero
- Single-digit numbers
- The value 9
- The transition around 10
- Very large integers
- Invalid input
- Blank input
- Command-line behaviour
- Recursion behaviour
What I Learned
This project began as a simple recursion exercise and developed into a practical Python package.
The project provided an opportunity to learn:
- Base cases
- Recursive calls
- Recursion unwinding
- Local state within recursive calls
- Passing state through recursion
- Recursive digit processing
- Function composition
- Input validation
- Automated testing
- Test-driven improvements
- Python package structure
srclayoutpyproject.toml- Building wheels and source distributions
- Package metadata
- Command-line entry points
- TestPyPI publishing
- Installing packages from a package index
- Git branching, commits and releases
One of the main lessons from the project is that there can be many ways to solve a problem. Developing a strong solution requires understanding the trade-offs between correctness, readability, maintainability and efficiency, while remaining open to improving the implementation as knowledge develops.
Future Improvements
- Improve code efficiency and readability as understanding develops
- Expand automated test coverage
- Add command-line arguments
- Improve command-line error handling
- Add package documentation
- Add a web interface
- Explore alternative implementations and compare their performance
Project Structure
nine-project/
├── src/
│ └── nine/
│ ├── __init__.py
│ ├── calculator.py
│ └── cli.py
├── tests/
│ ├── __init__.py
│ ├── test_calculator.py
│ └── test_cli.py
├── README.md
├── pyproject.toml
└── .gitignore
License
This project is licensed under the MIT License.
See the repository for the complete license information.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nine_recursive_calculator-0.1.2.tar.gz.
File metadata
- Download URL: nine_recursive_calculator-0.1.2.tar.gz
- Upload date:
- Size: 5.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dd7e26dde81631b3ed4f41d07fb5e23b8affbdd9b36f59ac3302e4f717859df8
|
|
| MD5 |
7326c3a422d25331fa3ba2037dc31c5b
|
|
| BLAKE2b-256 |
172cf8fdd49bc4b2a18d793e341fa4df57dc75b3d2145185daff2dab3042c7bc
|
File details
Details for the file nine_recursive_calculator-0.1.2-py3-none-any.whl.
File metadata
- Download URL: nine_recursive_calculator-0.1.2-py3-none-any.whl
- Upload date:
- Size: 4.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5d011e82d60d05af8d5b09e37b1526a5a596d353810087a0073f840cf79cac65
|
|
| MD5 |
e7ec4503900b2f037c1670723e097183
|
|
| BLAKE2b-256 |
f3014d01e5f13a354757ac7c091460b60a31030fe8d7dbf992bf312492025665
|