bioguider 0.2.29__py3-none-any.whl → 0.2.30__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.

Potentially problematic release.


This version of bioguider might be problematic. Click here for more details.

@@ -8,50 +8,132 @@ class SuggestionExtractor:
8
8
  def extract(self, report: EvaluationReport) -> List[SuggestionItem]:
9
9
  suggestions: List[SuggestionItem] = []
10
10
 
11
- # README-related suggestions
11
+ # README-related suggestions - Extract specific suggestions
12
12
  if report.readme_evaluation:
13
13
  for file_name, evaluation in report.readme_evaluation.items():
14
14
  structured = evaluation.get("structured_evaluation") if isinstance(evaluation, dict) else None
15
15
  if structured:
16
+ # Extract specific dependency suggestions
17
+ dep_score = structured.get("dependency_score")
18
+ dep_suggestions = structured.get("dependency_suggestions")
19
+ if dep_score in ("Poor", "Fair") and dep_suggestions:
20
+ suggestions.append(SuggestionItem(
21
+ id=f"readme-dependencies-{file_name}",
22
+ category="readme.dependencies",
23
+ severity="should_fix",
24
+ source={"section": "readme", "field": "dependency_suggestions", "evidence": dep_suggestions, "score": dep_score},
25
+ target_files=[file_name],
26
+ action="add_dependencies_section",
27
+ anchor_hint="Dependencies",
28
+ content_guidance=dep_suggestions,
29
+ ))
30
+
31
+ # Extract specific hardware/software suggestions
32
+ hw_sw_score = structured.get("hardware_and_software_spec_score")
33
+ hw_sw_suggestions = structured.get("hardware_and_software_spec_suggestions")
34
+ if hw_sw_score in ("Poor", "Fair") and hw_sw_suggestions:
35
+ suggestions.append(SuggestionItem(
36
+ id=f"readme-hardware-{file_name}",
37
+ category="readme.hardware",
38
+ severity="should_fix",
39
+ source={"section": "readme", "field": "hardware_and_software_spec_suggestions", "evidence": hw_sw_suggestions, "score": hw_sw_score},
40
+ target_files=[file_name],
41
+ action="add_system_requirements_section",
42
+ anchor_hint="System Requirements",
43
+ content_guidance=hw_sw_suggestions,
44
+ ))
45
+
46
+ # Extract specific project purpose suggestions
47
+ purpose_score = structured.get("project_purpose_score")
48
+ purpose_suggestions = structured.get("project_purpose_suggestions")
49
+ if purpose_score in ("Poor", "Fair") and purpose_suggestions:
50
+ suggestions.append(SuggestionItem(
51
+ id=f"readme-purpose-{file_name}",
52
+ category="readme.purpose",
53
+ severity="should_fix",
54
+ source={"section": "readme", "field": "project_purpose_suggestions", "evidence": purpose_suggestions, "score": purpose_score},
55
+ target_files=[file_name],
56
+ action="add_overview_section",
57
+ anchor_hint="Overview",
58
+ content_guidance=purpose_suggestions,
59
+ ))
60
+
61
+ # Extract specific readability suggestions
62
+ readability_score = structured.get("readability_score")
63
+ readability_suggestions = structured.get("readability_suggestions")
64
+ if readability_score in ("Poor", "Fair") and readability_suggestions:
65
+ suggestions.append(SuggestionItem(
66
+ id=f"readme-readability-{file_name}",
67
+ category="readme.readability",
68
+ severity="should_fix",
69
+ source={"section": "readme", "field": "readability_suggestions", "evidence": readability_suggestions, "score": readability_score},
70
+ target_files=[file_name],
71
+ action="improve_readability",
72
+ anchor_hint="Introduction",
73
+ content_guidance=readability_suggestions,
74
+ ))
75
+
16
76
  # Intro cleanup / overview enhancement beyond explicit suggestions
17
77
  suggestions.append(SuggestionItem(
18
78
  id=f"readme-intro-cleanup-{file_name}",
19
79
  category="readme.intro_cleanup",
20
80
  severity="should_fix",
21
- source={"section": "readme", "field": "overview", "evidence": "Improve top-level overview for clarity and tone."},
81
+ source={"section": "readme", "field": "overview", "evidence": "Improve top-level overview for clarity and tone.", "score": "Fair"},
22
82
  target_files=[file_name],
23
83
  action="replace_intro",
24
84
  anchor_hint="Overview",
25
85
  content_guidance="Rewrite the opening summary to be clear, neutral, and typo-free.",
26
86
  ))
27
- # Dependency clarity
87
+ # Dependency clarity - prioritize specific suggestions (avoid duplicates)
28
88
  dep_score = structured.get("dependency_score")
29
89
  dep_sugg = structured.get("dependency_suggestions")
30
- if dep_score in ("Poor", "Fair") or dep_sugg:
90
+ if dep_sugg and dep_score in ("Poor", "Fair"): # Only if not already added above
31
91
  suggestions.append(SuggestionItem(
32
- id=f"readme-dependencies-{file_name}",
92
+ id=f"readme-dependencies-clarify-{file_name}",
33
93
  category="readme.dependencies",
34
94
  severity="should_fix",
35
- source={"section": "readme", "field": "dependencies", "evidence": str(dep_sugg or dep_score)},
95
+ source={"section": "readme", "field": "dependencies", "evidence": str(dep_sugg), "score": dep_score},
36
96
  target_files=[file_name],
37
97
  action="add_dependencies_section",
38
98
  anchor_hint="Dependencies",
39
- content_guidance=str(dep_sugg or ""),
99
+ content_guidance=str(dep_sugg),
100
+ ))
101
+ elif dep_score in ("Poor", "Fair"): # Fallback to score-based approach
102
+ suggestions.append(SuggestionItem(
103
+ id=f"readme-dependencies-fallback-{file_name}",
104
+ category="readme.dependencies",
105
+ severity="should_fix",
106
+ source={"section": "readme", "field": "dependencies", "evidence": f"score={dep_score}", "score": dep_score},
107
+ target_files=[file_name],
108
+ action="add_dependencies_section",
109
+ anchor_hint="Dependencies",
110
+ content_guidance="List R library dependencies and provide installation guide.",
40
111
  ))
41
112
 
42
- # Hardware/Software specs
113
+ # Hardware/Software specs - prioritize specific suggestions (avoid duplicates)
43
114
  hw_score = structured.get("hardware_and_software_spec_score")
44
115
  hw_sugg = structured.get("hardware_and_software_spec_suggestions")
45
- if hw_score in ("Poor", "Fair") or hw_sugg:
116
+ if hw_sugg and hw_score in ("Poor", "Fair"): # Only if not already added above
46
117
  suggestions.append(SuggestionItem(
47
- id=f"readme-sysreq-{file_name}",
118
+ id=f"readme-sysreq-clarify-{file_name}",
48
119
  category="readme.system_requirements",
49
120
  severity="should_fix",
50
- source={"section": "readme", "field": "hardware_and_software", "evidence": str(hw_sugg or hw_score)},
121
+ source={"section": "readme", "field": "hardware_and_software", "evidence": str(hw_sugg), "score": hw_score},
51
122
  target_files=[file_name],
52
123
  action="add_system_requirements_section",
53
124
  anchor_hint="System Requirements",
54
- content_guidance=str(hw_sugg or ""),
125
+ content_guidance=str(hw_sugg),
126
+ ))
127
+ elif hw_score in ("Poor", "Fair"): # Fallback to score-based approach
128
+ suggestions.append(SuggestionItem(
129
+ id=f"readme-sysreq-fallback-{file_name}",
130
+ category="readme.system_requirements",
131
+ severity="should_fix",
132
+ source={"section": "readme", "field": "hardware_and_software", "evidence": f"score={hw_score}", "score": hw_score},
133
+ target_files=[file_name],
134
+ action="add_system_requirements_section",
135
+ anchor_hint="System Requirements",
136
+ content_guidance="Specify R version requirements, recommend RAM/CPU configurations, and tailor installation instructions for platforms.",
55
137
  ))
56
138
 
57
139
  # License mention
@@ -69,19 +151,31 @@ class SuggestionExtractor:
69
151
  content_guidance=str(lic_sugg),
70
152
  ))
71
153
 
72
- # Readability structuring
154
+ # Readability structuring - prioritize specific suggestions (avoid duplicates)
73
155
  read_sugg = structured.get("readability_suggestions")
74
- if read_sugg:
156
+ read_score = structured.get("readability_score")
157
+ if read_sugg and read_score in ("Poor", "Fair"): # Only if not already added above
75
158
  suggestions.append(SuggestionItem(
76
- id=f"readme-structure-{file_name}",
159
+ id=f"readme-structure-clarify-{file_name}",
77
160
  category="readme.readability",
78
- severity="nice_to_have",
79
- source={"section": "readability", "field": "readability_suggestions", "evidence": str(read_sugg)},
161
+ severity="should_fix",
162
+ source={"section": "readability", "field": "readability_suggestions", "evidence": str(read_sugg), "score": read_score},
80
163
  target_files=[file_name],
81
164
  action="normalize_headings_structure",
82
165
  anchor_hint="Installation",
83
166
  content_guidance=str(read_sugg),
84
167
  ))
168
+ elif read_score in ("Poor", "Fair"): # Fallback to score-based approach
169
+ suggestions.append(SuggestionItem(
170
+ id=f"readme-structure-fallback-{file_name}",
171
+ category="readme.readability",
172
+ severity="should_fix",
173
+ source={"section": "readability", "field": "readability_score", "evidence": f"score={read_score}", "score": read_score},
174
+ target_files=[file_name],
175
+ action="normalize_headings_structure",
176
+ anchor_hint="Installation",
177
+ content_guidance="Improve readability with better structure and formatting.",
178
+ ))
85
179
  # If suggestions mention Usage, add a usage section
86
180
  if isinstance(read_sugg, str) and "Usage" in read_sugg:
87
181
  suggestions.append(SuggestionItem(
@@ -101,8 +195,25 @@ class SuggestionExtractor:
101
195
  if isinstance(report.installation_evaluation, dict):
102
196
  structured = report.installation_evaluation.get("structured_evaluation")
103
197
  if structured:
198
+ # If installation has deficits, full replace installation docs listed in installation_files
199
+ overall = structured.get("overall_score")
200
+ hw = structured.get("hardware_requirements")
201
+ compat = structured.get("compatible_os")
202
+ dep_sugg = structured.get("dependency_suggestions")
203
+ if overall in ("Poor", "Fair") or hw is False or compat is False or dep_sugg:
204
+ for target in report.installation_files or []:
205
+ suggestions.append(SuggestionItem(
206
+ id=f"install-full-replace-{target}",
207
+ category="installation.full_replace",
208
+ severity="should_fix",
209
+ source={"section": "installation", "field": "overall", "evidence": str(structured)},
210
+ target_files=[target],
211
+ action="full_replace",
212
+ anchor_hint=None,
213
+ content_guidance="Rewrite installation doc based on evaluation (dependencies, OS, hardware).",
214
+ ))
104
215
  dep_sugg = structured.get("dependency_suggestions")
105
- if dep_sugg:
216
+ if dep_sugg: # Prioritize specific suggestions
106
217
  for target in report.installation_files or []:
107
218
  suggestions.append(SuggestionItem(
108
219
  id=f"install-dep-clarify-{target}",
@@ -114,14 +225,14 @@ class SuggestionExtractor:
114
225
  anchor_hint="Dependencies",
115
226
  content_guidance=str(dep_sugg),
116
227
  ))
117
- hw = structured.get("hardware_requirements")
118
- if hw is False:
228
+ hw_score = structured.get("hardware_requirements")
229
+ if hw_score is False:
119
230
  for target in report.installation_files or []:
120
231
  suggestions.append(SuggestionItem(
121
232
  id=f"install-hw-req-{target}",
122
233
  category="installation.hardware",
123
234
  severity="should_fix",
124
- source={"section": "installation", "field": "hardware_requirements", "evidence": "not specified"},
235
+ source={"section": "installation", "field": "hardware_requirements", "score": "Poor", "evidence": "Hardware requirements not specified"},
125
236
  target_files=[target],
126
237
  action="add_hardware_requirements",
127
238
  anchor_hint="Hardware Requirements",
@@ -131,6 +242,219 @@ class SuggestionExtractor:
131
242
  # Submission requirements could drive expected output/dataset sections; use only if in files list
132
243
  # Keep minimal to avoid speculative content
133
244
 
245
+ # Userguide/API docs suggestions (new interface) - Extract specific suggestions
246
+ if getattr(report, "userguide_evaluation", None) and isinstance(report.userguide_evaluation, dict):
247
+ for file_name, eval_block in report.userguide_evaluation.items():
248
+ ug_eval = eval_block.get("user_guide_evaluation") if isinstance(eval_block, dict) else None
249
+ consistency_eval = eval_block.get("consistency_evaluation") if isinstance(eval_block, dict) else None
250
+
251
+ if isinstance(ug_eval, dict):
252
+ # Extract specific readability suggestions
253
+ readability_score = ug_eval.get("readability_score", "")
254
+ readability_suggestions = ug_eval.get("readability_suggestions", [])
255
+ if readability_score in ("Poor", "Fair") and readability_suggestions:
256
+ for i, suggestion in enumerate(readability_suggestions):
257
+ if isinstance(suggestion, str) and suggestion.strip():
258
+ suggestions.append(SuggestionItem(
259
+ id=f"userguide-readability-{file_name}-{i}",
260
+ category="userguide.readability",
261
+ severity="should_fix",
262
+ source={"section": "userguide", "field": "readability_suggestions", "evidence": suggestion, "score": readability_score},
263
+ target_files=[file_name],
264
+ action="improve_readability",
265
+ anchor_hint=f"Readability-{i+1}",
266
+ content_guidance=suggestion,
267
+ ))
268
+
269
+ # Extract specific context and purpose suggestions
270
+ context_score = ug_eval.get("context_and_purpose_score", "")
271
+ context_suggestions = ug_eval.get("context_and_purpose_suggestions", [])
272
+ if context_score in ("Poor", "Fair") and context_suggestions:
273
+ for i, suggestion in enumerate(context_suggestions):
274
+ if isinstance(suggestion, str) and suggestion.strip():
275
+ suggestions.append(SuggestionItem(
276
+ id=f"userguide-context-{file_name}-{i}",
277
+ category="userguide.context",
278
+ severity="should_fix",
279
+ source={"section": "userguide", "field": "context_and_purpose_suggestions", "evidence": suggestion, "score": context_score},
280
+ target_files=[file_name],
281
+ action="improve_context",
282
+ anchor_hint=f"Context-{i+1}",
283
+ content_guidance=suggestion,
284
+ ))
285
+
286
+ # Extract specific error handling suggestions
287
+ error_score = ug_eval.get("error_handling_score", "")
288
+ error_suggestions = ug_eval.get("error_handling_suggestions", [])
289
+ if error_score in ("Poor", "Fair") and error_suggestions:
290
+ for i, suggestion in enumerate(error_suggestions):
291
+ if isinstance(suggestion, str) and suggestion.strip():
292
+ suggestions.append(SuggestionItem(
293
+ id=f"userguide-error-{file_name}-{i}",
294
+ category="userguide.error_handling",
295
+ severity="should_fix",
296
+ source={"section": "userguide", "field": "error_handling_suggestions", "evidence": suggestion, "score": error_score},
297
+ target_files=[file_name],
298
+ action="improve_error_handling",
299
+ anchor_hint=f"Error-Handling-{i+1}",
300
+ content_guidance=suggestion,
301
+ ))
302
+
303
+ # If consistency issues present, add targeted improvements
304
+ if isinstance(consistency_eval, dict):
305
+ score = consistency_eval.get("score")
306
+ if score in ("Poor", "Fair"):
307
+ suggestions.append(SuggestionItem(
308
+ id=f"userguide-consistency-{file_name}",
309
+ category="userguide.consistency",
310
+ severity="should_fix",
311
+ source={"section": "userguide", "field": "consistency", "evidence": f"score={score}"},
312
+ target_files=[file_name],
313
+ action="improve_consistency",
314
+ anchor_hint="Examples",
315
+ content_guidance="Improve consistency in examples, terminology, and formatting based on evaluation report.",
316
+ ))
317
+
318
+ # Tutorials/vignettes suggestions (new interface) - ONLY Poor/Fair scores
319
+ if getattr(report, "tutorial_evaluation", None) and isinstance(report.tutorial_evaluation, dict):
320
+ for file_name, eval_block in report.tutorial_evaluation.items():
321
+ tut_eval = eval_block.get("tutorial_evaluation") if isinstance(eval_block, dict) else None
322
+ consistency_eval = eval_block.get("consistency_evaluation") if isinstance(eval_block, dict) else None
323
+ if isinstance(tut_eval, dict):
324
+ # Only extract suggestions for Poor/Fair scores
325
+
326
+ # Readability suggestions - only if score is Poor/Fair
327
+ readability_score = tut_eval.get("readability_score", "")
328
+ readability_suggestions = tut_eval.get("readability_suggestions", [])
329
+ if readability_score in ("Poor", "Fair") and readability_suggestions:
330
+ for i, suggestion in enumerate(readability_suggestions):
331
+ if isinstance(suggestion, str) and suggestion.strip():
332
+ suggestions.append(SuggestionItem(
333
+ id=f"tutorial-readability-{file_name}-{i}",
334
+ category="tutorial.readability",
335
+ severity="should_fix",
336
+ source={"section": "tutorial", "field": "readability_suggestions", "evidence": suggestion, "score": readability_score},
337
+ target_files=[file_name],
338
+ action="improve_readability",
339
+ anchor_hint="Introduction",
340
+ content_guidance=suggestion,
341
+ ))
342
+
343
+ # Setup and dependencies suggestions - only if score is Poor/Fair
344
+ setup_score = tut_eval.get("setup_and_dependencies_score", "")
345
+ setup_suggestions = tut_eval.get("setup_and_dependencies_suggestions", [])
346
+ if setup_score in ("Poor", "Fair") and setup_suggestions:
347
+ for i, suggestion in enumerate(setup_suggestions):
348
+ if isinstance(suggestion, str) and suggestion.strip():
349
+ suggestions.append(SuggestionItem(
350
+ id=f"tutorial-setup-{file_name}-{i}",
351
+ category="tutorial.setup",
352
+ severity="should_fix",
353
+ source={"section": "tutorial", "field": "setup_and_dependencies_suggestions", "evidence": suggestion, "score": setup_score},
354
+ target_files=[file_name],
355
+ action="improve_setup",
356
+ anchor_hint="Setup",
357
+ content_guidance=suggestion,
358
+ ))
359
+
360
+ # Reproducibility suggestions - only if score is Poor/Fair
361
+ reproducibility_score = tut_eval.get("reproducibility_score", "")
362
+ reproducibility_suggestions = tut_eval.get("reproducibility_suggestions", [])
363
+ if reproducibility_score in ("Poor", "Fair") and reproducibility_suggestions:
364
+ for i, suggestion in enumerate(reproducibility_suggestions):
365
+ if isinstance(suggestion, str) and suggestion.strip():
366
+ suggestions.append(SuggestionItem(
367
+ id=f"tutorial-reproducibility-{file_name}-{i}",
368
+ category="tutorial.reproducibility",
369
+ severity="should_fix",
370
+ source={"section": "tutorial", "field": "reproducibility_suggestions", "evidence": suggestion, "score": reproducibility_score},
371
+ target_files=[file_name],
372
+ action="improve_reproducibility",
373
+ anchor_hint="Setup",
374
+ content_guidance=suggestion,
375
+ ))
376
+
377
+ # Structure and navigation suggestions - only if score is Poor/Fair
378
+ structure_score = tut_eval.get("structure_and_navigation_score", "")
379
+ structure_suggestions = tut_eval.get("structure_and_navigation_suggestions", [])
380
+ if structure_score in ("Poor", "Fair") and structure_suggestions:
381
+ for i, suggestion in enumerate(structure_suggestions):
382
+ if isinstance(suggestion, str) and suggestion.strip():
383
+ suggestions.append(SuggestionItem(
384
+ id=f"tutorial-structure-{file_name}-{i}",
385
+ category="tutorial.structure",
386
+ severity="should_fix",
387
+ source={"section": "tutorial", "field": "structure_and_navigation_suggestions", "evidence": suggestion, "score": structure_score},
388
+ target_files=[file_name],
389
+ action="improve_structure",
390
+ anchor_hint="Introduction",
391
+ content_guidance=suggestion,
392
+ ))
393
+
394
+ # Executable code quality suggestions - only if score is Poor/Fair
395
+ code_score = tut_eval.get("executable_code_quality_score", "")
396
+ code_suggestions = tut_eval.get("executable_code_quality_suggestions", [])
397
+ if code_score in ("Poor", "Fair") and code_suggestions:
398
+ for i, suggestion in enumerate(code_suggestions):
399
+ if isinstance(suggestion, str) and suggestion.strip():
400
+ suggestions.append(SuggestionItem(
401
+ id=f"tutorial-code-{file_name}-{i}",
402
+ category="tutorial.code_quality",
403
+ severity="should_fix",
404
+ source={"section": "tutorial", "field": "executable_code_quality_suggestions", "evidence": suggestion, "score": code_score},
405
+ target_files=[file_name],
406
+ action="improve_code_quality",
407
+ anchor_hint="Code Examples",
408
+ content_guidance=suggestion,
409
+ ))
410
+
411
+ # Result verification suggestions - only if score is Poor/Fair
412
+ verification_score = tut_eval.get("result_verification_score", "")
413
+ verification_suggestions = tut_eval.get("result_verification_suggestions", [])
414
+ if verification_score in ("Poor", "Fair") and verification_suggestions:
415
+ for i, suggestion in enumerate(verification_suggestions):
416
+ if isinstance(suggestion, str) and suggestion.strip():
417
+ suggestions.append(SuggestionItem(
418
+ id=f"tutorial-verification-{file_name}-{i}",
419
+ category="tutorial.verification",
420
+ severity="should_fix",
421
+ source={"section": "tutorial", "field": "result_verification_suggestions", "evidence": suggestion, "score": verification_score},
422
+ target_files=[file_name],
423
+ action="improve_verification",
424
+ anchor_hint="Results",
425
+ content_guidance=suggestion,
426
+ ))
427
+
428
+ # Performance and resource notes suggestions - only if score is Poor/Fair
429
+ performance_score = tut_eval.get("performance_and_resource_notes_score", "")
430
+ performance_suggestions = tut_eval.get("performance_and_resource_notes_suggestions", [])
431
+ if performance_score in ("Poor", "Fair") and performance_suggestions:
432
+ for i, suggestion in enumerate(performance_suggestions):
433
+ if isinstance(suggestion, str) and suggestion.strip():
434
+ suggestions.append(SuggestionItem(
435
+ id=f"tutorial-performance-{file_name}-{i}",
436
+ category="tutorial.performance",
437
+ severity="should_fix",
438
+ source={"section": "tutorial", "field": "performance_and_resource_notes_suggestions", "evidence": suggestion, "score": performance_score},
439
+ target_files=[file_name],
440
+ action="improve_performance",
441
+ anchor_hint="Performance",
442
+ content_guidance=suggestion,
443
+ ))
444
+ if isinstance(consistency_eval, dict):
445
+ score = consistency_eval.get("score")
446
+ if score in ("Poor", "Fair"):
447
+ suggestions.append(SuggestionItem(
448
+ id=f"tutorial-consistency-{file_name}",
449
+ category="tutorial.consistency",
450
+ severity="should_fix",
451
+ source={"section": "tutorial", "field": "consistency", "evidence": f"score={score}"},
452
+ target_files=[file_name],
453
+ action="full_replace",
454
+ anchor_hint=None,
455
+ content_guidance="Align tutorial with code definitions; fix inconsistencies as per report.",
456
+ ))
457
+
134
458
  return suggestions
135
459
 
136
460