File size: 6,289 Bytes
769668f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import logging
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.DEBUG) # Set to DEBUG for detailed output

import gradio as gr
from gradio_calendar import Calendar
from gematria import calculate_gematria, strip_diacritics
from datetime import datetime, timedelta
import json
import inflect

# --- Helper Functions ---
def calculate_gematria_sum(text):
    if text:
        text_gematria = calculate_gematria(strip_diacritics(text))
        return text_gematria
    else:
        return None

# Custom function to convert number to ordinal words
def number_to_ordinal_word(number):
    ordinal_dict = {
        1: "first", 2: "second", 3: "third", 4: "fourth", 5: "fifth",
        6: "sixth", 7: "seventh", 8: "eighth", 9: "ninth", 10: "tenth",
        11: "eleventh", 12: "twelfth", 13: "thirteenth", 14: "fourteenth",
        15: "fifteenth", 16: "sixteenth", 17: "seventeenth", 18: "eighteenth",
        19: "nineteenth", 20: "twentieth", 21: "twentyfirst", 22: "twentysecond",
        23: "twentythird", 24: "twentyfourth", 25: "twentyfifth",
        26: "twentysixth", 27: "twentyseventh", 28: "twentyeighth",
        29: "twentyninth", 30: "thirtieth", 31: "thirtyfirst"
    }
    return ordinal_dict.get(number, "")

def date_to_words(date_string):
    """Converts a date in YYYY-MM-DD format to English words."""
    inf_engine = inflect.engine()
    date_obj = datetime.strptime(date_string, "%Y-%m-%d")

    year = date_obj.year
    if 1100 <= year <= 1999:
        year_words = f"{inf_engine.number_to_words(year // 100, andword='') } hundred"
        if year % 100 != 0:
            year_words += f" {inf_engine.number_to_words(year % 100, andword='')}"
    else:
        year_words = inf_engine.number_to_words(year, andword='')
    year_formatted = year_words.replace(',', '')

    month = date_obj.strftime("%B")
    day = date_obj.day
    day_ordinal = number_to_ordinal_word(day)

    output_text = f"{day_ordinal} {month} {year_formatted}"
    return output_text

def perform_gematria_calculation_for_date_range(start_date, end_date):
    logger.debug(f"Calculating date gematria for range: {start_date} - {end_date}")
    results = {}
    delta = timedelta(days=1)
    current_date = start_date

    while current_date <= end_date:
        date_string = current_date.strftime("%Y-%m-%d")
        date_words = date_to_words(date_string)
        date_gematria = calculate_gematria_sum(date_words)

        results[date_string] = {
            "date_words": date_words,
            "date_gematria": date_gematria,
        }
        current_date += delta
    logger.debug(f"Finished calculating date gematria.")
    return results


def find_matching_dates(date_gematrias, names, search_journal_sum):
    logger.debug(f"Searching for matches with journal sum: {search_journal_sum}")
    matching_dates = {}

    for name in names:
        name_gematria = calculate_gematria_sum(name)
        target_date_gematria = search_journal_sum - name_gematria if name_gematria is not None else None
        logger.debug(f"Name: {name}, Gematria: {name_gematria}, Target Date Gematria: {target_date_gematria}")

        if target_date_gematria is not None:
            for date_str, date_data in date_gematrias.items():
                if date_data["date_gematria"] == target_date_gematria:
                    if name not in matching_dates:
                        matching_dates[name] = []
                    matching_dates[name].append(date_str)
        logger.debug(f"Matches for {name}: {matching_dates.get(name, [])}")
    return matching_dates


def find_shared_gematria_dates(date_gematrias, names):
    """Finds dates where names share the same journal sum."""
    logger.debug("Calculating shared gematria dates...")
    shared_dates = {}
    name_gematrias = {}

    for name in names:
        name_gematrias[name] = calculate_gematria_sum(name)

    for date_str, date_data in date_gematrias.items():
        date_gematria = date_data["date_gematria"]
        for name1 in names:
            for name2 in names:
                if name1 != name2:
                    journal_sum1 = date_gematria + name_gematrias[name1]
                    journal_sum2 = date_gematria + name_gematrias[name2]

                    if journal_sum1 == journal_sum2:
                        key = tuple(sorted((name1, name2))) # Create a consistent key regardless of name order
                        if key not in shared_dates:
                            shared_dates[key] = []
                        shared_dates[key].append(date_str)

    logger.debug(f"Shared Gematria Dates: {shared_dates}")  # Log the shared dates
    return shared_dates

def calculate_and_find(start_date, end_date, names_input, search_journal_sum):
    names = [n.strip() for n in names_input.split("\n") if n.strip()]
    date_gematrias = perform_gematria_calculation_for_date_range(start_date, end_date)
    matching_dates = find_matching_dates(date_gematrias, names, int(search_journal_sum))
    shared_gematria_dates = find_shared_gematria_dates(date_gematrias, names)

    return (
        json.dumps(matching_dates, indent=4, ensure_ascii=False),
        json.dumps(date_gematrias, indent=4, ensure_ascii=False),  # Keep this for debugging if needed
        json.dumps(shared_gematria_dates, indent=4, ensure_ascii=False)
    )


# --- Main Gradio App ---
with gr.Blocks() as app:
    with gr.Row():
        start_date = Calendar(type="datetime", label="Start Date")
        end_date = Calendar(type="datetime", label="End Date")
    with gr.Row():
        names_input = gr.Textbox(label="Names (one per line)", lines=5) # Multiline input
        search_sum = gr.Number(label="Search Journal Sum", precision=0)

    calculate_btn = gr.Button("Calculate")
    with gr.Row():
        matching_dates_output = gr.JSON(label="Matching Dates")
        shared_dates_output = gr.JSON(label="Shared Gematria Dates") # New output component
        json_output = gr.JSON(label="Complete Results (for debugging)")


    calculate_btn.click(
        calculate_and_find,
        inputs=[start_date, end_date, names_input, search_sum],
        outputs=[matching_dates_output, json_output, shared_dates_output]  # Added shared_dates_output
    )

if __name__ == "__main__":
    app.launch(share=False)