jeysshon commited on
Commit
240c3a6
·
verified ·
1 Parent(s): b4ae22d

Create pdf_processor.py

Browse files
Files changed (1) hide show
  1. pdf_processor.py +105 -0
pdf_processor.py ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import fitz
2
+ from tqdm.auto import tqdm
3
+ from spacy.lang.en import English
4
+
5
+ def text_formatter(text: str) -> str:
6
+ """
7
+ Formatea el texto extraído de un PDF eliminando saltos de línea
8
+ y espacios sobrantes.
9
+ """
10
+ return text.replace("\n", " ").strip()
11
+
12
+ def read_pdf(pdf_bytes: bytes) -> list[dict]:
13
+ """
14
+ Lee un archivo PDF a partir de sus bytes y extrae información de cada página:
15
+ - Número de página
16
+ - Conteo de caracteres
17
+ - Conteo de palabras
18
+ - Conteo aproximado de oraciones (separadas por '. ')
19
+ - Conteo de tokens aproximado (asumiendo 1 token ~ 4 caracteres)
20
+ - Texto completo de la página
21
+
22
+ Parámetros:
23
+ -----------
24
+ pdf_bytes : bytes
25
+ Contenido binario de un PDF.
26
+
27
+ Retorna:
28
+ --------
29
+ list[dict]
30
+ Lista de diccionarios con la información de cada página.
31
+ """
32
+ doc = fitz.open(stream=pdf_bytes, filetype="pdf")
33
+ pages_and_text = []
34
+ for page_number, page in tqdm(enumerate(doc), desc="Leyendo PDF"):
35
+ text = page.get_text()
36
+ text = text_formatter(text=text)
37
+ pages_and_text.append(
38
+ {
39
+ "page_number": page_number + 1,
40
+ "page_char_count": len(text),
41
+ "page_word_count": len(text.split(" ")),
42
+ "page_sentence_count_raw": len(text.split(". ")),
43
+ "page_token_count": len(text) / 4, # Estimación aproximada
44
+ "text": text,
45
+ }
46
+ )
47
+ return pages_and_text
48
+
49
+ def process_chunks(pages_and_text: list[dict]) -> list[dict]:
50
+ """
51
+ Procesa cada página para dividir el texto en oraciones y luego agrupar
52
+ esas oraciones en 'chunks' de 10 oraciones cada uno.
53
+
54
+ Parámetros:
55
+ -----------
56
+ pages_and_text : list[dict]
57
+ Lista de diccionarios que contienen el texto y metadatos de cada página.
58
+
59
+ Retorna:
60
+ --------
61
+ list[dict]
62
+ Lista de diccionarios donde cada diccionario representa un chunk de oraciones.
63
+ """
64
+ nlp = English()
65
+ nlp.add_pipe("sentencizer")
66
+
67
+ # Dividir el texto en oraciones
68
+ for item in tqdm(pages_and_text, desc="Dividiendo en oraciones"):
69
+ item["sentences"] = [str(sent) for sent in nlp(item["text"]).sents]
70
+ item["sentence_chunks"] = split_list(item["sentences"], 10)
71
+ item["num_of_chunks"] = len(item["sentence_chunks"])
72
+
73
+ # Crear una lista de todos los chunks
74
+ pages_and_chunks = []
75
+ for item in tqdm(pages_and_text, desc="Creando 'chunks'"):
76
+ for sentence_chunk in item["sentence_chunks"]:
77
+ chunk_dict = {
78
+ "page_number": item["page_number"],
79
+ "sentence_chunk": " ".join(sentence_chunk).strip(),
80
+ "chunk_word_count": sum(len(sentence.split()) for sentence in sentence_chunk),
81
+ "chunk_token_count": sum(len(sentence) for sentence in sentence_chunk) / 4,
82
+ }
83
+ pages_and_chunks.append(chunk_dict)
84
+
85
+ return pages_and_chunks
86
+
87
+ def split_list(input_list: list[str], slice_size: int) -> list[list[str]]:
88
+ """
89
+ Divide una lista en sublistas de tamaño determinado.
90
+
91
+ Parámetros:
92
+ -----------
93
+ input_list : list[str]
94
+ Lista original que se desea dividir.
95
+ slice_size : int
96
+ Tamaño de cada sublista.
97
+
98
+ Retorna:
99
+ --------
100
+ list[list[str]]
101
+ Lista de sublistas, cada una con una longitud máxima de 'slice_size'.
102
+ """
103
+ return [
104
+ input_list[i : i + slice_size] for i in range(0, len(input_list), slice_size)
105
+ ]