forked from Rockachopa/Timmy-time-dashboard
388 lines
12 KiB
Python
388 lines
12 KiB
Python
"""Gematria computation engine — the language of letters and numbers.
|
||
|
||
Implements multiple cipher systems for gematric analysis:
|
||
- Simple English (A=1 .. Z=26)
|
||
- Full Reduction (reduce each letter value to single digit)
|
||
- Reverse Ordinal (A=26 .. Z=1)
|
||
- Sumerian (Simple × 6)
|
||
- Hebrew (traditional letter values, for A-Z mapping)
|
||
|
||
Also provides numerological reduction, notable-number lookup,
|
||
and multi-phrase comparison.
|
||
|
||
Alexander Whitestone = 222 in Simple English Gematria.
|
||
This is not trivia. It is foundational.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import math
|
||
|
||
# ── Cipher Tables ────────────────────────────────────────────────────────────
|
||
|
||
# Simple English: A=1, B=2, ..., Z=26
|
||
_SIMPLE: dict[str, int] = {chr(i): i - 64 for i in range(65, 91)}
|
||
|
||
# Full Reduction: reduce each letter to single digit (A=1..I=9, J=1..R=9, S=1..Z=8)
|
||
_REDUCTION: dict[str, int] = {}
|
||
for _c, _v in _SIMPLE.items():
|
||
_r = _v
|
||
while _r > 9:
|
||
_r = sum(int(d) for d in str(_r))
|
||
_REDUCTION[_c] = _r
|
||
|
||
# Reverse Ordinal: A=26, B=25, ..., Z=1
|
||
_REVERSE: dict[str, int] = {chr(i): 91 - i for i in range(65, 91)}
|
||
|
||
# Sumerian: Simple × 6
|
||
_SUMERIAN: dict[str, int] = {c: v * 6 for c, v in _SIMPLE.items()}
|
||
|
||
# Hebrew-mapped: traditional Hebrew gematria mapped to Latin alphabet
|
||
# Aleph=1..Tet=9, Yod=10..Tsade=90, Qoph=100..Tav=400
|
||
# Standard mapping for the 22 Hebrew letters extended to 26 Latin chars
|
||
_HEBREW: dict[str, int] = {
|
||
"A": 1,
|
||
"B": 2,
|
||
"C": 3,
|
||
"D": 4,
|
||
"E": 5,
|
||
"F": 6,
|
||
"G": 7,
|
||
"H": 8,
|
||
"I": 9,
|
||
"J": 10,
|
||
"K": 20,
|
||
"L": 30,
|
||
"M": 40,
|
||
"N": 50,
|
||
"O": 60,
|
||
"P": 70,
|
||
"Q": 80,
|
||
"R": 90,
|
||
"S": 100,
|
||
"T": 200,
|
||
"U": 300,
|
||
"V": 400,
|
||
"W": 500,
|
||
"X": 600,
|
||
"Y": 700,
|
||
"Z": 800,
|
||
}
|
||
|
||
CIPHERS: dict[str, dict[str, int]] = {
|
||
"simple": _SIMPLE,
|
||
"reduction": _REDUCTION,
|
||
"reverse": _REVERSE,
|
||
"sumerian": _SUMERIAN,
|
||
"hebrew": _HEBREW,
|
||
}
|
||
|
||
# ── Notable Numbers ──────────────────────────────────────────────────────────
|
||
|
||
NOTABLE_NUMBERS: dict[int, str] = {
|
||
1: "Unity, the Monad, beginning of all",
|
||
3: "Trinity, divine completeness, the Triad",
|
||
7: "Spiritual perfection, completion (7 days, 7 seals)",
|
||
9: "Finality, judgment, the last single digit",
|
||
11: "Master number — intuition, spiritual insight",
|
||
12: "Divine government (12 tribes, 12 apostles)",
|
||
13: "Rebellion and transformation, the 13th step",
|
||
22: "Master builder — turning dreams into reality",
|
||
26: "YHWH (Yod=10, He=5, Vav=6, He=5)",
|
||
33: "Master teacher — Christ consciousness, 33 vertebrae",
|
||
36: "The number of the righteous (Lamed-Vav Tzadikim)",
|
||
40: "Trial, testing, probation (40 days, 40 years)",
|
||
42: "The answer, and the number of generations to Christ",
|
||
72: "The Shemhamphorasch — 72 names of God",
|
||
88: "Mercury, infinite abundance, double infinity",
|
||
108: "Sacred in Hinduism and Buddhism (108 beads)",
|
||
111: "Angel number — new beginnings, alignment",
|
||
144: "12² — the elect, the sealed (144,000)",
|
||
153: "The miraculous catch of fish (John 21:11)",
|
||
222: "Alexander Whitestone. Balance, partnership, trust the process",
|
||
333: "Ascended masters present, divine protection",
|
||
369: "Tesla's key to the universe",
|
||
444: "Angels surrounding, foundation, stability",
|
||
555: "Major change coming, transformation",
|
||
616: "Earliest manuscript number of the Beast (P115)",
|
||
666: "Number of the Beast (Revelation 13:18), also carbon (6p 6n 6e)",
|
||
777: "Divine perfection tripled, jackpot of the spirit",
|
||
888: "Jesus in Greek isopsephy (Ιησους = 888)",
|
||
1776: "Year of independence, Bavarian Illuminati founding",
|
||
}
|
||
|
||
|
||
# ── Core Functions ───────────────────────────────────────────────────────────
|
||
|
||
|
||
def _clean(text: str) -> str:
|
||
"""Strip non-alpha, uppercase."""
|
||
return "".join(c for c in text.upper() if c.isalpha())
|
||
|
||
|
||
def compute_value(text: str, cipher: str = "simple") -> int:
|
||
"""Compute the gematria value of text in a given cipher.
|
||
|
||
Args:
|
||
text: Any string (non-alpha characters are ignored).
|
||
cipher: One of 'simple', 'reduction', 'reverse', 'sumerian', 'hebrew'.
|
||
|
||
Returns:
|
||
Integer gematria value.
|
||
|
||
Raises:
|
||
ValueError: If cipher name is not recognized.
|
||
"""
|
||
table = CIPHERS.get(cipher)
|
||
if table is None:
|
||
raise ValueError(f"Unknown cipher: {cipher!r}. Use one of {list(CIPHERS)}")
|
||
return sum(table.get(c, 0) for c in _clean(text))
|
||
|
||
|
||
def compute_all(text: str) -> dict[str, int]:
|
||
"""Compute gematria value across all cipher systems.
|
||
|
||
Args:
|
||
text: Any string.
|
||
|
||
Returns:
|
||
Dict mapping cipher name to integer value.
|
||
"""
|
||
return {name: compute_value(text, name) for name in CIPHERS}
|
||
|
||
|
||
def letter_breakdown(text: str, cipher: str = "simple") -> list[tuple[str, int]]:
|
||
"""Return per-letter values for a text in a given cipher.
|
||
|
||
Args:
|
||
text: Any string.
|
||
cipher: Cipher system name.
|
||
|
||
Returns:
|
||
List of (letter, value) tuples for each alpha character.
|
||
"""
|
||
table = CIPHERS.get(cipher)
|
||
if table is None:
|
||
raise ValueError(f"Unknown cipher: {cipher!r}")
|
||
return [(c, table.get(c, 0)) for c in _clean(text)]
|
||
|
||
|
||
def reduce_number(n: int) -> int:
|
||
"""Numerological reduction — sum digits until single digit.
|
||
|
||
Master numbers (11, 22, 33) are preserved.
|
||
|
||
Args:
|
||
n: Any positive integer.
|
||
|
||
Returns:
|
||
Single-digit result (or master number 11/22/33).
|
||
"""
|
||
n = abs(n)
|
||
while n > 9 and n not in (11, 22, 33):
|
||
n = sum(int(d) for d in str(n))
|
||
return n
|
||
|
||
|
||
def factorize(n: int) -> list[int]:
|
||
"""Prime factorization of n.
|
||
|
||
Args:
|
||
n: Positive integer.
|
||
|
||
Returns:
|
||
List of prime factors in ascending order (with repetition).
|
||
"""
|
||
if n < 2:
|
||
return [n] if n > 0 else []
|
||
factors = []
|
||
d = 2
|
||
while d * d <= n:
|
||
while n % d == 0:
|
||
factors.append(d)
|
||
n //= d
|
||
d += 1
|
||
if n > 1:
|
||
factors.append(n)
|
||
return factors
|
||
|
||
|
||
def analyze_number(n: int) -> dict:
|
||
"""Deep analysis of a number — reduction, factors, significance.
|
||
|
||
Args:
|
||
n: Any positive integer.
|
||
|
||
Returns:
|
||
Dict with reduction, factors, properties, and any notable significance.
|
||
"""
|
||
result: dict = {
|
||
"value": n,
|
||
"numerological_reduction": reduce_number(n),
|
||
"prime_factors": factorize(n),
|
||
"is_prime": len(factorize(n)) == 1 and n > 1,
|
||
"is_perfect_square": math.isqrt(n) ** 2 == n if n >= 0 else False,
|
||
"is_triangular": _is_triangular(n),
|
||
"digit_sum": sum(int(d) for d in str(abs(n))),
|
||
}
|
||
|
||
# Master numbers
|
||
if n in (11, 22, 33):
|
||
result["master_number"] = True
|
||
|
||
# Angel numbers (repeating digits)
|
||
s = str(n)
|
||
if len(s) >= 3 and len(set(s)) == 1:
|
||
result["angel_number"] = True
|
||
|
||
# Notable significance
|
||
if n in NOTABLE_NUMBERS:
|
||
result["significance"] = NOTABLE_NUMBERS[n]
|
||
|
||
return result
|
||
|
||
|
||
def _is_triangular(n: int) -> bool:
|
||
"""Check if n is a triangular number (1, 3, 6, 10, 15, ...)."""
|
||
if n < 0:
|
||
return False
|
||
# n = k(k+1)/2 → k² + k - 2n = 0 → k = (-1 + sqrt(1+8n))/2
|
||
discriminant = 1 + 8 * n
|
||
sqrt_d = math.isqrt(discriminant)
|
||
return sqrt_d * sqrt_d == discriminant and (sqrt_d - 1) % 2 == 0
|
||
|
||
|
||
# ── Tool Function (registered with Timmy) ────────────────────────────────────
|
||
|
||
|
||
def gematria(query: str) -> str:
|
||
"""Compute gematria values, analyze numbers, and find correspondences.
|
||
|
||
This is the wizard's language — letters are numbers, numbers are letters.
|
||
Use this tool for ANY gematria calculation. Do not attempt mental arithmetic.
|
||
|
||
Input modes:
|
||
- A word or phrase → computes values across all cipher systems
|
||
- A bare integer → analyzes the number (factors, reduction, significance)
|
||
- "compare: X, Y, Z" → side-by-side gematria comparison
|
||
|
||
Examples:
|
||
gematria("Alexander Whitestone")
|
||
gematria("222")
|
||
gematria("compare: Timmy Time, Alexander Whitestone")
|
||
|
||
Args:
|
||
query: A word/phrase, a number, or a "compare:" instruction.
|
||
|
||
Returns:
|
||
Formatted gematria analysis as a string.
|
||
"""
|
||
query = query.strip()
|
||
|
||
# Mode: compare
|
||
if query.lower().startswith("compare:"):
|
||
phrases = [p.strip() for p in query[8:].split(",") if p.strip()]
|
||
if len(phrases) < 2:
|
||
return "Compare requires at least two phrases separated by commas."
|
||
return _format_comparison(phrases)
|
||
|
||
# Mode: number analysis
|
||
if query.lstrip("-").isdigit():
|
||
n = int(query)
|
||
return _format_number_analysis(n)
|
||
|
||
# Mode: phrase gematria
|
||
if not _clean(query):
|
||
return "No alphabetic characters found in input."
|
||
|
||
return _format_phrase_analysis(query)
|
||
|
||
|
||
def _format_phrase_analysis(text: str) -> str:
|
||
"""Format full gematria analysis for a phrase."""
|
||
values = compute_all(text)
|
||
lines = [f'Gematria of "{text}":', ""]
|
||
|
||
# All cipher values
|
||
for cipher, val in values.items():
|
||
label = cipher.replace("_", " ").title()
|
||
lines.append(f" {label:12s} = {val}")
|
||
|
||
# Letter breakdown (simple)
|
||
breakdown = letter_breakdown(text, "simple")
|
||
letters_str = " + ".join(f"{c}({v})" for c, v in breakdown)
|
||
lines.append(f"\n Breakdown (Simple): {letters_str}")
|
||
|
||
# Numerological reduction of the simple value
|
||
simple_val = values["simple"]
|
||
reduced = reduce_number(simple_val)
|
||
lines.append(f" Numerological root: {simple_val} → {reduced}")
|
||
|
||
# Check notable
|
||
for cipher, val in values.items():
|
||
if val in NOTABLE_NUMBERS:
|
||
label = cipher.replace("_", " ").title()
|
||
lines.append(f"\n ★ {val} ({label}): {NOTABLE_NUMBERS[val]}")
|
||
|
||
return "\n".join(lines)
|
||
|
||
|
||
def _format_number_analysis(n: int) -> str:
|
||
"""Format deep number analysis."""
|
||
info = analyze_number(n)
|
||
lines = [f"Analysis of {n}:", ""]
|
||
lines.append(f" Numerological reduction: {n} → {info['numerological_reduction']}")
|
||
lines.append(f" Prime factors: {' × '.join(str(f) for f in info['prime_factors']) or 'N/A'}")
|
||
lines.append(f" Is prime: {info['is_prime']}")
|
||
lines.append(f" Is perfect square: {info['is_perfect_square']}")
|
||
lines.append(f" Is triangular: {info['is_triangular']}")
|
||
lines.append(f" Digit sum: {info['digit_sum']}")
|
||
|
||
if info.get("master_number"):
|
||
lines.append(" ★ Master Number")
|
||
if info.get("angel_number"):
|
||
lines.append(" ★ Angel Number (repeating digits)")
|
||
if info.get("significance"):
|
||
lines.append(f"\n Significance: {info['significance']}")
|
||
|
||
return "\n".join(lines)
|
||
|
||
|
||
def _format_comparison(phrases: list[str]) -> str:
|
||
"""Format side-by-side gematria comparison."""
|
||
lines = ["Gematria Comparison:", ""]
|
||
|
||
# Header
|
||
max_name = max(len(p) for p in phrases)
|
||
header = f" {'Phrase':<{max_name}s} Simple Reduct Reverse Sumerian Hebrew"
|
||
lines.append(header)
|
||
lines.append(" " + "─" * (len(header) - 2))
|
||
|
||
all_values = {}
|
||
for phrase in phrases:
|
||
vals = compute_all(phrase)
|
||
all_values[phrase] = vals
|
||
lines.append(
|
||
f" {phrase:<{max_name}s} {vals['simple']:>6d} {vals['reduction']:>6d}"
|
||
f" {vals['reverse']:>7d} {vals['sumerian']:>8d} {vals['hebrew']:>6d}"
|
||
)
|
||
|
||
# Find matches (shared values across any cipher)
|
||
matches = []
|
||
for cipher in CIPHERS:
|
||
vals_by_cipher = {p: all_values[p][cipher] for p in phrases}
|
||
unique_vals = set(vals_by_cipher.values())
|
||
if len(unique_vals) < len(phrases):
|
||
# At least two phrases share a value
|
||
for v in unique_vals:
|
||
sharing = [p for p, pv in vals_by_cipher.items() if pv == v]
|
||
if len(sharing) > 1:
|
||
label = cipher.title()
|
||
matches.append(f" ★ {label} = {v}: " + ", ".join(sharing))
|
||
|
||
if matches:
|
||
lines.append("\nCorrespondences found:")
|
||
lines.extend(matches)
|
||
|
||
return "\n".join(lines)
|