pattonma
Added PDF reader and changed text splitter
1318cbe
raw
history blame
5.18 kB
import os
from typing import List
from PyPDF2 import PdfReader
import re
class TextFileLoader:
def __init__(self, path: str, encoding: str = "utf-8"):
self.documents = []
self.path = path
self.encoding = encoding
def load(self):
if os.path.isdir(self.path):
self.load_directory()
elif os.path.isfile(self.path) and self.path.endswith(".txt"):
self.load_file()
else:
raise ValueError(
"Provided path is neither a valid directory nor a .txt file."
)
def load_file(self):
with open(self.path, "r", encoding=self.encoding) as f:
self.documents.append(f.read())
def load_directory(self):
for root, _, files in os.walk(self.path):
for file in files:
if file.endswith(".txt"):
with open(
os.path.join(root, file), "r", encoding=self.encoding
) as f:
self.documents.append(f.read())
def load_documents(self):
self.load()
return self.documents
class CharacterTextSplitter:
def __init__(
self,
chunk_size: int = 1000,
chunk_overlap: int = 200,
):
assert (
chunk_size > chunk_overlap
), "Chunk size must be greater than chunk overlap"
self.chunk_size = chunk_size
self.chunk_overlap = chunk_overlap
def split(self, text: str) -> List[str]:
chunks = []
for i in range(0, len(text), self.chunk_size - self.chunk_overlap):
chunks.append(text[i : i + self.chunk_size])
return chunks
def split_texts(self, texts: List[str]) -> List[str]:
chunks = []
for text in texts:
chunks.extend(self.split(text))
return chunks
class PDFLoader:
def __init__(self, path: str):
self.documents = []
self.path = path
def load(self):
if os.path.isdir(self.path):
self.load_directory()
elif os.path.isfile(self.path) and self.path.endswith(".pdf"):
self.load_file()
else:
raise ValueError("Provided path is neither a valid directory nor a .pdf file.")
def load_file(self):
with open(self.path, 'rb') as file:
pdf_reader = PdfReader(file)
text = ""
for page in pdf_reader.pages:
text += page.extract_text()
self.documents.append(text)
def load_directory(self):
for root, _, files in os.walk(self.path):
for file in files:
if file.endswith(".pdf"):
file_path = os.path.join(root, file)
with open(file_path, 'rb') as f:
pdf_reader = PdfReader(f)
text = ""
for page in pdf_reader.pages:
text += page.extract_text()
self.documents.append(text)
def load_documents(self) -> List[str]:
self.load()
return self.documents
class SentenceTextSplitter:
def __init__(
self,
chunk_size: int = 1000,
chunk_overlap: int = 200,
separator: str = "\n"
):
self.chunk_size = chunk_size
self.chunk_overlap = chunk_overlap
self.separator = separator
def split(self, text: str) -> List[str]:
# Split the text into sentences
sentences = re.split(r'(?<=[.!?])\s+', text)
chunks = []
current_chunk = []
current_size = 0
for sentence in sentences:
sentence_size = len(sentence)
if current_size + sentence_size > self.chunk_size and current_chunk:
# If adding this sentence would exceed the chunk size, store the current chunk
chunks.append(self.separator.join(current_chunk))
# Start a new chunk, keeping some overlap
overlap_size = 0
while overlap_size < self.chunk_overlap and current_chunk:
overlap_sentence = current_chunk.pop(0)
overlap_size += len(overlap_sentence)
current_chunk = [overlap_sentence] if overlap_size < self.chunk_overlap else []
current_size = overlap_size
current_chunk.append(sentence)
current_size += sentence_size
# Add the last chunk if it's not empty
if current_chunk:
chunks.append(self.separator.join(current_chunk))
return chunks
def split_texts(self, texts: List[str]) -> List[str]:
chunks = []
for text in texts:
chunks.extend(self.split(text))
return chunks
if __name__ == "__main__":
loader = TextFileLoader("data/KingLear.txt")
loader.load()
splitter = CharacterTextSplitter()
chunks = splitter.split_texts(loader.documents)
print(len(chunks))
print(chunks[0])
print("--------")
print(chunks[1])
print("--------")
print(chunks[-2])
print("--------")
print(chunks[-1])