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.
@@ -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,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -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