From 1de9ed7687788669b2fea1f77658fc8dedb3eac5 Mon Sep 17 00:00:00 2001 From: VarunArora24 Date: Sat, 18 Oct 2025 16:20:45 +0530 Subject: [PATCH 1/6] Added a program to check whether a number is disarium or not --- maths/special_numbers/disarium_number.py | 27 ++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 maths/special_numbers/disarium_number.py diff --git a/maths/special_numbers/disarium_number.py b/maths/special_numbers/disarium_number.py new file mode 100644 index 000000000000..565a7676576b --- /dev/null +++ b/maths/special_numbers/disarium_number.py @@ -0,0 +1,27 @@ +def is_disarium(num): + """ + Check if a number is a Disarium number. + A Disarium number is a number in which the sum of its digits + powered with their respective positions is equal to the number itself. + + Example: + 135 -> 1¹ + 3² + 5³ = 135 ✅ + """ + digits = str(num) + total = 0 + position = 1 + + for i in digits: + total += int(i) ** position + position += 1 + + if total == num: + return True + else: + return False + + +if __name__ == "__main__": + test_numbers = [89, 135, 175, 518, 9, 10] + for n in test_numbers: + print(f"{n} → {'Disarium' if is_disarium(n) else 'Not Disarium'}") From ccbd0d2fe39a162afe6f45837d7d1c41df8a9e93 Mon Sep 17 00:00:00 2001 From: VarunArora24 Date: Sat, 18 Oct 2025 16:50:08 +0530 Subject: [PATCH 2/6] Fixed the return statement and improved syntax --- maths/special_numbers/disarium_number.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/maths/special_numbers/disarium_number.py b/maths/special_numbers/disarium_number.py index 565a7676576b..8264f9ba8637 100644 --- a/maths/special_numbers/disarium_number.py +++ b/maths/special_numbers/disarium_number.py @@ -15,10 +15,7 @@ def is_disarium(num): total += int(i) ** position position += 1 - if total == num: - return True - else: - return False + return total == num if __name__ == "__main__": From 626c456bafe5d6ce7066242e96fe1f942b248e8d Mon Sep 17 00:00:00 2001 From: VarunArora24 Date: Sat, 18 Oct 2025 17:20:47 +0530 Subject: [PATCH 3/6] Add type hints and doctests for is_disarium function --- maths/special_numbers/disarium_number.py | 27 +++++++++++++++++------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/maths/special_numbers/disarium_number.py b/maths/special_numbers/disarium_number.py index 8264f9ba8637..dc890db4869f 100644 --- a/maths/special_numbers/disarium_number.py +++ b/maths/special_numbers/disarium_number.py @@ -1,11 +1,25 @@ -def is_disarium(num): +def is_disarium(num: int) -> bool: """ Check if a number is a Disarium number. + A Disarium number is a number in which the sum of its digits powered with their respective positions is equal to the number itself. - Example: - 135 -> 1¹ + 3² + 5³ = 135 ✅ + Args: + num (int): The number to check. + + Returns: + bool: True if num is a Disarium number, False otherwise. + + Examples: + >>> is_disarium(135) + True + >>> is_disarium(89) + True + >>> is_disarium(75) + False + >>> is_disarium(9) + True """ digits = str(num) total = 0 @@ -16,9 +30,6 @@ def is_disarium(num): position += 1 return total == num - - if __name__ == "__main__": - test_numbers = [89, 135, 175, 518, 9, 10] - for n in test_numbers: - print(f"{n} → {'Disarium' if is_disarium(n) else 'Not Disarium'}") + import doctest + doctest.testmod() From cc4918c645d986c90229dbb5496917c4fc80dde7 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 18 Oct 2025 11:51:20 +0000 Subject: [PATCH 4/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- maths/special_numbers/disarium_number.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/maths/special_numbers/disarium_number.py b/maths/special_numbers/disarium_number.py index dc890db4869f..4cd72bdb074e 100644 --- a/maths/special_numbers/disarium_number.py +++ b/maths/special_numbers/disarium_number.py @@ -30,6 +30,9 @@ def is_disarium(num: int) -> bool: position += 1 return total == num + + if __name__ == "__main__": import doctest + doctest.testmod() From 031d0e666de1198b08c58106b83ae313e51758b1 Mon Sep 17 00:00:00 2001 From: VarunArora24 Date: Sun, 19 Oct 2025 18:35:00 +0530 Subject: [PATCH 5/6] Added command line calculator script --- scripts/command_line_calculator.py | 175 +++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 scripts/command_line_calculator.py diff --git a/scripts/command_line_calculator.py b/scripts/command_line_calculator.py new file mode 100644 index 000000000000..c83ffa204ca0 --- /dev/null +++ b/scripts/command_line_calculator.py @@ -0,0 +1,175 @@ +""" +Expression Evaluator +-------------------- +A Python module that evaluates arithmetic and bitwise expressions. + +Supports: + + - * / ** << >> & | ^ ( ) + + + +Usage: + >>> from evaluator import evaluate + >>> evaluate("2 + 3 * 4") + 14 + >>> evaluate("(2 + 3) * 4") + 20 + >>> evaluate("2 ** 8") + 256 + >>> evaluate("10 | 6") + 14 + >>> evaluate("10 & 6") + 2 + >>> evaluate("(10 | 6) ^ 5") + 9 + >>> evaluate("10 / 4") + 2.5 +""" + +import re + +def evaluate(expr: str): + """ + Evaluate an arithmetic/bitwise expression string and return result. + + Args: + expr (str): Expression to evaluate + + Returns: + int | float: The computed result, automatically casted. + + Examples: + >>> evaluate("2 + 3 * 4") + 14 + >>> evaluate("2 ** 10") + 1024 + >>> evaluate("10 / 4") + 2.5 + >>> evaluate("(10 | 6) ^ 5") + 9 + """ + + # --- Tokenization --- + tokens = re.findall(r'\d+\.\d+|\d+|\*\*|<<|>>|[&|^+\-*/()]', expr.replace(" ", "")) + + # --- Handle unary minus (e.g., -5 + 3) and minus in starting --- + if tokens and tokens[0] == "-": + tokens.insert(0, "0") + + def clean(lst): + return [x for x in lst if x is not None] + + def solve_power(z): + while "**" in z: + i = z.index("**") + z[i - 1] = float(z[i - 1]) ** float(z[i + 1]) + z[i:i + 2] = [None, None] + z = clean(z) + return z + + def solve_div(z): + while "/" in z: + i = z.index("/") + z[i - 1] = float(z[i - 1]) / float(z[i + 1]) + z[i:i + 2] = [None, None] + z = clean(z) + return z + + def solve_mul(z): + while "*" in z: + i = z.index("*") + z[i - 1] = float(z[i - 1]) * float(z[i + 1]) + z[i:i + 2] = [None, None] + z = clean(z) + return z + + def solve_minus(z): + while "-" in z: + i = z.index("-") + z[i] = "+" + z[i + 1] = -1 * float(z[i + 1]) + return z + + def solve_add(z): + while "+" in z: + i = z.index("+") + z[i - 1] = float(z[i - 1]) + float(z[i + 1]) + z[i:i + 2] = [None, None] + z = clean(z) + return z + + def solve_lshift(z): + while "<<" in z: + i = z.index("<<") + z[i - 1] = int(float(z[i - 1])) << int(float(z[i + 1])) + z[i:i + 2] = [None, None] + z = clean(z) + return z + + def solve_rshift(z): + while ">>" in z: + i = z.index(">>") + z[i - 1] = int(float(z[i - 1])) >> int(float(z[i + 1])) + z[i:i + 2] = [None, None] + z = clean(z) + return z + + def solve_and(z): + while "&" in z: + i = z.index("&") + z[i - 1] = int(float(z[i - 1])) & int(float(z[i + 1])) + z[i:i + 2] = [None, None] + z = clean(z) + return z + + def solve_xor(z): + while "^" in z: + i = z.index("^") + z[i - 1] = int(float(z[i - 1])) ^ int(float(z[i + 1])) + z[i:i + 2] = [None, None] + z = clean(z) + return z + + def solve_or(z): + while "|" in z: + i = z.index("|") + z[i - 1] = int(float(z[i - 1])) | int(float(z[i + 1])) + z[i:i + 2] = [None, None] + z = clean(z) + return z + + def solve_parentheses(z): + while "(" in z: + close = z.index(")") + open_ = max(i for i, v in enumerate(z[:close]) if v == "(") + inner = z[open_ + 1:close] + result = evaluate(" ".join(map(str, inner))) + z = z[:open_] + [str(result)] + z[close + 1:] + return z + + tokens = solve_parentheses(tokens) + + # Precedence order + for func in [solve_power, solve_div, solve_mul, solve_minus, solve_add, + solve_lshift, solve_rshift, solve_and, solve_xor, solve_or]: + tokens = func(tokens) + + result = tokens[0] + + # Return as int if it’s cleanly integer-valued + if isinstance(result, (int, float)): + if abs(result - int(result)) < 1e-9: + return int(result) + return float(result) + + # If it's a string (edge-case), convert safely + try: + f = float(result) + return int(f) if f.is_integer() else f + except ValueError: + raise ValueError("Invalid expression or unsupported syntax.") + + +if __name__ == "__main__": + import doctest + doctest.testmod(verbose=True) From 8ca3a442421e41044f89c6c9d5cc041c90d00d98 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 19 Oct 2025 13:17:54 +0000 Subject: [PATCH 6/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- scripts/evaluator.py | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/scripts/evaluator.py b/scripts/evaluator.py index eae3cd3f8f0c..a6c94fbc3748 100644 --- a/scripts/evaluator.py +++ b/scripts/evaluator.py @@ -28,6 +28,7 @@ import re + def evaluate(expr: str): """ Evaluate an arithmetic/bitwise expression string and return result. @@ -50,7 +51,7 @@ def evaluate(expr: str): """ # --- Tokenization --- - tokens = re.findall(r'\d+\.\d+|\d+|\*\*|<<|>>|[&|^+\-*/()]', expr.replace(" ", "")) + tokens = re.findall(r"\d+\.\d+|\d+|\*\*|<<|>>|[&|^+\-*/()]", expr.replace(" ", "")) # --- Handle unary minus (e.g., -5 + 3) and minus in starting --- if tokens and tokens[0] == "-": @@ -63,7 +64,7 @@ def solve_power(z): while "**" in z: i = z.index("**") z[i - 1] = float(z[i - 1]) ** float(z[i + 1]) - z[i:i + 2] = [None, None] + z[i : i + 2] = [None, None] z = clean(z) return z @@ -71,7 +72,7 @@ def solve_div(z): while "/" in z: i = z.index("/") z[i - 1] = float(z[i - 1]) / float(z[i + 1]) - z[i:i + 2] = [None, None] + z[i : i + 2] = [None, None] z = clean(z) return z @@ -79,7 +80,7 @@ def solve_mul(z): while "*" in z: i = z.index("*") z[i - 1] = float(z[i - 1]) * float(z[i + 1]) - z[i:i + 2] = [None, None] + z[i : i + 2] = [None, None] z = clean(z) return z @@ -94,7 +95,7 @@ def solve_add(z): while "+" in z: i = z.index("+") z[i - 1] = float(z[i - 1]) + float(z[i + 1]) - z[i:i + 2] = [None, None] + z[i : i + 2] = [None, None] z = clean(z) return z @@ -102,7 +103,7 @@ def solve_lshift(z): while "<<" in z: i = z.index("<<") z[i - 1] = int(float(z[i - 1])) << int(float(z[i + 1])) - z[i:i + 2] = [None, None] + z[i : i + 2] = [None, None] z = clean(z) return z @@ -110,7 +111,7 @@ def solve_rshift(z): while ">>" in z: i = z.index(">>") z[i - 1] = int(float(z[i - 1])) >> int(float(z[i + 1])) - z[i:i + 2] = [None, None] + z[i : i + 2] = [None, None] z = clean(z) return z @@ -118,7 +119,7 @@ def solve_and(z): while "&" in z: i = z.index("&") z[i - 1] = int(float(z[i - 1])) & int(float(z[i + 1])) - z[i:i + 2] = [None, None] + z[i : i + 2] = [None, None] z = clean(z) return z @@ -126,7 +127,7 @@ def solve_xor(z): while "^" in z: i = z.index("^") z[i - 1] = int(float(z[i - 1])) ^ int(float(z[i + 1])) - z[i:i + 2] = [None, None] + z[i : i + 2] = [None, None] z = clean(z) return z @@ -134,7 +135,7 @@ def solve_or(z): while "|" in z: i = z.index("|") z[i - 1] = int(float(z[i - 1])) | int(float(z[i + 1])) - z[i:i + 2] = [None, None] + z[i : i + 2] = [None, None] z = clean(z) return z @@ -142,16 +143,26 @@ def solve_parentheses(z): while "(" in z: close = z.index(")") open_ = max(i for i, v in enumerate(z[:close]) if v == "(") - inner = z[open_ + 1:close] + inner = z[open_ + 1 : close] result = evaluate(" ".join(map(str, inner))) - z = z[:open_] + [str(result)] + z[close + 1:] + z = z[:open_] + [str(result)] + z[close + 1 :] return z tokens = solve_parentheses(tokens) # Precedence order - for func in [solve_power, solve_div, solve_mul, solve_minus, solve_add, - solve_lshift, solve_rshift, solve_and, solve_xor, solve_or]: + for func in [ + solve_power, + solve_div, + solve_mul, + solve_minus, + solve_add, + solve_lshift, + solve_rshift, + solve_and, + solve_xor, + solve_or, + ]: tokens = func(tokens) result = tokens[0] @@ -168,8 +179,9 @@ def solve_parentheses(z): return int(f) if f.is_integer() else f except ValueError: raise ValueError("Invalid expression or unsupported syntax.") - + if __name__ == "__main__": import doctest + doctest.testmod(verbose=True)