Files
doczyai-pipelines/textract-pipeline/src/lambda/prompt-orchestrator/preprocess.py
T
Michael McGuinness 037909db74 format codebase
2024-09-30 12:21:29 +01:00

166 lines
6.8 KiB
Python

from itertools import groupby, count
import re
def clean_newlines(contract_text):
"""
Cleans up isolated newlines in a contract text, converting them into spaces to ensure text continuity.
This function uses a regular expression to identify standalone newlines (those not part of a paragraph break, which
typically consists of consecutive newlines) and replaces them with a single space. This process helps in preserving
the flow of text and making it more readable and processable, particularly for text extraction and analysis tasks that
might be sensitive to abrupt breaks in the text.
Parameters:
contract_text (str): The text of the contract that may contain sporadic newlines.
Returns:
str: The cleaned contract text with isolated newlines replaced by spaces.
"""
cleaned_text = re.sub(r"(?<!\n)\n(?!\n)", " ", contract_text)
return cleaned_text
def split_text(text):
"""
Splits a contract text into a dictionary of pages based on a specific delimiter indicating the start of a page.
This function uses the delimiter 'Start of Page No. = ' to segment the input text into different pages.
Each page is stored in a dictionary where the key is the page number (extracted as the first word after the delimiter)
and the value is the corresponding page text. This facilitates easier access and processing of individual pages in the contract.
Parameters:
text (str): The contract text containing multiple pages separated by the delimiter.
Returns:
dict: A dictionary with page numbers as keys and the respective page texts as values.
"""
text_list = text.split("Start of Page No. = ")
text_dict = {page.split()[0]: page for page in text_list}
return text_dict
def highlight_rates(text_dict):
"""
Highlights rate-related terms (percentages and dollar amounts) in the text of each page within a dictionary.
This function processes each page's text in the provided dictionary, identifying words that contain percentage signs ('%')
or dollar signs ('$'). It wraps these words with '>>>' and '<<<' to highlight them. The modified text for each page
is then updated in the dictionary, allowing for easier identification and processing of rate-related terms in subsequent analyses.
Parameters:
text_dict (dict): A dictionary where keys are page numbers and values are the text content of those pages.
Returns:
dict: The updated dictionary with rate-related terms highlighted in the text of each page.
"""
for page, text in text_dict.items():
words = text.split()
highlighted_words = []
for word in words:
if "%" in word or "$" in word:
word = f">>>{word}<<<"
highlighted_words.append(word)
text_dict[page] = " ".join(highlighted_words)
return text_dict
def chunk_text(text_dict):
"""
Creates text chunks from a dictionary of page texts, focusing on pages with special characters (percentages and dollar amounts).
This function identifies pages that contain '%' or '$' signs and includes those pages along with their immediate neighbors
(previous and next pages) to form chunks. The chunks are then grouped and concatenated into single text blocks for easier
processing. Each chunk is stored in a new dictionary where the keys represent the range of pages included in the chunk.
Parameters:
text_dict (dict): A dictionary where keys are page numbers (as strings) and values are the text content of those pages.
Returns:
dict: A new dictionary where each key is a string representing the range of pages in a chunk, and each value is the concatenated text of those pages.
"""
special_pages = {
int(page): text
for page, text in text_dict.items()
if (("%" in text) or ("$" in text) or ("percent" in text))
}
page_numbers = sorted(special_pages.keys())
chunk_page_numbers = []
for page in page_numbers:
chunk_page_numbers.append(page - 1)
chunk_page_numbers.append(page)
chunk_page_numbers.append(page + 1)
chunk_page_numbers = list(set(chunk_page_numbers))
chunk_page_numbers = [
page for page in chunk_page_numbers if str(page) in text_dict.keys()
]
chunks = [
list(group)
for key, group in groupby(chunk_page_numbers, lambda x, c=count(): x - next(c))
]
chunk_dict = {}
for item in chunks:
dict_key = f"{min(item)}-{max(item)}"
text = "".join([text_dict[str(page)] for page in item])
chunk_dict[dict_key] = text
return chunk_dict
def clean_billed_charges(contract_text):
"""
Cleans occurrences of 'billed charges' in a text by replacing them with '100% of billed charges' unless preceded by a percentage.
This function uses a regular expression to find all instances of the phrase 'billed charges'. For each match, it checks the preceding
text (up to 15 characters before the match) for a percentage sign ('%'). If a percentage is found, it leaves the match unchanged.
Otherwise, it replaces 'billed charges' with '100% of billed charges'.
Parameters:
text (str): The input text to be cleaned.
Returns:
str: The cleaned text with appropriate replacements made for 'billed charges'.
"""
substrings = [
"Physician's Billed Charges",
"Provider's Billed Charges",
"Allowable Billed Charges",
"Hospital's Billed Charges",
"Physician's Charges",
"Provider's Charges",
"Allowable Charges",
"Hospital's Charges",
"Billed Charges",
"the rates set forth in this Exhibit",
"the rutes set forth in this Exhibit",
]
max_substring_length = max([len(s) for s in substrings])
def find_substring_indices(contract_text, s):
indices = []
lower_contract_text = contract_text.lower()
lower_s = s.lower()
index = lower_contract_text.find(lower_s)
while index != -1:
indices.append(index)
index = lower_contract_text.find(lower_s, index + 1)
return indices
for s in substrings:
indices = find_substring_indices(contract_text, s)
index_adder = 0
if indices:
for i in indices:
index = i + index_adder
end_index = index + max_substring_length
match_part = contract_text[index:end_index]
previous = contract_text[max(0, index - 30) : index]
if "%" not in previous:
contract_text = (
contract_text[0:index]
+ f" 100% of {match_part}"
+ contract_text[end_index:]
)
index_adder += 9
return contract_text.replace(" ", " ")