quicktools-atom 0.1.1__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.
- quicktools_atom-0.1.1/PKG-INFO +47 -0
- quicktools_atom-0.1.1/README.md +40 -0
- quicktools_atom-0.1.1/pyproject.toml +17 -0
- quicktools_atom-0.1.1/setup.cfg +4 -0
- quicktools_atom-0.1.1/src/quicktools/__init__.py +3 -0
- quicktools_atom-0.1.1/src/quicktools/cli.py +36 -0
- quicktools_atom-0.1.1/src/quicktools/mathtools.py +50 -0
- quicktools_atom-0.1.1/src/quicktools/strtools.py +41 -0
- quicktools_atom-0.1.1/src/quicktools_atom.egg-info/PKG-INFO +47 -0
- quicktools_atom-0.1.1/src/quicktools_atom.egg-info/SOURCES.txt +11 -0
- quicktools_atom-0.1.1/src/quicktools_atom.egg-info/dependency_links.txt +1 -0
- quicktools_atom-0.1.1/src/quicktools_atom.egg-info/entry_points.txt +2 -0
- quicktools_atom-0.1.1/src/quicktools_atom.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: quicktools-atom
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Math and string utilities with a bundled CLI
|
|
5
|
+
Requires-Python: >=3.9
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
|
|
8
|
+
\# quicktools
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
A small toolkit with math and string utilities, plus a bundled CLI.
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
\## Install
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
  pip install quicktools-atom
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
\## Usage
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
  from quicktools import mathtools, strtools
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
  mathtools.is\_prime(97)
|
|
33
|
+
|
|
34
|
+
  strtools.slugify("Hello World")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
\## CLI
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
  quicktools is-prime 97
|
|
43
|
+
|
|
44
|
+
  quicktools stats 1 2 3 4 5
|
|
45
|
+
|
|
46
|
+
  quicktools slugify "Hello World"
|
|
47
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
\# quicktools
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
A small toolkit with math and string utilities, plus a bundled CLI.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
\## Install
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
  pip install quicktools-atom
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
\## Usage
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
  from quicktools import mathtools, strtools
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
  mathtools.is\_prime(97)
|
|
26
|
+
|
|
27
|
+
  strtools.slugify("Hello World")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
\## CLI
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
  quicktools is-prime 97
|
|
36
|
+
|
|
37
|
+
  quicktools stats 1 2 3 4 5
|
|
38
|
+
|
|
39
|
+
  quicktools slugify "Hello World"
|
|
40
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "quicktools-atom"
|
|
7
|
+
version = "0.1.1"
|
|
8
|
+
description = "Math and string utilities with a bundled CLI"
|
|
9
|
+
requires-python = ">=3.9"
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
dependencies = []
|
|
12
|
+
|
|
13
|
+
[project.scripts]
|
|
14
|
+
quicktools = "quicktools.cli:main"
|
|
15
|
+
|
|
16
|
+
[tool.setuptools.packages.find]
|
|
17
|
+
where = ["src"]
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""Command-line interface for quicktools."""
|
|
2
|
+
import argparse
|
|
3
|
+
from quicktools import mathtools, strtools
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def main() -> None:
|
|
7
|
+
parser = argparse.ArgumentParser(prog="quicktools", description="Quick math and text utilities.")
|
|
8
|
+
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
9
|
+
|
|
10
|
+
p_prime = subparsers.add_parser("is-prime", help="Check if a number is prime")
|
|
11
|
+
p_prime.add_argument("number", type=int)
|
|
12
|
+
|
|
13
|
+
p_stats = subparsers.add_parser("stats", help="Compute mean/median/stdev of numbers")
|
|
14
|
+
p_stats.add_argument("numbers", type=float, nargs="+")
|
|
15
|
+
|
|
16
|
+
p_slug = subparsers.add_parser("slugify", help="Convert text into a url-friendly slug")
|
|
17
|
+
p_slug.add_argument("text")
|
|
18
|
+
|
|
19
|
+
p_palin = subparsers.add_parser("is-palindrome", help="Check if text is a palindrome")
|
|
20
|
+
p_palin.add_argument("text")
|
|
21
|
+
|
|
22
|
+
args = parser.parse_args()
|
|
23
|
+
|
|
24
|
+
if args.command == "is-prime":
|
|
25
|
+
print(f"{args.number} is prime: {mathtools.is_prime(args.number)}")
|
|
26
|
+
elif args.command == "stats":
|
|
27
|
+
nums = args.numbers
|
|
28
|
+
print(f"mean={mathtools.mean(nums):.4f} median={mathtools.median(nums):.4f} stdev={mathtools.std_dev(nums):.4f}")
|
|
29
|
+
elif args.command == "slugify":
|
|
30
|
+
print(strtools.slugify(args.text))
|
|
31
|
+
elif args.command == "is-palindrome":
|
|
32
|
+
print(strtools.is_palindrome(args.text))
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
if __name__ == "__main__":
|
|
36
|
+
main()
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""Math utilities: primes, number theory, and basic statistics."""
|
|
2
|
+
import math
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def is_prime(n: int) -> bool:
|
|
6
|
+
"""Return True if n is a prime number."""
|
|
7
|
+
if n < 2:
|
|
8
|
+
return False
|
|
9
|
+
for i in range(2, int(math.sqrt(n)) + 1):
|
|
10
|
+
if n % i == 0:
|
|
11
|
+
return False
|
|
12
|
+
return True
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def gcd(a: int, b: int) -> int:
|
|
16
|
+
"""Greatest common divisor of a and b."""
|
|
17
|
+
return math.gcd(a, b)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def lcm(a: int, b: int) -> int:
|
|
21
|
+
"""Least common multiple of a and b."""
|
|
22
|
+
return abs(a * b) // math.gcd(a, b)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def mean(numbers: list[float]) -> float:
|
|
26
|
+
"""Arithmetic mean of a list of numbers."""
|
|
27
|
+
if not numbers:
|
|
28
|
+
raise ValueError("mean() requires at least one number")
|
|
29
|
+
return sum(numbers) / len(numbers)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def median(numbers: list[float]) -> float:
|
|
33
|
+
"""Median of a list of numbers."""
|
|
34
|
+
if not numbers:
|
|
35
|
+
raise ValueError("median() requires at least one number")
|
|
36
|
+
nums = sorted(numbers)
|
|
37
|
+
n = len(nums)
|
|
38
|
+
mid = n // 2
|
|
39
|
+
if n % 2 == 0:
|
|
40
|
+
return (nums[mid - 1] + nums[mid]) / 2
|
|
41
|
+
return nums[mid]
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def std_dev(numbers: list[float]) -> float:
|
|
45
|
+
"""Population standard deviation of a list of numbers."""
|
|
46
|
+
if not numbers:
|
|
47
|
+
raise ValueError("std_dev() requires at least one number")
|
|
48
|
+
m = mean(numbers)
|
|
49
|
+
variance = sum((x - m) ** 2 for x in numbers) / len(numbers)
|
|
50
|
+
return math.sqrt(variance)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""String utilities: text checks, transforms, and simple ciphers."""
|
|
2
|
+
import re
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def is_palindrome(text: str) -> bool:
|
|
6
|
+
"""Return True if text reads the same forwards and backwards (ignoring case/spaces)."""
|
|
7
|
+
cleaned = re.sub(r"[^a-zA-Z0-9]", "", text).lower()
|
|
8
|
+
return cleaned == cleaned[::-1]
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def slugify(text: str) -> str:
|
|
12
|
+
"""Convert text into a url-friendly slug, e.g. 'Hello World!' -> 'hello-world'."""
|
|
13
|
+
text = text.lower().strip()
|
|
14
|
+
text = re.sub(r"[^a-z0-9]+", "-", text)
|
|
15
|
+
return text.strip("-")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def word_frequency(text: str) -> dict[str, int]:
|
|
19
|
+
"""Count occurrences of each word in text (case-insensitive)."""
|
|
20
|
+
words = re.findall(r"[a-zA-Z']+", text.lower())
|
|
21
|
+
freq: dict[str, int] = {}
|
|
22
|
+
for w in words:
|
|
23
|
+
freq[w] = freq.get(w, 0) + 1
|
|
24
|
+
return freq
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def caesar_cipher(text: str, shift: int) -> str:
|
|
28
|
+
"""Shift each letter in text by `shift` positions (Caesar cipher). Negative shift decodes."""
|
|
29
|
+
result = []
|
|
30
|
+
for ch in text:
|
|
31
|
+
if ch.isalpha():
|
|
32
|
+
base = ord('A') if ch.isupper() else ord('a')
|
|
33
|
+
result.append(chr((ord(ch) - base + shift) % 26 + base))
|
|
34
|
+
else:
|
|
35
|
+
result.append(ch)
|
|
36
|
+
return "".join(result)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def reverse_words(text: str) -> str:
|
|
40
|
+
"""Reverse the order of words in a sentence."""
|
|
41
|
+
return " ".join(text.split()[::-1])
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: quicktools-atom
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Math and string utilities with a bundled CLI
|
|
5
|
+
Requires-Python: >=3.9
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
|
|
8
|
+
\# quicktools
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
A small toolkit with math and string utilities, plus a bundled CLI.
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
\## Install
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
  pip install quicktools-atom
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
\## Usage
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
  from quicktools import mathtools, strtools
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
  mathtools.is\_prime(97)
|
|
33
|
+
|
|
34
|
+
  strtools.slugify("Hello World")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
\## CLI
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
  quicktools is-prime 97
|
|
43
|
+
|
|
44
|
+
  quicktools stats 1 2 3 4 5
|
|
45
|
+
|
|
46
|
+
  quicktools slugify "Hello World"
|
|
47
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
src/quicktools/__init__.py
|
|
4
|
+
src/quicktools/cli.py
|
|
5
|
+
src/quicktools/mathtools.py
|
|
6
|
+
src/quicktools/strtools.py
|
|
7
|
+
src/quicktools_atom.egg-info/PKG-INFO
|
|
8
|
+
src/quicktools_atom.egg-info/SOURCES.txt
|
|
9
|
+
src/quicktools_atom.egg-info/dependency_links.txt
|
|
10
|
+
src/quicktools_atom.egg-info/entry_points.txt
|
|
11
|
+
src/quicktools_atom.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
quicktools
|