vedicmaths 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vedicmaths-0.1.0/LICENSE +21 -0
- vedicmaths-0.1.0/PKG-INFO +206 -0
- vedicmaths-0.1.0/README.md +182 -0
- vedicmaths-0.1.0/pyproject.toml +39 -0
- vedicmaths-0.1.0/setup.cfg +4 -0
- vedicmaths-0.1.0/tests/test_arithmetic.py +198 -0
- vedicmaths-0.1.0/vedicmathematics/__init__.py +107 -0
- vedicmaths-0.1.0/vedicmathematics/arithmetic.py +683 -0
- vedicmaths-0.1.0/vedicmaths/__init__.py +4 -0
- vedicmaths-0.1.0/vedicmaths.egg-info/PKG-INFO +206 -0
- vedicmaths-0.1.0/vedicmaths.egg-info/SOURCES.txt +12 -0
- vedicmaths-0.1.0/vedicmaths.egg-info/dependency_links.txt +1 -0
- vedicmaths-0.1.0/vedicmaths.egg-info/requires.txt +3 -0
- vedicmaths-0.1.0/vedicmaths.egg-info/top_level.txt +2 -0
vedicmaths-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Karthik Srinivasan
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: vedicmaths
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python helpers for learning and applying Vedic mathematics techniques.
|
|
5
|
+
Author: Karthik Srinivasan
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/ksriniv2/vedicmaths
|
|
8
|
+
Project-URL: Issues, https://github.com/ksriniv2/vedicmaths/issues
|
|
9
|
+
Keywords: vedic mathematics,vedic maths,mental math,math,education,arithmetic
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Education
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Topic :: Education
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Provides-Extra: dev
|
|
22
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# Vedic Mathematics
|
|
26
|
+
|
|
27
|
+
Python helpers for learning and applying Vedic mathematics techniques. The
|
|
28
|
+
library focuses on two things:
|
|
29
|
+
|
|
30
|
+
- returning correct arithmetic results as simple Python values
|
|
31
|
+
- exposing step-by-step workings that teachers, students, notebooks, and apps
|
|
32
|
+
can display
|
|
33
|
+
|
|
34
|
+
This project is early-stage and intended to grow into an open-source package of
|
|
35
|
+
well-tested Vedic mathematics methods.
|
|
36
|
+
|
|
37
|
+
The first implementation pass is guided by the parsed source chunks in the
|
|
38
|
+
larger Mr Rishi project, especially
|
|
39
|
+
`data/processed/Vedic_mathematics_chunks.jsonl`.
|
|
40
|
+
|
|
41
|
+
## Install for Development
|
|
42
|
+
|
|
43
|
+
```powershell
|
|
44
|
+
git clone https://github.com/ksriniv2/vedicmaths.git
|
|
45
|
+
cd vedicmaths
|
|
46
|
+
python -m pip install -e ".[dev]"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
If you are working from this local starter folder:
|
|
50
|
+
|
|
51
|
+
```powershell
|
|
52
|
+
cd C:\Users\KARTH\OneDrive\Documents\vedicmathematics
|
|
53
|
+
python -m pip install -e ".[dev]"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Quick Start
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from vedicmathematics import (
|
|
60
|
+
nikhilam_multiply,
|
|
61
|
+
nikhilam_steps,
|
|
62
|
+
square_ending_in_5,
|
|
63
|
+
urdhva_tiryagbhyam_multiply,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
print(nikhilam_multiply(98, 97))
|
|
67
|
+
# 9506
|
|
68
|
+
|
|
69
|
+
print(urdhva_tiryagbhyam_multiply(123, 456))
|
|
70
|
+
# 56088
|
|
71
|
+
|
|
72
|
+
print(square_ending_in_5(35))
|
|
73
|
+
# 1225
|
|
74
|
+
|
|
75
|
+
trace = nikhilam_steps(98, 97)
|
|
76
|
+
for step in trace.steps:
|
|
77
|
+
print(step.title, step.expression, "=>", step.value)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
You can also use the shorter package alias:
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from vedicmaths import nikhilam_multiply
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Available Functions
|
|
87
|
+
|
|
88
|
+
| Function | Purpose |
|
|
89
|
+
|---|---|
|
|
90
|
+
| `digit_sum(number)` | Sums the decimal digits of a number. |
|
|
91
|
+
| `sum_digits_until_single(number)` | Repeated digit sum, equivalent to digital root. |
|
|
92
|
+
| `nikhilam_multiply(a, b, base=None)` | Multiplies numbers using a nearby base, commonly a power of ten. |
|
|
93
|
+
| `nikhilam_steps(a, b, base=None)` | Returns the worked steps for Nikhilam multiplication. |
|
|
94
|
+
| `anurupyena_multiply(a, b, working_base, theoretical_base=None)` | Proportionate-base multiplication when a multiple or sub-multiple is more convenient. |
|
|
95
|
+
| `anurupyena_steps(a, b, working_base, theoretical_base=None)` | Worked steps for proportionate-base multiplication. |
|
|
96
|
+
| `urdhva_tiryagbhyam_multiply(a, b)` | General multiplication using the vertically-and-crosswise digit method. |
|
|
97
|
+
| `urdhva_tiryagbhyam_steps(a, b)` | Returns the worked steps for vertically-and-crosswise multiplication. |
|
|
98
|
+
| `left_to_right_add(a, b)` | Addition with a trace-friendly column process. |
|
|
99
|
+
| `left_to_right_add_steps(a, b)` | Worked steps for addition. |
|
|
100
|
+
| `subtract_using_complement(a, b)` | Subtraction by complementing the subtrahend from a power of ten. |
|
|
101
|
+
| `subtract_using_complement_steps(a, b)` | Worked steps for complement subtraction. |
|
|
102
|
+
| `complement(number, base=None)` | Complement from a supplied base or next power of ten. |
|
|
103
|
+
| `all_from_9_last_from_10(number)` | Nikhilam-style complement helper. |
|
|
104
|
+
| `vinculum_digits(number)` | Signed digit representation for digits above 5. |
|
|
105
|
+
| `multiply_by_5(number)` | Shortcut for multiplication by 5. |
|
|
106
|
+
| `multiply_by_9(number)` | Shortcut for multiplication by 9. |
|
|
107
|
+
| `multiply_by_11(number)` | Adjacent-sum shortcut for multiplication by 11. |
|
|
108
|
+
| `multiply_by_11_steps(number)` | Worked steps for multiplication by 11. |
|
|
109
|
+
| `multiply_by_12(number)` | Shortcut for multiplication by 12. |
|
|
110
|
+
| `multiply_by_15(number)` | Shortcut for multiplication by 15. |
|
|
111
|
+
| `multiply_by_25(number)` | Shortcut for multiplication by 25. |
|
|
112
|
+
| `multiply_by_50(number)` | Shortcut for multiplication by 50. |
|
|
113
|
+
| `multiply_by_75(number)` | Shortcut for multiplication by 75. |
|
|
114
|
+
| `multiply_by_99(number)` | Shortcut for multiplication by 99. |
|
|
115
|
+
| `multiply_by_125(number)` | Shortcut for multiplication by 125. |
|
|
116
|
+
| `multiply_by_999(number)` | Shortcut for multiplication by 999. |
|
|
117
|
+
| `multiply_by_repeated_9(number, count)` | Multiply by 9, 99, 999, etc. |
|
|
118
|
+
| `square_ending_in_5(number)` | Squares numbers ending in 5 using the "one more than the previous" pattern. |
|
|
119
|
+
| `square_ending_in_5_steps(number)` | Returns the worked steps for squaring a number ending in 5. |
|
|
120
|
+
| `square_near_base(number, base=None)` | Squares numbers close to a power-of-ten base. |
|
|
121
|
+
| `square_near_base_steps(number, base=None)` | Worked steps for near-base squaring. |
|
|
122
|
+
| `square_near_50(number)` | Shortcut for squaring values near 50. |
|
|
123
|
+
| `cube_ending_in_5(number)` | Cubes numbers ending in 5. |
|
|
124
|
+
| `divide_by_5(number)` | Division by 5 as doubling then dividing by 10. |
|
|
125
|
+
| `divide_by_25(number)` | Division by 25 as multiplying by 4 then dividing by 100. |
|
|
126
|
+
| `recurring_decimal_unit_fraction(denominator, limit=None)` | Decimal expansion of `1 / denominator`, with repeating cycles in parentheses. |
|
|
127
|
+
| `osculator_for_ending_9(divisor)` | Ekadhika-style osculator for divisors ending in 9. |
|
|
128
|
+
| `fraction_to_percent(numerator, denominator)` | Converts fractions to percentages. |
|
|
129
|
+
| `percent_of(percent, number)` | Calculates percent of a number. |
|
|
130
|
+
| `transpose_percent(percent, number)` | Uses `a% of b = b% of a`. |
|
|
131
|
+
| `is_divisible_by_3(number)` | Divisibility by 3 using digit sum. |
|
|
132
|
+
| `is_divisible_by_9(number)` | Divisibility by 9 using digit sum. |
|
|
133
|
+
| `is_divisible_by_11(number)` | Divisibility by 11 using alternating digit sums. |
|
|
134
|
+
| `square_root_if_perfect(number)` | Returns the integer square root for perfect squares, otherwise `None`. |
|
|
135
|
+
| `cube_root_if_perfect(number)` | Returns the integer cube root for perfect cubes, otherwise `None`. |
|
|
136
|
+
| `digital_root(number)` | Computes a number's digital root. |
|
|
137
|
+
| `casting_out_nines_check(a, b, result, operator="*")` | Verifies `+`, `-`, or `*` results using digital roots. |
|
|
138
|
+
|
|
139
|
+
## Example Step Trace
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
from vedicmathematics import nikhilam_steps
|
|
143
|
+
|
|
144
|
+
trace = nikhilam_steps(98, 97)
|
|
145
|
+
print(trace.result)
|
|
146
|
+
# 9506
|
|
147
|
+
|
|
148
|
+
for step in trace.steps:
|
|
149
|
+
print(f"{step.title}: {step.expression} = {step.value}")
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Output:
|
|
153
|
+
|
|
154
|
+
```text
|
|
155
|
+
Choose base: base = 100 = 100
|
|
156
|
+
Find deviations: 98 - 100, 97 - 100 = -2, -3
|
|
157
|
+
Cross subtract: 98 + (-3) = 95
|
|
158
|
+
Multiply deviations: (-2) * (-3) = 6
|
|
159
|
+
Combine: (95 * 100) + (6) = 9506
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Roadmap
|
|
163
|
+
|
|
164
|
+
Good next functions to add:
|
|
165
|
+
|
|
166
|
+
- division using Paravartya Yojayet
|
|
167
|
+
- multiplication by 9, 99, 999, and related bases
|
|
168
|
+
- straight division and auxiliary fractions
|
|
169
|
+
- simple and complex oscillators for divisibility
|
|
170
|
+
- cube-root techniques
|
|
171
|
+
- fraction simplification and recurring decimal patterns
|
|
172
|
+
- richer renderers for traces, such as Markdown and HTML
|
|
173
|
+
|
|
174
|
+
## Development
|
|
175
|
+
|
|
176
|
+
Run tests:
|
|
177
|
+
|
|
178
|
+
```powershell
|
|
179
|
+
python -m pytest
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Project structure:
|
|
183
|
+
|
|
184
|
+
```text
|
|
185
|
+
vedicmathematics/
|
|
186
|
+
vedicmathematics/
|
|
187
|
+
__init__.py
|
|
188
|
+
arithmetic.py
|
|
189
|
+
tests/
|
|
190
|
+
test_arithmetic.py
|
|
191
|
+
pyproject.toml
|
|
192
|
+
README.md
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Contributing
|
|
196
|
+
|
|
197
|
+
Contributions are welcome. Please include:
|
|
198
|
+
|
|
199
|
+
- a clear function name and docstring
|
|
200
|
+
- tests for regular cases and edge cases
|
|
201
|
+
- a `*_steps` variant when the method is teachable step by step
|
|
202
|
+
- examples in the README when adding a major new method
|
|
203
|
+
|
|
204
|
+
## License
|
|
205
|
+
|
|
206
|
+
MIT
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# Vedic Mathematics
|
|
2
|
+
|
|
3
|
+
Python helpers for learning and applying Vedic mathematics techniques. The
|
|
4
|
+
library focuses on two things:
|
|
5
|
+
|
|
6
|
+
- returning correct arithmetic results as simple Python values
|
|
7
|
+
- exposing step-by-step workings that teachers, students, notebooks, and apps
|
|
8
|
+
can display
|
|
9
|
+
|
|
10
|
+
This project is early-stage and intended to grow into an open-source package of
|
|
11
|
+
well-tested Vedic mathematics methods.
|
|
12
|
+
|
|
13
|
+
The first implementation pass is guided by the parsed source chunks in the
|
|
14
|
+
larger Mr Rishi project, especially
|
|
15
|
+
`data/processed/Vedic_mathematics_chunks.jsonl`.
|
|
16
|
+
|
|
17
|
+
## Install for Development
|
|
18
|
+
|
|
19
|
+
```powershell
|
|
20
|
+
git clone https://github.com/ksriniv2/vedicmaths.git
|
|
21
|
+
cd vedicmaths
|
|
22
|
+
python -m pip install -e ".[dev]"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
If you are working from this local starter folder:
|
|
26
|
+
|
|
27
|
+
```powershell
|
|
28
|
+
cd C:\Users\KARTH\OneDrive\Documents\vedicmathematics
|
|
29
|
+
python -m pip install -e ".[dev]"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Quick Start
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
from vedicmathematics import (
|
|
36
|
+
nikhilam_multiply,
|
|
37
|
+
nikhilam_steps,
|
|
38
|
+
square_ending_in_5,
|
|
39
|
+
urdhva_tiryagbhyam_multiply,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
print(nikhilam_multiply(98, 97))
|
|
43
|
+
# 9506
|
|
44
|
+
|
|
45
|
+
print(urdhva_tiryagbhyam_multiply(123, 456))
|
|
46
|
+
# 56088
|
|
47
|
+
|
|
48
|
+
print(square_ending_in_5(35))
|
|
49
|
+
# 1225
|
|
50
|
+
|
|
51
|
+
trace = nikhilam_steps(98, 97)
|
|
52
|
+
for step in trace.steps:
|
|
53
|
+
print(step.title, step.expression, "=>", step.value)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
You can also use the shorter package alias:
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from vedicmaths import nikhilam_multiply
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Available Functions
|
|
63
|
+
|
|
64
|
+
| Function | Purpose |
|
|
65
|
+
|---|---|
|
|
66
|
+
| `digit_sum(number)` | Sums the decimal digits of a number. |
|
|
67
|
+
| `sum_digits_until_single(number)` | Repeated digit sum, equivalent to digital root. |
|
|
68
|
+
| `nikhilam_multiply(a, b, base=None)` | Multiplies numbers using a nearby base, commonly a power of ten. |
|
|
69
|
+
| `nikhilam_steps(a, b, base=None)` | Returns the worked steps for Nikhilam multiplication. |
|
|
70
|
+
| `anurupyena_multiply(a, b, working_base, theoretical_base=None)` | Proportionate-base multiplication when a multiple or sub-multiple is more convenient. |
|
|
71
|
+
| `anurupyena_steps(a, b, working_base, theoretical_base=None)` | Worked steps for proportionate-base multiplication. |
|
|
72
|
+
| `urdhva_tiryagbhyam_multiply(a, b)` | General multiplication using the vertically-and-crosswise digit method. |
|
|
73
|
+
| `urdhva_tiryagbhyam_steps(a, b)` | Returns the worked steps for vertically-and-crosswise multiplication. |
|
|
74
|
+
| `left_to_right_add(a, b)` | Addition with a trace-friendly column process. |
|
|
75
|
+
| `left_to_right_add_steps(a, b)` | Worked steps for addition. |
|
|
76
|
+
| `subtract_using_complement(a, b)` | Subtraction by complementing the subtrahend from a power of ten. |
|
|
77
|
+
| `subtract_using_complement_steps(a, b)` | Worked steps for complement subtraction. |
|
|
78
|
+
| `complement(number, base=None)` | Complement from a supplied base or next power of ten. |
|
|
79
|
+
| `all_from_9_last_from_10(number)` | Nikhilam-style complement helper. |
|
|
80
|
+
| `vinculum_digits(number)` | Signed digit representation for digits above 5. |
|
|
81
|
+
| `multiply_by_5(number)` | Shortcut for multiplication by 5. |
|
|
82
|
+
| `multiply_by_9(number)` | Shortcut for multiplication by 9. |
|
|
83
|
+
| `multiply_by_11(number)` | Adjacent-sum shortcut for multiplication by 11. |
|
|
84
|
+
| `multiply_by_11_steps(number)` | Worked steps for multiplication by 11. |
|
|
85
|
+
| `multiply_by_12(number)` | Shortcut for multiplication by 12. |
|
|
86
|
+
| `multiply_by_15(number)` | Shortcut for multiplication by 15. |
|
|
87
|
+
| `multiply_by_25(number)` | Shortcut for multiplication by 25. |
|
|
88
|
+
| `multiply_by_50(number)` | Shortcut for multiplication by 50. |
|
|
89
|
+
| `multiply_by_75(number)` | Shortcut for multiplication by 75. |
|
|
90
|
+
| `multiply_by_99(number)` | Shortcut for multiplication by 99. |
|
|
91
|
+
| `multiply_by_125(number)` | Shortcut for multiplication by 125. |
|
|
92
|
+
| `multiply_by_999(number)` | Shortcut for multiplication by 999. |
|
|
93
|
+
| `multiply_by_repeated_9(number, count)` | Multiply by 9, 99, 999, etc. |
|
|
94
|
+
| `square_ending_in_5(number)` | Squares numbers ending in 5 using the "one more than the previous" pattern. |
|
|
95
|
+
| `square_ending_in_5_steps(number)` | Returns the worked steps for squaring a number ending in 5. |
|
|
96
|
+
| `square_near_base(number, base=None)` | Squares numbers close to a power-of-ten base. |
|
|
97
|
+
| `square_near_base_steps(number, base=None)` | Worked steps for near-base squaring. |
|
|
98
|
+
| `square_near_50(number)` | Shortcut for squaring values near 50. |
|
|
99
|
+
| `cube_ending_in_5(number)` | Cubes numbers ending in 5. |
|
|
100
|
+
| `divide_by_5(number)` | Division by 5 as doubling then dividing by 10. |
|
|
101
|
+
| `divide_by_25(number)` | Division by 25 as multiplying by 4 then dividing by 100. |
|
|
102
|
+
| `recurring_decimal_unit_fraction(denominator, limit=None)` | Decimal expansion of `1 / denominator`, with repeating cycles in parentheses. |
|
|
103
|
+
| `osculator_for_ending_9(divisor)` | Ekadhika-style osculator for divisors ending in 9. |
|
|
104
|
+
| `fraction_to_percent(numerator, denominator)` | Converts fractions to percentages. |
|
|
105
|
+
| `percent_of(percent, number)` | Calculates percent of a number. |
|
|
106
|
+
| `transpose_percent(percent, number)` | Uses `a% of b = b% of a`. |
|
|
107
|
+
| `is_divisible_by_3(number)` | Divisibility by 3 using digit sum. |
|
|
108
|
+
| `is_divisible_by_9(number)` | Divisibility by 9 using digit sum. |
|
|
109
|
+
| `is_divisible_by_11(number)` | Divisibility by 11 using alternating digit sums. |
|
|
110
|
+
| `square_root_if_perfect(number)` | Returns the integer square root for perfect squares, otherwise `None`. |
|
|
111
|
+
| `cube_root_if_perfect(number)` | Returns the integer cube root for perfect cubes, otherwise `None`. |
|
|
112
|
+
| `digital_root(number)` | Computes a number's digital root. |
|
|
113
|
+
| `casting_out_nines_check(a, b, result, operator="*")` | Verifies `+`, `-`, or `*` results using digital roots. |
|
|
114
|
+
|
|
115
|
+
## Example Step Trace
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
from vedicmathematics import nikhilam_steps
|
|
119
|
+
|
|
120
|
+
trace = nikhilam_steps(98, 97)
|
|
121
|
+
print(trace.result)
|
|
122
|
+
# 9506
|
|
123
|
+
|
|
124
|
+
for step in trace.steps:
|
|
125
|
+
print(f"{step.title}: {step.expression} = {step.value}")
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Output:
|
|
129
|
+
|
|
130
|
+
```text
|
|
131
|
+
Choose base: base = 100 = 100
|
|
132
|
+
Find deviations: 98 - 100, 97 - 100 = -2, -3
|
|
133
|
+
Cross subtract: 98 + (-3) = 95
|
|
134
|
+
Multiply deviations: (-2) * (-3) = 6
|
|
135
|
+
Combine: (95 * 100) + (6) = 9506
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Roadmap
|
|
139
|
+
|
|
140
|
+
Good next functions to add:
|
|
141
|
+
|
|
142
|
+
- division using Paravartya Yojayet
|
|
143
|
+
- multiplication by 9, 99, 999, and related bases
|
|
144
|
+
- straight division and auxiliary fractions
|
|
145
|
+
- simple and complex oscillators for divisibility
|
|
146
|
+
- cube-root techniques
|
|
147
|
+
- fraction simplification and recurring decimal patterns
|
|
148
|
+
- richer renderers for traces, such as Markdown and HTML
|
|
149
|
+
|
|
150
|
+
## Development
|
|
151
|
+
|
|
152
|
+
Run tests:
|
|
153
|
+
|
|
154
|
+
```powershell
|
|
155
|
+
python -m pytest
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Project structure:
|
|
159
|
+
|
|
160
|
+
```text
|
|
161
|
+
vedicmathematics/
|
|
162
|
+
vedicmathematics/
|
|
163
|
+
__init__.py
|
|
164
|
+
arithmetic.py
|
|
165
|
+
tests/
|
|
166
|
+
test_arithmetic.py
|
|
167
|
+
pyproject.toml
|
|
168
|
+
README.md
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Contributing
|
|
172
|
+
|
|
173
|
+
Contributions are welcome. Please include:
|
|
174
|
+
|
|
175
|
+
- a clear function name and docstring
|
|
176
|
+
- tests for regular cases and edge cases
|
|
177
|
+
- a `*_steps` variant when the method is teachable step by step
|
|
178
|
+
- examples in the README when adding a major new method
|
|
179
|
+
|
|
180
|
+
## License
|
|
181
|
+
|
|
182
|
+
MIT
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "vedicmaths"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Python helpers for learning and applying Vedic mathematics techniques."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [
|
|
14
|
+
{ name = "Karthik Srinivasan" }
|
|
15
|
+
]
|
|
16
|
+
keywords = ["vedic mathematics", "vedic maths", "mental math", "math", "education", "arithmetic"]
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 3 - Alpha",
|
|
19
|
+
"Intended Audience :: Education",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Topic :: Education",
|
|
25
|
+
"Topic :: Scientific/Engineering :: Mathematics",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
[project.optional-dependencies]
|
|
29
|
+
dev = ["pytest>=8"]
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Homepage = "https://github.com/ksriniv2/vedicmaths"
|
|
33
|
+
Issues = "https://github.com/ksriniv2/vedicmaths/issues"
|
|
34
|
+
|
|
35
|
+
[tool.setuptools.packages.find]
|
|
36
|
+
include = ["vedicmathematics", "vedicmaths"]
|
|
37
|
+
|
|
38
|
+
[tool.pytest.ini_options]
|
|
39
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from vedicmathematics import (
|
|
4
|
+
all_from_9_last_from_10,
|
|
5
|
+
anurupyena_multiply,
|
|
6
|
+
casting_out_nines_check,
|
|
7
|
+
complement,
|
|
8
|
+
cube_ending_in_5,
|
|
9
|
+
cube_root_if_perfect,
|
|
10
|
+
digit_sum,
|
|
11
|
+
digital_root,
|
|
12
|
+
divide_by_5,
|
|
13
|
+
divide_by_25,
|
|
14
|
+
fraction_to_percent,
|
|
15
|
+
is_divisible_by_3,
|
|
16
|
+
is_divisible_by_9,
|
|
17
|
+
is_divisible_by_11,
|
|
18
|
+
left_to_right_add,
|
|
19
|
+
multiply_by_5,
|
|
20
|
+
multiply_by_9,
|
|
21
|
+
multiply_by_11,
|
|
22
|
+
multiply_by_12,
|
|
23
|
+
multiply_by_15,
|
|
24
|
+
multiply_by_25,
|
|
25
|
+
multiply_by_50,
|
|
26
|
+
multiply_by_75,
|
|
27
|
+
multiply_by_99,
|
|
28
|
+
multiply_by_125,
|
|
29
|
+
multiply_by_999,
|
|
30
|
+
multiply_by_repeated_9,
|
|
31
|
+
nikhilam_multiply,
|
|
32
|
+
nikhilam_steps,
|
|
33
|
+
osculator_for_ending_9,
|
|
34
|
+
percent_of,
|
|
35
|
+
recurring_decimal_unit_fraction,
|
|
36
|
+
square_ending_in_5,
|
|
37
|
+
square_near_50,
|
|
38
|
+
square_near_base,
|
|
39
|
+
square_root_if_perfect,
|
|
40
|
+
subtract_using_complement,
|
|
41
|
+
sum_digits_until_single,
|
|
42
|
+
transpose_percent,
|
|
43
|
+
urdhva_tiryagbhyam_multiply,
|
|
44
|
+
vinculum_digits,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@pytest.mark.parametrize(
|
|
49
|
+
("number", "expected"),
|
|
50
|
+
[(0, 0), (9, 9), (10, 1), (99, 9), (12345, 6), (-987, 6)],
|
|
51
|
+
)
|
|
52
|
+
def test_digital_root(number, expected):
|
|
53
|
+
assert digital_root(number) == expected
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def test_digit_sum_helpers():
|
|
57
|
+
assert digit_sum(98765) == 35
|
|
58
|
+
assert sum_digits_until_single(98765) == 8
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def test_casting_out_nines_check():
|
|
62
|
+
assert casting_out_nines_check(98, 97, 9506)
|
|
63
|
+
assert casting_out_nines_check(45, 17, 62, "+")
|
|
64
|
+
assert not casting_out_nines_check(45, 17, 63, "+")
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@pytest.mark.parametrize(
|
|
68
|
+
("a", "b"),
|
|
69
|
+
[(98, 97), (104, 103), (1002, 1005), (-98, 97), (98, -97)],
|
|
70
|
+
)
|
|
71
|
+
def test_nikhilam_multiply(a, b):
|
|
72
|
+
assert nikhilam_multiply(a, b) == a * b
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def test_nikhilam_steps_exposes_working():
|
|
76
|
+
trace = nikhilam_steps(98, 97)
|
|
77
|
+
assert trace.result == 9506
|
|
78
|
+
assert trace.steps[0].title == "Choose base"
|
|
79
|
+
assert trace.steps[-1].title == "Combine"
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def test_anurupyena_multiply():
|
|
83
|
+
assert anurupyena_multiply(41, 41, 50, 100) == 1681
|
|
84
|
+
assert anurupyena_multiply(46, 44, 50, 100) == 46 * 44
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@pytest.mark.parametrize(
|
|
88
|
+
("a", "b"),
|
|
89
|
+
[(12, 13), (123, 456), (999, 999), (1001, 77), (-321, 45), (-321, -45)],
|
|
90
|
+
)
|
|
91
|
+
def test_urdhva_tiryagbhyam_multiply(a, b):
|
|
92
|
+
assert urdhva_tiryagbhyam_multiply(a, b) == a * b
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@pytest.mark.parametrize("number", [5, 15, 25, 105, 9995, -35])
|
|
96
|
+
def test_square_ending_in_5(number):
|
|
97
|
+
assert square_ending_in_5(number) == number * number
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def test_square_ending_in_5_rejects_other_numbers():
|
|
101
|
+
with pytest.raises(ValueError):
|
|
102
|
+
square_ending_in_5(42)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def test_complements():
|
|
106
|
+
assert complement(87) == 13
|
|
107
|
+
assert complement(887, 1000) == 113
|
|
108
|
+
assert all_from_9_last_from_10(76) == 24
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def test_left_to_right_add():
|
|
112
|
+
assert left_to_right_add(987, 654) == 1641
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@pytest.mark.parametrize(("a", "b"), [(1000, 348), (348, 1000), (12345, 9876)])
|
|
116
|
+
def test_subtract_using_complement(a, b):
|
|
117
|
+
assert subtract_using_complement(a, b) == a - b
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def test_vinculum_digits():
|
|
121
|
+
assert vinculum_digits(18) == (2, -2)
|
|
122
|
+
assert vinculum_digits(76) == (1, -2, -4)
|
|
123
|
+
assert vinculum_digits(576) == (6, -2, -4)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@pytest.mark.parametrize("number", [0, 1, 7, 42, 1234, -56])
|
|
127
|
+
def test_multiplication_shortcuts(number):
|
|
128
|
+
assert multiply_by_5(number) == number * 5
|
|
129
|
+
assert multiply_by_9(number) == number * 9
|
|
130
|
+
assert multiply_by_11(number) == number * 11
|
|
131
|
+
assert multiply_by_12(number) == number * 12
|
|
132
|
+
assert multiply_by_15(number) == number * 15
|
|
133
|
+
assert multiply_by_25(number) == number * 25
|
|
134
|
+
assert multiply_by_50(number) == number * 50
|
|
135
|
+
assert multiply_by_75(number) == number * 75
|
|
136
|
+
assert multiply_by_99(number) == number * 99
|
|
137
|
+
assert multiply_by_125(number) == number * 125
|
|
138
|
+
assert multiply_by_999(number) == number * 999
|
|
139
|
+
assert multiply_by_repeated_9(number, 4) == number * 9999
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
@pytest.mark.parametrize("number", [98, 102, 1004, 47, -103])
|
|
143
|
+
def test_square_near_base(number):
|
|
144
|
+
assert square_near_base(number) == number * number
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
@pytest.mark.parametrize("number", [47, 49, 51, 56])
|
|
148
|
+
def test_square_near_50(number):
|
|
149
|
+
assert square_near_50(number) == number * number
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def test_cube_ending_in_5():
|
|
153
|
+
assert cube_ending_in_5(15) == 15**3
|
|
154
|
+
assert cube_ending_in_5(-25) == (-25) ** 3
|
|
155
|
+
with pytest.raises(ValueError):
|
|
156
|
+
cube_ending_in_5(24)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def test_division_and_percent_helpers():
|
|
160
|
+
assert divide_by_5(125) == 25
|
|
161
|
+
assert divide_by_25(125) == 5
|
|
162
|
+
assert fraction_to_percent(1, 8) == 12.5
|
|
163
|
+
assert percent_of(12.5, 80) == 10
|
|
164
|
+
assert transpose_percent(12.5, 80) == percent_of(80, 12.5)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def test_divisibility_helpers():
|
|
168
|
+
assert is_divisible_by_3(123)
|
|
169
|
+
assert is_divisible_by_9(729)
|
|
170
|
+
assert is_divisible_by_11(121)
|
|
171
|
+
assert not is_divisible_by_11(123)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def test_recurring_decimal_unit_fraction():
|
|
175
|
+
assert recurring_decimal_unit_fraction(2) == "0.5"
|
|
176
|
+
assert recurring_decimal_unit_fraction(3) == "0.(3)"
|
|
177
|
+
assert recurring_decimal_unit_fraction(19) == "0.(052631578947368421)"
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def test_osculator_for_ending_9():
|
|
181
|
+
assert osculator_for_ending_9(19) == 2
|
|
182
|
+
assert osculator_for_ending_9(29) == 3
|
|
183
|
+
with pytest.raises(ValueError):
|
|
184
|
+
osculator_for_ending_9(21)
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def test_perfect_roots():
|
|
188
|
+
assert square_root_if_perfect(144) == 12
|
|
189
|
+
assert square_root_if_perfect(145) is None
|
|
190
|
+
assert cube_root_if_perfect(15625) == 25
|
|
191
|
+
assert cube_root_if_perfect(-15625) == -25
|
|
192
|
+
assert cube_root_if_perfect(15626) is None
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def test_vedicmaths_alias():
|
|
196
|
+
from vedicmaths import nikhilam_multiply as alias_nikhilam_multiply
|
|
197
|
+
|
|
198
|
+
assert alias_nikhilam_multiply(98, 97) == 9506
|