simple-icd-10-cm 1.2.0__py3-none-any.whl → 1.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,8 @@
1
+ # simple_icd_10_cm is released under the MIT License
2
+ # Copyright (c) 2021-2025 Stefano Travasci
3
+ # Read the full LICENCES at https://github.com/StefanoTrv/simple_icd_10_cm/blob/master/LICENSE
4
+
5
+ from typing import Optional
1
6
  import xml.etree.ElementTree as ET
2
7
 
3
8
  try:
@@ -8,15 +13,18 @@ except ImportError:
8
13
 
9
14
  from . import data # relative-import the "package" containing the data
10
15
 
11
- chapter_list: list["_CodeTree"] = []
16
+ _chapter_list: list["_CodeTree"] = []
17
+
18
+ _code_to_node: dict[str, "_CodeTree"] = {}
12
19
 
13
- code_to_node: dict[str, "_CodeTree"] = {}
20
+ _all_codes_list: list[str] = []
14
21
 
15
- all_codes_list: list[str] = []
22
+ _all_codes_list_no_dots: list[str] = []
16
23
 
17
- all_codes_list_no_dots: list[str] = []
24
+ _code_to_index_dictionary: dict[str, int] = {}
18
25
 
19
- code_to_index_dictionary: dict[str, int] = {}
26
+ _all_codes_package_file_name:str = 'code-list-April-2025.txt'
27
+ _classification_data_package_file_name:str = 'icd10cm-tabular-April-2025.xml'
20
28
 
21
29
  class _CodeTree:
22
30
  def __init__(self, tree, parent = None, seven_chr_def_ancestor = None, seven_chr_note_ancestor = None, use_additional_code_ancestor = None, code_first_ancestor = None):
@@ -105,15 +113,15 @@ class _CodeTree:
105
113
  self.type="subcategory"
106
114
 
107
115
  #adds the new node to the dictionary
108
- if self.name not in code_to_node:#in case a section has the same name of a code (ex B99)
109
- code_to_node[self.name]=self
116
+ if self.name not in _code_to_node:#in case a section has the same name of a code (ex B99)
117
+ _code_to_node[self.name]=self
110
118
 
111
119
  #if this code is a leaf, it adds to its children the codes created by adding the seventh character
112
120
  if len(self.children)==0 and (self.seven_chr_def!={} or self.seven_chr_def_ancestor!=None) and self.type!="extended subcategory":
113
121
  if self.seven_chr_def!={}:
114
122
  dictionary = self.seven_chr_def
115
123
  else:
116
- dictionary = self.seven_chr_def_ancestor.seven_chr_def
124
+ dictionary = self.seven_chr_def_ancestor.seven_chr_def # type: ignore[reportOptionalMemberAccess]
117
125
  extended_name=self.name
118
126
  if len(extended_name)==3:
119
127
  extended_name=extended_name+"."
@@ -124,128 +132,154 @@ class _CodeTree:
124
132
  new_XML = "<diag_ext><name>"+extended_name+extension+"</name><desc>"+self.description+", "+dictionary[extension]+"</desc></diag_ext>"
125
133
  self.children.append(_CodeTree(ET.fromstring(new_XML),parent=self,seven_chr_def_ancestor=new_seven_chr_def_ancestor,seven_chr_note_ancestor=new_seven_chr_note_ancestor,use_additional_code_ancestor=new_use_additional_code_ancestor,code_first_ancestor=new_code_first_ancestor))
126
134
 
127
- def _load_codes():
135
+ def _load_codes(all_codes_file_path:Optional[str] = None, classification_data_file_path:Optional[str] = None) -> None: # either both or none of the strings must be None
128
136
  #loads the list of all codes, to remove later from the tree the ones that do not exist for very specific rules not easily extracted from the XML file
129
- f = pkg_resources.read_text(data, 'icd10cm-order-Jan-2021.txt')
137
+ if all_codes_file_path is None:
138
+ assert classification_data_file_path is None
139
+ text = pkg_resources.read_text(data, _all_codes_package_file_name)
140
+ else:
141
+ assert classification_data_file_path is not None
142
+ with open(all_codes_file_path, encoding="utf-8") as f:
143
+ text = f.read()
130
144
  global all_confirmed_codes
131
145
  all_confirmed_codes = set()
132
- lines=f.split("\n")
146
+ lines=text.split("\n")
133
147
  for line in lines:
134
- all_confirmed_codes.add(line[6:13].strip())
148
+ all_confirmed_codes.add(line.split(" ")[0].replace(".",""))
135
149
 
136
150
  #creates the tree
137
- root = ET.fromstring(pkg_resources.read_text(data, 'icd10cm_tabular_2021.xml'))
151
+ if classification_data_file_path is None:
152
+ root = ET.fromstring(pkg_resources.read_text(data, _classification_data_package_file_name))
153
+ else:
154
+ with open(classification_data_file_path, encoding="utf-8") as f:
155
+ text = f.read()
156
+ root = ET.fromstring(text)
138
157
  root.remove(root[0])
139
158
  root.remove(root[0])
159
+ if len(_chapter_list)>0: #empties data structures only if needed and if the files have been read with no error
160
+ _chapter_list.clear()
161
+ _code_to_node.clear()
162
+ _all_codes_list.clear()
163
+ _all_codes_list_no_dots.clear()
164
+ _code_to_index_dictionary.clear()
140
165
  for child in root:
141
- chapter_list.append(_CodeTree(child))
166
+ _chapter_list.append(_CodeTree(child))
142
167
 
143
168
  del all_confirmed_codes #deletes this list since it won't be needed anymore
144
169
 
145
170
 
146
171
  _load_codes()
147
172
 
148
- def _add_dot_to_code(code):
173
+ def change_version(all_codes_file_path:Optional[str] = None, classification_data_file_path:Optional[str] = None) -> None:
174
+ if (all_codes_file_path is None and classification_data_file_path is None) or (all_codes_file_path is not None and classification_data_file_path is not None):
175
+ _load_codes(all_codes_file_path=all_codes_file_path,classification_data_file_path=classification_data_file_path)
176
+ else:
177
+ ac_error = "None" if all_codes_file_path is None else "\"" + all_codes_file_path + "\""
178
+ cd_error = "None" if classification_data_file_path is None else "\"" + classification_data_file_path + "\""
179
+ raise ValueError("Either both paths must be provided, or none.\nProvided values were:\n\t-all_codes_file_path is "+ac_error+"\n\t-classification_data_file_path is "+cd_error+"\n")
180
+
181
+ def _add_dot_to_code(code:str) -> str:
149
182
  if len(code)<4 or code[3]==".":
150
183
  return code
151
- elif code[:3]+"."+code[3:] in code_to_node:
184
+ elif code[:3]+"."+code[3:] in _code_to_node:
152
185
  return code[:3]+"."+code[3:]
153
186
  else:
154
187
  return code
155
188
 
156
- def is_valid_item(code: str) -> bool:
157
- return code in code_to_node or len(code)>=4 and code[:3]+"."+code[3:] in code_to_node
189
+ def is_valid_item(code:str) -> bool:
190
+ return code in _code_to_node or len(code)>=4 and code[:3]+"."+code[3:] in _code_to_node
158
191
 
159
- def is_chapter(code: str) -> bool:
192
+ def is_chapter(code:str) -> bool:
160
193
  code = _add_dot_to_code(code)
161
- if code in code_to_node:
162
- return code_to_node[code].type=="chapter"
194
+ if code in _code_to_node:
195
+ return _code_to_node[code].type=="chapter"
163
196
  else:
164
197
  return False
165
198
 
166
- def is_block(code: str) -> bool:
199
+ def is_block(code:str) -> bool:
167
200
  code = _add_dot_to_code(code)
168
- if code in code_to_node:
169
- return code_to_node[code].type=="section" or code_to_node[code].parent!=None and code_to_node[code].parent.name==code #second half of the or is for sections containing a single category
201
+ if code in _code_to_node:
202
+ #second half of the or is for sections containing a single category
203
+ return _code_to_node[code].type=="section" or _code_to_node[code].parent!=None and _code_to_node[code].parent.name==code # type: ignore[reportOptionalMemberAccess]
170
204
  else:
171
205
  return False
172
206
 
173
- def is_category(code: str) -> bool:
207
+ def is_category(code:str) -> bool:
174
208
  code = _add_dot_to_code(code)
175
- if code in code_to_node:
176
- return code_to_node[code].type=="category"
209
+ if code in _code_to_node:
210
+ return _code_to_node[code].type=="category"
177
211
  else:
178
212
  return False
179
213
 
180
- def is_subcategory(code: str, include_extended_subcategories=True) -> bool:
214
+ def is_subcategory(code:str, include_extended_subcategories:bool=True) -> bool:
181
215
  code = _add_dot_to_code(code)
182
- if code in code_to_node:
183
- return code_to_node[code].type=="subcategory" or code_to_node[code].type=="extended subcategory" and include_extended_subcategories
216
+ if code in _code_to_node:
217
+ return _code_to_node[code].type=="subcategory" or _code_to_node[code].type=="extended subcategory" and include_extended_subcategories
184
218
  else:
185
219
  return False
186
220
 
187
- def is_extended_subcategory(code: str) -> bool:
221
+ def is_extended_subcategory(code:str) -> bool:
188
222
  code = _add_dot_to_code(code)
189
- if code in code_to_node:
190
- return code_to_node[code].type=="extended subcategory"
223
+ if code in _code_to_node:
224
+ return _code_to_node[code].type=="extended subcategory"
191
225
  else:
192
226
  return False
193
227
 
194
- def is_category_or_subcategory(code: str) -> bool:
228
+ def is_category_or_subcategory(code:str) -> bool:
195
229
  return is_subcategory(code) or is_category(code)
196
230
 
197
- def is_chapter_or_block(code: str) -> bool:
231
+ def is_chapter_or_block(code:str) -> bool:
198
232
  return is_block(code) or is_chapter(code)
199
233
 
200
- def get_description(code: str, prioritize_blocks=False) -> str:
234
+ def get_description(code:str, prioritize_blocks:bool=False) -> str:
201
235
  if not is_valid_item(code):
202
236
  raise ValueError("The code \""+code+"\" does not exist.")
203
- node = code_to_node[_add_dot_to_code(code)]
237
+ node = _code_to_node[_add_dot_to_code(code)]
204
238
  if prioritize_blocks and node.parent!=None and node.parent.name==node.name:
205
239
  return node.parent.description
206
240
  else:
207
241
  return node.description
208
242
 
209
- def get_excludes1(code: str, prioritize_blocks=False) -> list[str]:
243
+ def get_excludes1(code:str, prioritize_blocks:bool=False) -> list[str]:
210
244
  if not is_valid_item(code):
211
245
  raise ValueError("The code \""+code+"\" does not exist.")
212
- node = code_to_node[_add_dot_to_code(code)]
246
+ node = _code_to_node[_add_dot_to_code(code)]
213
247
  if prioritize_blocks and node.parent!=None and node.parent.name==node.name:
214
248
  return node.parent.excludes1.copy()
215
249
  else:
216
250
  return node.excludes1.copy()
217
251
 
218
- def get_excludes2(code: str, prioritize_blocks=False) -> list[str]:
252
+ def get_excludes2(code:str, prioritize_blocks:bool=False) -> list[str]:
219
253
  if not is_valid_item(code):
220
254
  raise ValueError("The code \""+code+"\" does not exist.")
221
- node = code_to_node[_add_dot_to_code(code)]
255
+ node = _code_to_node[_add_dot_to_code(code)]
222
256
  if prioritize_blocks and node.parent!=None and node.parent.name==node.name:
223
257
  return node.parent.excludes2.copy()
224
258
  else:
225
259
  return node.excludes2.copy()
226
260
 
227
- def get_includes(code: str, prioritize_blocks=False) -> list[str]:
261
+ def get_includes(code:str, prioritize_blocks:bool=False) -> list[str]:
228
262
  if not is_valid_item(code):
229
263
  raise ValueError("The code \""+code+"\" does not exist.")
230
- node = code_to_node[_add_dot_to_code(code)]
264
+ node = _code_to_node[_add_dot_to_code(code)]
231
265
  if prioritize_blocks and node.parent!=None and node.parent.name==node.name:
232
266
  return node.parent.includes.copy()
233
267
  else:
234
268
  return node.includes.copy()
235
269
 
236
- def get_inclusion_term(code: str, prioritize_blocks=False) -> list[str]:
270
+ def get_inclusion_term(code:str, prioritize_blocks:bool=False) -> list[str]:
237
271
  if not is_valid_item(code):
238
272
  raise ValueError("The code \""+code+"\" does not exist.")
239
- node = code_to_node[_add_dot_to_code(code)]
273
+ node = _code_to_node[_add_dot_to_code(code)]
240
274
  if prioritize_blocks and node.parent!=None and node.parent.name==node.name:
241
275
  return node.parent.inclusion_term.copy()
242
276
  else:
243
277
  return node.inclusion_term.copy()
244
278
 
245
- def get_seven_chr_def(code: str, search_in_ancestors=False, prioritize_blocks=False) -> dict[str, str]:
279
+ def get_seven_chr_def(code:str, search_in_ancestors:bool=False, prioritize_blocks:bool=False) -> dict[str,str]:
246
280
  if not is_valid_item(code):
247
281
  raise ValueError("The code \""+code+"\" does not exist.")
248
- node = code_to_node[_add_dot_to_code(code)]
282
+ node = _code_to_node[_add_dot_to_code(code)]
249
283
  if prioritize_blocks and node.parent!=None and node.parent.name==node.name:
250
284
  node = node.parent
251
285
  res = node.seven_chr_def.copy()
@@ -254,10 +288,10 @@ def get_seven_chr_def(code: str, search_in_ancestors=False, prioritize_blocks=Fa
254
288
  else:
255
289
  return res
256
290
 
257
- def get_seven_chr_note(code: str, search_in_ancestors=False, prioritize_blocks=False) -> str:
291
+ def get_seven_chr_note(code:str, search_in_ancestors:bool=False, prioritize_blocks:bool=False) -> str:
258
292
  if not is_valid_item(code):
259
293
  raise ValueError("The code \""+code+"\" does not exist.")
260
- node = code_to_node[_add_dot_to_code(code)]
294
+ node = _code_to_node[_add_dot_to_code(code)]
261
295
  if prioritize_blocks and node.parent!=None and node.parent.name==node.name:
262
296
  node = node.parent
263
297
  res = node.seven_chr_note
@@ -266,10 +300,10 @@ def get_seven_chr_note(code: str, search_in_ancestors=False, prioritize_blocks=F
266
300
  else:
267
301
  return res
268
302
 
269
- def get_use_additional_code(code: str, search_in_ancestors=False, prioritize_blocks=False) -> str:
303
+ def get_use_additional_code(code:str, search_in_ancestors:bool=False, prioritize_blocks:bool=False) -> str:
270
304
  if not is_valid_item(code):
271
305
  raise ValueError("The code \""+code+"\" does not exist.")
272
- node = code_to_node[_add_dot_to_code(code)]
306
+ node = _code_to_node[_add_dot_to_code(code)]
273
307
  if prioritize_blocks and node.parent!=None and node.parent.name==node.name:
274
308
  node = node.parent
275
309
  res = node.use_additional_code
@@ -278,10 +312,10 @@ def get_use_additional_code(code: str, search_in_ancestors=False, prioritize_blo
278
312
  else:
279
313
  return res
280
314
 
281
- def get_code_first(code: str, search_in_ancestors=False, prioritize_blocks=False) -> str:
315
+ def get_code_first(code:str, search_in_ancestors:bool=False, prioritize_blocks:bool=False) -> str:
282
316
  if not is_valid_item(code):
283
317
  raise ValueError("The code \""+code+"\" does not exist.")
284
- node = code_to_node[_add_dot_to_code(code)]
318
+ node = _code_to_node[_add_dot_to_code(code)]
285
319
  if prioritize_blocks and node.parent!=None and node.parent.name==node.name:
286
320
  node = node.parent
287
321
  res = node.code_first
@@ -290,10 +324,10 @@ def get_code_first(code: str, search_in_ancestors=False, prioritize_blocks=False
290
324
  else:
291
325
  return res
292
326
 
293
- def get_parent(code: str, prioritize_blocks=False) -> str:
327
+ def get_parent(code:str, prioritize_blocks:bool=False) -> str:
294
328
  if not is_valid_item(code):
295
329
  raise ValueError("The code \""+code+"\" does not exist.")
296
- node = code_to_node[_add_dot_to_code(code)]
330
+ node = _code_to_node[_add_dot_to_code(code)]
297
331
  if prioritize_blocks and node.parent!=None and node.parent.name==node.name:
298
332
  node = node.parent
299
333
  if node.parent!=None:
@@ -301,10 +335,10 @@ def get_parent(code: str, prioritize_blocks=False) -> str:
301
335
  else:
302
336
  return ""
303
337
 
304
- def get_children(code: str, prioritize_blocks=False) -> list[str]:
338
+ def get_children(code:str, prioritize_blocks:bool=False) -> list[str]:
305
339
  if not is_valid_item(code):
306
340
  raise ValueError("The code \""+code+"\" does not exist.")
307
- node = code_to_node[_add_dot_to_code(code)]
341
+ node = _code_to_node[_add_dot_to_code(code)]
308
342
  if prioritize_blocks and node.parent!=None and node.parent.name==node.name:
309
343
  node = node.parent
310
344
  res = []
@@ -312,18 +346,18 @@ def get_children(code: str, prioritize_blocks=False) -> list[str]:
312
346
  res.append(child.name)
313
347
  return res
314
348
 
315
- def is_leaf(code: str, prioritize_blocks=False) -> bool:
349
+ def is_leaf(code:str, prioritize_blocks:bool=False) -> bool:
316
350
  if not is_valid_item(code):
317
351
  raise ValueError("The code \""+code+"\" does not exist.")
318
- node = code_to_node[_add_dot_to_code(code)]
352
+ node = _code_to_node[_add_dot_to_code(code)]
319
353
  if prioritize_blocks and node.parent!=None and node.parent.name==node.name:
320
354
  node = node.parent
321
355
  return len(node.children)==0
322
356
 
323
- def get_full_data(code: str, search_in_ancestors=False, prioritize_blocks=False) -> str:
357
+ def get_full_data(code:str, search_in_ancestors:bool=False, prioritize_blocks:bool=False) -> str:
324
358
  if not is_valid_item(code):
325
359
  raise ValueError("The code \""+code+"\" does not exist.")
326
- node = code_to_node[_add_dot_to_code(code)]
360
+ node = _code_to_node[_add_dot_to_code(code)]
327
361
  if prioritize_blocks and node.parent!=None and node.parent.name==node.name:
328
362
  node = node.parent
329
363
  str = "Name:\n"+node.name+"\nDescription:\n"+node.description
@@ -367,10 +401,10 @@ def get_full_data(code: str, search_in_ancestors=False, prioritize_blocks=False)
367
401
  str = str + child.name + ", "
368
402
  return str[:-2]
369
403
 
370
- def get_ancestors(code: str,prioritize_blocks=False) -> list[str]:
404
+ def get_ancestors(code:str,prioritize_blocks:bool=False) -> list[str]:
371
405
  if not is_valid_item(code):
372
406
  raise ValueError("The code \""+code+"\" does not exist.")
373
- node = code_to_node[_add_dot_to_code(code)]
407
+ node = _code_to_node[_add_dot_to_code(code)]
374
408
  if prioritize_blocks and node.parent!=None and node.parent.name==node.name:
375
409
  node = node.parent
376
410
  result = []
@@ -379,33 +413,33 @@ def get_ancestors(code: str,prioritize_blocks=False) -> list[str]:
379
413
  node=node.parent
380
414
  return result
381
415
 
382
- def get_descendants(code: str,prioritize_blocks=False) -> list[str]:
416
+ def get_descendants(code:str,prioritize_blocks:bool=False) -> list[str]:
383
417
  if not is_valid_item(code):
384
418
  raise ValueError("The code \""+code+"\" does not exist.")
385
- node = code_to_node[_add_dot_to_code(code)]
419
+ node = _code_to_node[_add_dot_to_code(code)]
386
420
  if prioritize_blocks and node.parent!=None and node.parent.name==node.name:
387
421
  node = node.parent
388
422
  result = []
389
423
  _add_children_to_list(node, result)
390
424
  return result
391
425
 
392
- def _add_children_to_list(node, list):
426
+ def _add_children_to_list(node:_CodeTree, list:list[str]) -> None:
393
427
  for child in node.children:
394
428
  list.append(child.name)
395
429
  _add_children_to_list(child,list)
396
430
 
397
- def is_ancestor(a:str,b:str,prioritize_blocks_a=False,prioritize_blocks_b=False) -> bool:
431
+ def is_ancestor(a:str,b:str,prioritize_blocks_a:bool=False,prioritize_blocks_b:bool=False) -> bool:
398
432
  if not is_valid_item(a):
399
433
  raise ValueError("The code \""+a+"\" does not exist.")
400
- node = code_to_node[_add_dot_to_code(a)]
434
+ node = _code_to_node[_add_dot_to_code(a)]
401
435
  if prioritize_blocks_a and node.parent!=None and node.parent.name==node.name:
402
436
  node = node.parent
403
437
  return a in get_ancestors(b, prioritize_blocks=prioritize_blocks_b) and (a!=b or prioritize_blocks_a)
404
438
 
405
- def is_descendant(a:str,b:str,prioritize_blocks_a=False,prioritize_blocks_b=False) -> bool:
439
+ def is_descendant(a:str,b:str,prioritize_blocks_a:bool=False,prioritize_blocks_b:bool=False) -> bool:
406
440
  return is_ancestor(b,a,prioritize_blocks_a=prioritize_blocks_b,prioritize_blocks_b=prioritize_blocks_a)
407
441
 
408
- def get_nearest_common_ancestor(a:str,b:str,prioritize_blocks_a=False,prioritize_blocks_b=False) -> str:
442
+ def get_nearest_common_ancestor(a:str,b:str,prioritize_blocks_a:bool=False,prioritize_blocks_b:bool=False) -> str:
409
443
  anc_a = [_add_dot_to_code(a)] + get_ancestors(a, prioritize_blocks=prioritize_blocks_a)
410
444
  anc_b = [_add_dot_to_code(b)] + get_ancestors(b, prioritize_blocks=prioritize_blocks_b)
411
445
  if len(anc_b) > len(anc_a):
@@ -417,50 +451,50 @@ def get_nearest_common_ancestor(a:str,b:str,prioritize_blocks_a=False,prioritize
417
451
  return anc
418
452
  return ""
419
453
 
420
- def get_all_codes(with_dots=True) -> list[str]:
421
- if all_codes_list==[]:
422
- for chapter in chapter_list:
423
- _add_tree_to_list(chapter)
454
+ def get_all_codes(with_dots:bool=True) -> list[str]:
455
+ if _all_codes_list==[]:
456
+ _fill_all_codes_list()
424
457
  if with_dots:
425
- return all_codes_list.copy()
458
+ return _all_codes_list.copy()
426
459
  else:
427
- return all_codes_list_no_dots.copy()
460
+ return _all_codes_list_no_dots.copy()
428
461
 
429
- def _add_tree_to_list(tree):
430
- all_codes_list.append(tree.name)
462
+ def _fill_all_codes_list() -> None:
463
+ for chapter in _chapter_list:
464
+ _add_tree_to_list(chapter)
465
+
466
+ def _add_tree_to_list(tree:_CodeTree) -> None:
467
+ _all_codes_list.append(tree.name)
431
468
  if(len(tree.name)>4 and tree.name[3]=="."):
432
- all_codes_list_no_dots.append(tree.name[:3]+tree.name[4:])
469
+ _all_codes_list_no_dots.append(tree.name[:3]+tree.name[4:])
433
470
  else:
434
- all_codes_list_no_dots.append(tree.name)
471
+ _all_codes_list_no_dots.append(tree.name)
435
472
  for child in tree.children:
436
473
  _add_tree_to_list(child)
437
474
 
438
- def get_index(code: str) -> int:
475
+ def get_index(code:str) -> int: # type: ignore[reportReturnType]
439
476
  if not is_valid_item(code):
440
477
  raise ValueError("The code \""+code+"\" does not exist.")
441
478
  code = _add_dot_to_code(code)
442
- if all_codes_list==[]:
443
- for chapter in chapter_list:
444
- _add_tree_to_list(chapter)
445
- if code in code_to_index_dictionary:
446
- return code_to_index_dictionary[code]
479
+ if _all_codes_list==[]:
480
+ _fill_all_codes_list()
481
+ if code in _code_to_index_dictionary:
482
+ return _code_to_index_dictionary[code]
447
483
  else:
448
484
  i=0
449
- for c in all_codes_list:
485
+ for c in _all_codes_list:
450
486
  if c==code:
451
- code_to_index_dictionary[code]=i
487
+ _code_to_index_dictionary[code]=i
452
488
  return i
453
489
  else:
454
490
  i=i+1
455
491
 
456
- def remove_dot(code: str) -> str:
457
- if all_codes_list==[]:
458
- for chapter in chapter_list:
459
- _add_tree_to_list(chapter)
460
- return all_codes_list_no_dots[get_index(code)]
461
-
462
- def add_dot(code: str) -> str:
463
- if all_codes_list==[]:
464
- for chapter in chapter_list:
465
- _add_tree_to_list(chapter)
466
- return all_codes_list[get_index(code)]
492
+ def remove_dot(code:str) -> str:
493
+ if _all_codes_list==[]:
494
+ _fill_all_codes_list()
495
+ return _all_codes_list_no_dots[get_index(code)]
496
+
497
+ def add_dot(code:str) -> str:
498
+ if _all_codes_list==[]:
499
+ _fill_all_codes_list()
500
+ return _all_codes_list[get_index(code)]