Squashed 'utils_v2/' content from commit aa76ceb

git-subtree-dir: utils_v2
git-subtree-split: aa76ceb7480020f473af5cdb44891d3ebcfc8373
This commit is contained in:
2024-12-05 10:29:29 +05:30
commit 24f5bc60dc
143 changed files with 125300 additions and 0 deletions
+168
View File
@@ -0,0 +1,168 @@
"""
AUTHOR:
Khushal P Soonderji
DATE:
Saturday, 18th May, 2024
OBJECTIVE:
To provide a quick set of functions to work with fuzzy logic.
REFERENCES:
1) https://www.w3schools.com/python/python_json.asp
DOWNLOADS:
N/A
"""
# *****************************************************************************************************************
# ***** ****
# *** IMPORT ***
# ***** ****
# *****************************************************************************************************************
# To make sibling directories accessible for imports:
import sys
sys.path.append(".")
sys.path.append("..")
# To apply fuzzy logic:
from thefuzz import fuzz, process
# To work with tabulated data:
import pandas as pd
# *****************************************************************************************************************
# ***** ****
# *** MACROS / ONE-TIME INIT ***
# ***** ****
# *****************************************************************************************************************
# --- Nothing Yet
# *****************************************************************************************************************
# ***** ****
# *** VARIABLES ***
# ***** ****
# *****************************************************************************************************************
# --- Nothing Yet
# *****************************************************************************************************************
# ***** ****
# *** FUNCTIONS ***
# ***** ****
# *****************************************************************************************************************
def get_best_match(
target,
choices,
threshold = 0.70,
partial = False
):
if partial: scorer = fuzz.partial_token_sort_ratio
else: scorer = fuzz.ratio
result = process.extractOne(
target,
choices,
score_cutoff = threshold * 100,
scorer = scorer
)
try: return result[0]
except: return None
# ---------------------------------------------------------------------------------------------------------------------
def rank(target, choices, partial = True):
if partial: scorer = fuzz.partial_token_sort_ratio
else: scorer = fuzz.ratio
result = process.extract(
target,
choices,
limit = len(choices),
scorer = scorer
)
result = pd.DataFrame(result, columns = ["choice", "closeness"])
result["closeness"] = result["closeness"] / 100.0
return result
# ---------------------------------------------------------------------------------------------------------------------
def match(targets, choices, threshold = 0.7, partial = False, allow_null = False):
all_matches_df = None
all_matches = {target: None for target in targets}
something_is_null = False
for target in targets:
match_df = rank(target, choices, partial = partial)
match_df["target"] = target
if all_matches_df is None: all_matches_df = match_df
else: all_matches_df = pd.concat([all_matches_df, match_df])
all_matches_df = all_matches_df.sort_values(by = ["closeness"], ascending = False).reset_index(drop = True)
for target in targets:
target_df = all_matches_df[all_matches_df["target"] == target].reset_index(drop = True)
if target_df.empty: continue
if target_df.at[0, "closeness"] >= threshold:
choice = target_df.at[0, "choice"]
all_matches[target] = choice
all_matches_df = all_matches_df[all_matches_df["choice"] != choice]
else:
all_matches[target] = None
something_is_null = True
# print(all_matches)
if something_is_null and not allow_null: return None
else: return all_matches
# *****************************************************************************************************************
# ***** ****
# *** MAIN PROGRAM ***
# ***** ****
# *****************************************************************************************************************
if __name__ == "__main__":
import async_json_utils
awb_numbers = [
"SF1111BIC",
"SF2222BIC",
"SF3333BIC",
"SF4444BIC",
]
chat_text = "SF1112BIC"
# print(chat_text == names[0])
best_match = get_best_match(chat_text, awb_numbers, threshold = 0.60, partial = False)
print(f"Best match for '{chat_text}' is '{best_match}'")