Spaces:
Sleeping
Sleeping
Create app.py
Browse files
app.py
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
import json
|
| 3 |
+
from rapidfuzz import process, fuzz
|
| 4 |
+
|
| 5 |
+
# --- CONFIGURATION ---
|
| 6 |
+
DATA_FILE = "navy_acronyms_clean.json"
|
| 7 |
+
|
| 8 |
+
# --- PAGE SETUP ---
|
| 9 |
+
st.set_page_config(page_title="Navy Acronym Finder", page_icon="⚓")
|
| 10 |
+
|
| 11 |
+
st.title("EDQP Acronym Lookup")
|
| 12 |
+
st.markdown("Type an acronym below to find its definition. Uses fuzzy matching to handle typos.")
|
| 13 |
+
|
| 14 |
+
# --- LOAD DATA ---
|
| 15 |
+
@st.cache_data
|
| 16 |
+
def load_acronyms():
|
| 17 |
+
try:
|
| 18 |
+
with open(DATA_FILE, 'r', encoding='utf-8') as f:
|
| 19 |
+
return json.load(f)
|
| 20 |
+
except FileNotFoundError:
|
| 21 |
+
return {"ERROR": "navy_acronyms_clean.json not found!"}
|
| 22 |
+
|
| 23 |
+
acronym_dict = load_acronyms()
|
| 24 |
+
acronym_keys = list(acronym_dict.keys())
|
| 25 |
+
|
| 26 |
+
# --- SEARCH BAR ---
|
| 27 |
+
query = st.text_input("Enter Acronym:", placeholder="e.g., ACAT, MDA, ASW...", max_chars=10)
|
| 28 |
+
|
| 29 |
+
# --- RESULTS ---
|
| 30 |
+
if query:
|
| 31 |
+
query = query.upper().strip()
|
| 32 |
+
|
| 33 |
+
# 1. Exact Match (The "Right" Answer)
|
| 34 |
+
if query in acronym_dict:
|
| 35 |
+
st.success(f"**{query}**")
|
| 36 |
+
st.markdown(f"### {acronym_dict[query]}")
|
| 37 |
+
st.divider()
|
| 38 |
+
|
| 39 |
+
# 2. Fuzzy / Top 5 Suggestions
|
| 40 |
+
st.markdown("#### Did you mean?")
|
| 41 |
+
|
| 42 |
+
# Extracts top 5 similar keys based on the user query
|
| 43 |
+
# scorer=fuzz.ratio gives a simple similarity score
|
| 44 |
+
matches = process.extract(query, acronym_keys, limit=5, scorer=fuzz.ratio)
|
| 45 |
+
|
| 46 |
+
for match_tuple in matches:
|
| 47 |
+
# Tuple format: (matched_string, score, index)
|
| 48 |
+
candidate = match_tuple[0]
|
| 49 |
+
score = match_tuple[1]
|
| 50 |
+
|
| 51 |
+
# Don't show the exact match again if we already showed the big green box
|
| 52 |
+
if candidate == query:
|
| 53 |
+
continue
|
| 54 |
+
|
| 55 |
+
# Only show relevant matches (score > 40)
|
| 56 |
+
if score > 40:
|
| 57 |
+
with st.expander(f"**{candidate}** (Match: {int(score)}%)"):
|
| 58 |
+
st.write(acronym_dict[candidate])
|
| 59 |
+
|
| 60 |
+
# --- SIDEBAR (Database Stats) ---
|
| 61 |
+
with st.sidebar:
|
| 62 |
+
st.header("Database Info")
|
| 63 |
+
st.metric("Total Acronyms", len(acronym_dict))
|
| 64 |
+
|
| 65 |
+
st.divider()
|
| 66 |
+
|
| 67 |
+
# Option to view raw list
|
| 68 |
+
if st.checkbox("Show Full List"):
|
| 69 |
+
st.dataframe(acronym_dict, use_container_width=True)
|