fishertools 0.2.1__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.
- fishertools/__init__.py +82 -0
- fishertools/config/__init__.py +24 -0
- fishertools/config/manager.py +247 -0
- fishertools/config/models.py +96 -0
- fishertools/config/parser.py +265 -0
- fishertools/decorators.py +93 -0
- fishertools/documentation/__init__.py +38 -0
- fishertools/documentation/api.py +242 -0
- fishertools/documentation/generator.py +502 -0
- fishertools/documentation/models.py +126 -0
- fishertools/documentation/visual.py +583 -0
- fishertools/errors/__init__.py +29 -0
- fishertools/errors/exceptions.py +191 -0
- fishertools/errors/explainer.py +303 -0
- fishertools/errors/formatters.py +386 -0
- fishertools/errors/models.py +228 -0
- fishertools/errors/patterns.py +119 -0
- fishertools/errors/recovery.py +467 -0
- fishertools/examples/__init__.py +22 -0
- fishertools/examples/models.py +118 -0
- fishertools/examples/repository.py +770 -0
- fishertools/helpers.py +116 -0
- fishertools/integration.py +451 -0
- fishertools/learn/__init__.py +18 -0
- fishertools/learn/examples.py +550 -0
- fishertools/learn/tips.py +281 -0
- fishertools/learning/__init__.py +32 -0
- fishertools/learning/core.py +349 -0
- fishertools/learning/models.py +112 -0
- fishertools/learning/progress.py +314 -0
- fishertools/learning/session.py +500 -0
- fishertools/learning/tutorial.py +626 -0
- fishertools/legacy/__init__.py +76 -0
- fishertools/legacy/deprecated.py +261 -0
- fishertools/legacy/deprecation.py +149 -0
- fishertools/safe/__init__.py +16 -0
- fishertools/safe/collections.py +242 -0
- fishertools/safe/files.py +240 -0
- fishertools/safe/strings.py +15 -0
- fishertools/utils.py +57 -0
- fishertools-0.2.1.dist-info/METADATA +256 -0
- fishertools-0.2.1.dist-info/RECORD +81 -0
- fishertools-0.2.1.dist-info/WHEEL +5 -0
- fishertools-0.2.1.dist-info/licenses/LICENSE +21 -0
- fishertools-0.2.1.dist-info/top_level.txt +2 -0
- tests/__init__.py +6 -0
- tests/conftest.py +25 -0
- tests/test_config/__init__.py +3 -0
- tests/test_config/test_basic_config.py +57 -0
- tests/test_config/test_config_error_handling.py +287 -0
- tests/test_config/test_config_properties.py +435 -0
- tests/test_documentation/__init__.py +3 -0
- tests/test_documentation/test_documentation_properties.py +253 -0
- tests/test_documentation/test_visual_documentation_properties.py +444 -0
- tests/test_errors/__init__.py +3 -0
- tests/test_errors/test_api.py +301 -0
- tests/test_errors/test_error_handling.py +354 -0
- tests/test_errors/test_explainer.py +173 -0
- tests/test_errors/test_formatters.py +338 -0
- tests/test_errors/test_models.py +248 -0
- tests/test_errors/test_patterns.py +270 -0
- tests/test_examples/__init__.py +3 -0
- tests/test_examples/test_example_repository_properties.py +204 -0
- tests/test_examples/test_specific_examples.py +303 -0
- tests/test_integration.py +298 -0
- tests/test_integration_enhancements.py +462 -0
- tests/test_learn/__init__.py +3 -0
- tests/test_learn/test_examples.py +221 -0
- tests/test_learn/test_tips.py +285 -0
- tests/test_learning/__init__.py +3 -0
- tests/test_learning/test_interactive_learning_properties.py +337 -0
- tests/test_learning/test_learning_system_properties.py +194 -0
- tests/test_learning/test_progress_tracking_properties.py +279 -0
- tests/test_legacy/__init__.py +3 -0
- tests/test_legacy/test_backward_compatibility.py +236 -0
- tests/test_legacy/test_deprecation_warnings.py +208 -0
- tests/test_safe/__init__.py +3 -0
- tests/test_safe/test_collections_properties.py +189 -0
- tests/test_safe/test_files.py +104 -0
- tests/test_structure.py +58 -0
- tests/test_structure_enhancements.py +115 -0
fishertools/helpers.py
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Помощники для частых задач разработки
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import re
|
|
6
|
+
import hashlib
|
|
7
|
+
import random
|
|
8
|
+
import string
|
|
9
|
+
from typing import List, Dict, Any, Optional
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class QuickConfig:
|
|
13
|
+
"""Простой класс для работы с конфигурацией"""
|
|
14
|
+
|
|
15
|
+
def __init__(self, config_dict: Optional[Dict[str, Any]] = None):
|
|
16
|
+
self._config = config_dict or {}
|
|
17
|
+
|
|
18
|
+
def get(self, key: str, default: Any = None) -> Any:
|
|
19
|
+
"""Получить значение по ключу с поддержкой точечной нотации"""
|
|
20
|
+
keys = key.split('.')
|
|
21
|
+
value = self._config
|
|
22
|
+
|
|
23
|
+
for k in keys:
|
|
24
|
+
if isinstance(value, dict) and k in value:
|
|
25
|
+
value = value[k]
|
|
26
|
+
else:
|
|
27
|
+
return default
|
|
28
|
+
|
|
29
|
+
return value
|
|
30
|
+
|
|
31
|
+
def set(self, key: str, value: Any) -> None:
|
|
32
|
+
"""Установить значение по ключу с поддержкой точечной нотации"""
|
|
33
|
+
keys = key.split('.')
|
|
34
|
+
config = self._config
|
|
35
|
+
|
|
36
|
+
for k in keys[:-1]:
|
|
37
|
+
if k not in config:
|
|
38
|
+
config[k] = {}
|
|
39
|
+
config = config[k]
|
|
40
|
+
|
|
41
|
+
config[keys[-1]] = value
|
|
42
|
+
|
|
43
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
44
|
+
"""Вернуть конфигурацию как словарь"""
|
|
45
|
+
return self._config.copy()
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def generate_password(length: int = 12, include_symbols: bool = True) -> str:
|
|
49
|
+
"""Генерирует случайный пароль"""
|
|
50
|
+
chars = string.ascii_letters + string.digits
|
|
51
|
+
if include_symbols:
|
|
52
|
+
chars += "!@#$%^&*"
|
|
53
|
+
|
|
54
|
+
return ''.join(random.choice(chars) for _ in range(length))
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def hash_string(text: str, algorithm: str = 'sha256') -> str:
|
|
58
|
+
"""Хеширует строку указанным алгоритмом"""
|
|
59
|
+
hash_obj = hashlib.new(algorithm)
|
|
60
|
+
hash_obj.update(text.encode('utf-8'))
|
|
61
|
+
return hash_obj.hexdigest()
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def validate_email(email: str) -> bool:
|
|
65
|
+
"""Проверяет корректность email адреса"""
|
|
66
|
+
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
|
|
67
|
+
return bool(re.match(pattern, email))
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def clean_string(text: str) -> str:
|
|
71
|
+
"""Очищает строку от лишних пробелов и символов"""
|
|
72
|
+
# Убираем лишние пробелы
|
|
73
|
+
text = re.sub(r'\s+', ' ', text.strip())
|
|
74
|
+
# Убираем специальные символы (оставляем только буквы, цифры, пробелы и основную пунктуацию)
|
|
75
|
+
text = re.sub(r'[^\w\s.,!?-]', '', text)
|
|
76
|
+
return text
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def chunk_list(lst: List[Any], chunk_size: int) -> List[List[Any]]:
|
|
80
|
+
"""Разбивает список на части заданного размера"""
|
|
81
|
+
return [lst[i:i + chunk_size] for i in range(0, len(lst), chunk_size)]
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def merge_dicts(*dicts: Dict[str, Any]) -> Dict[str, Any]:
|
|
85
|
+
"""Объединяет несколько словарей в один"""
|
|
86
|
+
result = {}
|
|
87
|
+
for d in dicts:
|
|
88
|
+
result.update(d)
|
|
89
|
+
return result
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class SimpleLogger:
|
|
93
|
+
"""Простой логгер для быстрой отладки"""
|
|
94
|
+
|
|
95
|
+
def __init__(self, name: str = "MyDevTools"):
|
|
96
|
+
self.name = name
|
|
97
|
+
|
|
98
|
+
def info(self, message: str) -> None:
|
|
99
|
+
"""Информационное сообщение"""
|
|
100
|
+
print(f"[{self.name}] INFO: {message}")
|
|
101
|
+
|
|
102
|
+
def warning(self, message: str) -> None:
|
|
103
|
+
"""Предупреждение"""
|
|
104
|
+
print(f"[{self.name}] WARNING: {message}")
|
|
105
|
+
|
|
106
|
+
def error(self, message: str) -> None:
|
|
107
|
+
"""Ошибка"""
|
|
108
|
+
print(f"[{self.name}] ERROR: {message}")
|
|
109
|
+
|
|
110
|
+
def debug(self, message: str) -> None:
|
|
111
|
+
"""Отладочное сообщение"""
|
|
112
|
+
print(f"[{self.name}] DEBUG: {message}")
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
# Создаем глобальный экземпляр логгера
|
|
116
|
+
logger = SimpleLogger()
|
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Integration layer for fishertools enhancement components.
|
|
3
|
+
|
|
4
|
+
This module provides the main integration point that connects all enhancement
|
|
5
|
+
components: Learning System, Documentation Generator, Example Repository,
|
|
6
|
+
Visual Documentation, and Configuration Manager.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import Optional, Dict, Any, List
|
|
10
|
+
import logging
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
# Import all enhancement components
|
|
14
|
+
from .learning import LearningSystem, TutorialEngine, ProgressSystem, InteractiveSessionManager
|
|
15
|
+
from .documentation import DocumentationGenerator, VisualDocumentation, APIGenerator
|
|
16
|
+
from .examples import ExampleRepository
|
|
17
|
+
from .config import ConfigurationManager, LearningConfig
|
|
18
|
+
from .errors import FishertoolsError, get_recovery_manager, with_error_recovery
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class FishertoolsIntegration:
|
|
22
|
+
"""
|
|
23
|
+
Main integration class that coordinates all fishertools enhancement components.
|
|
24
|
+
|
|
25
|
+
This class serves as the central hub for all learning, documentation, and
|
|
26
|
+
example management functionality. It handles component initialization,
|
|
27
|
+
configuration management, and inter-component communication.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __init__(self, config_path: Optional[str] = None, project_name: str = "fishertools"):
|
|
31
|
+
"""
|
|
32
|
+
Initialize the fishertools integration system.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
config_path: Optional path to configuration file
|
|
36
|
+
project_name: Name of the project for documentation
|
|
37
|
+
"""
|
|
38
|
+
self.project_name = project_name
|
|
39
|
+
self.config_path = config_path
|
|
40
|
+
|
|
41
|
+
# Initialize error recovery manager
|
|
42
|
+
self.recovery_manager = get_recovery_manager()
|
|
43
|
+
|
|
44
|
+
# Initialize configuration manager first
|
|
45
|
+
self.config_manager = ConfigurationManager(config_path)
|
|
46
|
+
|
|
47
|
+
# Load configuration
|
|
48
|
+
try:
|
|
49
|
+
if config_path and Path(config_path).exists():
|
|
50
|
+
self.config = self.config_manager.load_config(config_path)
|
|
51
|
+
else:
|
|
52
|
+
self.config = self.config_manager.get_default_config()
|
|
53
|
+
except Exception as e:
|
|
54
|
+
logging.warning(f"Failed to load configuration: {e}. Using defaults.")
|
|
55
|
+
self.config = self.config_manager.get_default_config()
|
|
56
|
+
|
|
57
|
+
# Initialize core components
|
|
58
|
+
self._initialize_components()
|
|
59
|
+
|
|
60
|
+
# Set up component integrations
|
|
61
|
+
self._setup_integrations()
|
|
62
|
+
|
|
63
|
+
def _initialize_components(self) -> None:
|
|
64
|
+
"""Initialize all enhancement components."""
|
|
65
|
+
try:
|
|
66
|
+
# Learning System components
|
|
67
|
+
self.learning_system = LearningSystem(self.config_path)
|
|
68
|
+
self.tutorial_engine = TutorialEngine()
|
|
69
|
+
self.progress_system = ProgressSystem()
|
|
70
|
+
self.session_manager = InteractiveSessionManager()
|
|
71
|
+
|
|
72
|
+
# Documentation components
|
|
73
|
+
self.doc_generator = DocumentationGenerator(
|
|
74
|
+
project_name=self.project_name,
|
|
75
|
+
output_dir=getattr(self.config, 'docs_output_dir', 'docs')
|
|
76
|
+
)
|
|
77
|
+
self.visual_docs = VisualDocumentation()
|
|
78
|
+
self.api_generator = APIGenerator()
|
|
79
|
+
|
|
80
|
+
# Example management
|
|
81
|
+
self.example_repository = ExampleRepository()
|
|
82
|
+
|
|
83
|
+
logging.info("All fishertools components initialized successfully")
|
|
84
|
+
|
|
85
|
+
except Exception as e:
|
|
86
|
+
# Use error recovery for component initialization failures
|
|
87
|
+
recovery_action = self.recovery_manager.handle_config_error(e, "integration")
|
|
88
|
+
|
|
89
|
+
if recovery_action.strategy.value == "graceful_degradation":
|
|
90
|
+
# Initialize with minimal components
|
|
91
|
+
self._initialize_minimal_components()
|
|
92
|
+
logging.warning("Initialized with minimal components due to errors")
|
|
93
|
+
else:
|
|
94
|
+
logging.error(f"Failed to initialize components: {e}")
|
|
95
|
+
raise FishertoolsError(f"Component initialization failed: {e}")
|
|
96
|
+
|
|
97
|
+
def _initialize_minimal_components(self) -> None:
|
|
98
|
+
"""Initialize minimal components for graceful degradation."""
|
|
99
|
+
try:
|
|
100
|
+
# Only initialize essential components
|
|
101
|
+
self.learning_system = LearningSystem()
|
|
102
|
+
self.example_repository = ExampleRepository()
|
|
103
|
+
|
|
104
|
+
# Set others to None for graceful handling
|
|
105
|
+
self.tutorial_engine = None
|
|
106
|
+
self.progress_system = None
|
|
107
|
+
self.session_manager = None
|
|
108
|
+
self.doc_generator = None
|
|
109
|
+
self.visual_docs = None
|
|
110
|
+
self.api_generator = None
|
|
111
|
+
|
|
112
|
+
except Exception as e:
|
|
113
|
+
logging.critical(f"Failed to initialize even minimal components: {e}")
|
|
114
|
+
raise FishertoolsError(f"Critical initialization failure: {e}")
|
|
115
|
+
|
|
116
|
+
def _setup_integrations(self) -> None:
|
|
117
|
+
"""Set up integrations between components."""
|
|
118
|
+
try:
|
|
119
|
+
# Connect Learning System with Tutorial Engine
|
|
120
|
+
self.learning_system._tutorial_engine = self.tutorial_engine
|
|
121
|
+
self.learning_system._progress_system = self.progress_system
|
|
122
|
+
self.learning_system._session_manager = self.session_manager
|
|
123
|
+
|
|
124
|
+
# Connect Tutorial Engine with Example Repository
|
|
125
|
+
self.tutorial_engine._example_repository = self.example_repository
|
|
126
|
+
|
|
127
|
+
# Connect Documentation Generator with Visual Documentation
|
|
128
|
+
self.doc_generator._visual_docs = self.visual_docs
|
|
129
|
+
|
|
130
|
+
# Connect Session Manager with Example Repository
|
|
131
|
+
self.session_manager._example_repository = self.example_repository
|
|
132
|
+
self.session_manager._tutorial_engine = self.tutorial_engine
|
|
133
|
+
|
|
134
|
+
logging.info("Component integrations set up successfully")
|
|
135
|
+
|
|
136
|
+
except Exception as e:
|
|
137
|
+
logging.error(f"Failed to set up integrations: {e}")
|
|
138
|
+
raise FishertoolsError(f"Integration setup failed: {e}")
|
|
139
|
+
|
|
140
|
+
@with_error_recovery("integration", "start_learning_session", "session_error")
|
|
141
|
+
def start_learning_session(self, topic: str, level: str = "beginner", user_id: Optional[str] = None):
|
|
142
|
+
"""
|
|
143
|
+
Start a comprehensive learning session that integrates all components.
|
|
144
|
+
|
|
145
|
+
Args:
|
|
146
|
+
topic: Topic to learn
|
|
147
|
+
level: Difficulty level
|
|
148
|
+
user_id: Optional user identifier for progress tracking
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
Integrated learning session with examples, tutorials, and progress tracking
|
|
152
|
+
"""
|
|
153
|
+
try:
|
|
154
|
+
# Start tutorial session
|
|
155
|
+
tutorial_session = self.learning_system.start_tutorial(topic, level)
|
|
156
|
+
|
|
157
|
+
# Get relevant examples from repository if available
|
|
158
|
+
if self.example_repository:
|
|
159
|
+
examples = self.example_repository.get_examples_by_topic(topic)
|
|
160
|
+
|
|
161
|
+
# Create interactive session if examples are available and session manager exists
|
|
162
|
+
if examples and self.session_manager:
|
|
163
|
+
interactive_session = self.session_manager.create_session(
|
|
164
|
+
user_id or "anonymous",
|
|
165
|
+
examples[0] # Start with first example
|
|
166
|
+
)
|
|
167
|
+
tutorial_session.interactive_session = interactive_session
|
|
168
|
+
|
|
169
|
+
# Track progress if user_id provided and progress system available
|
|
170
|
+
if user_id and self.progress_system:
|
|
171
|
+
self.learning_system.track_progress(user_id, topic, False) # Mark as started
|
|
172
|
+
|
|
173
|
+
return tutorial_session
|
|
174
|
+
|
|
175
|
+
except Exception as e:
|
|
176
|
+
# Graceful degradation - provide basic tutorial without interactive features
|
|
177
|
+
logging.warning(f"Failed to create full learning session: {e}")
|
|
178
|
+
|
|
179
|
+
if self.learning_system:
|
|
180
|
+
try:
|
|
181
|
+
return self.learning_system.start_tutorial(topic, level)
|
|
182
|
+
except Exception as basic_error:
|
|
183
|
+
logging.error(f"Failed to start even basic tutorial: {basic_error}")
|
|
184
|
+
raise FishertoolsError(f"Learning session failed: {basic_error}")
|
|
185
|
+
else:
|
|
186
|
+
raise FishertoolsError(f"Learning system unavailable: {e}")
|
|
187
|
+
|
|
188
|
+
@with_error_recovery("integration", "generate_documentation", "documentation_error")
|
|
189
|
+
def generate_comprehensive_documentation(self, module_paths: List[str]) -> Dict[str, Any]:
|
|
190
|
+
"""
|
|
191
|
+
Generate comprehensive documentation with visual elements.
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
module_paths: List of module paths to document
|
|
195
|
+
|
|
196
|
+
Returns:
|
|
197
|
+
Dictionary containing all generated documentation artifacts
|
|
198
|
+
"""
|
|
199
|
+
try:
|
|
200
|
+
# Generate API documentation
|
|
201
|
+
sphinx_docs = self.doc_generator.build_documentation(module_paths)
|
|
202
|
+
|
|
203
|
+
# Generate visual documentation for each module
|
|
204
|
+
visual_artifacts = {}
|
|
205
|
+
for module_path in module_paths:
|
|
206
|
+
api_info = self.doc_generator.extract_api_info(module_path)
|
|
207
|
+
|
|
208
|
+
# Create architecture diagram
|
|
209
|
+
arch_diagram = self.visual_docs.create_architecture_diagram([api_info.module_name])
|
|
210
|
+
visual_artifacts[f"{api_info.module_name}_architecture"] = arch_diagram
|
|
211
|
+
|
|
212
|
+
# Create data flow diagrams for functions
|
|
213
|
+
for func_info in api_info.functions:
|
|
214
|
+
flow_diagram = self.visual_docs.generate_data_flow_diagram(func_info)
|
|
215
|
+
visual_artifacts[f"{func_info.name}_flow"] = flow_diagram
|
|
216
|
+
|
|
217
|
+
# Publish to ReadTheDocs
|
|
218
|
+
publish_result = self.doc_generator.publish_to_readthedocs(sphinx_docs)
|
|
219
|
+
|
|
220
|
+
return {
|
|
221
|
+
'sphinx_docs': sphinx_docs,
|
|
222
|
+
'visual_artifacts': visual_artifacts,
|
|
223
|
+
'publish_result': publish_result
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
except Exception as e:
|
|
227
|
+
logging.error(f"Failed to generate documentation: {e}")
|
|
228
|
+
raise FishertoolsError(f"Documentation generation failed: {e}")
|
|
229
|
+
|
|
230
|
+
def get_learning_recommendations(self, user_id: str, current_topic: Optional[str] = None) -> Dict[str, Any]:
|
|
231
|
+
"""
|
|
232
|
+
Get personalized learning recommendations based on user progress.
|
|
233
|
+
|
|
234
|
+
Args:
|
|
235
|
+
user_id: User identifier
|
|
236
|
+
current_topic: Optional current topic being studied
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
Dictionary with recommendations including next topics, examples, and exercises
|
|
240
|
+
"""
|
|
241
|
+
try:
|
|
242
|
+
# Get user progress
|
|
243
|
+
progress = self.learning_system.get_user_progress(user_id)
|
|
244
|
+
|
|
245
|
+
recommendations = {
|
|
246
|
+
'next_topics': [],
|
|
247
|
+
'recommended_examples': [],
|
|
248
|
+
'suggested_exercises': [],
|
|
249
|
+
'progress_summary': None
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if progress:
|
|
253
|
+
recommendations['progress_summary'] = {
|
|
254
|
+
'completed_topics': progress.completed_topics,
|
|
255
|
+
'current_level': progress.current_level.value,
|
|
256
|
+
'total_exercises': progress.total_exercises_completed
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
# Get next topic recommendations
|
|
260
|
+
if current_topic:
|
|
261
|
+
related_topics = self.learning_system.suggest_related_topics(current_topic)
|
|
262
|
+
# Filter out already completed topics
|
|
263
|
+
next_topics = [
|
|
264
|
+
topic for topic in related_topics
|
|
265
|
+
if topic not in progress.completed_topics
|
|
266
|
+
]
|
|
267
|
+
recommendations['next_topics'] = next_topics[:3] # Top 3 recommendations
|
|
268
|
+
|
|
269
|
+
# Get examples for recommended topics
|
|
270
|
+
for topic in recommendations['next_topics']:
|
|
271
|
+
examples = self.example_repository.get_examples_by_topic(topic)
|
|
272
|
+
recommendations['recommended_examples'].extend(examples[:2]) # 2 per topic
|
|
273
|
+
|
|
274
|
+
return recommendations
|
|
275
|
+
|
|
276
|
+
except Exception as e:
|
|
277
|
+
logging.error(f"Failed to get recommendations: {e}")
|
|
278
|
+
return {
|
|
279
|
+
'next_topics': [],
|
|
280
|
+
'recommended_examples': [],
|
|
281
|
+
'suggested_exercises': [],
|
|
282
|
+
'progress_summary': None,
|
|
283
|
+
'error': str(e)
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
def explain_code_with_examples(self, code: str, include_visuals: bool = True) -> Dict[str, Any]:
|
|
287
|
+
"""
|
|
288
|
+
Provide comprehensive code explanation with examples and visual aids.
|
|
289
|
+
|
|
290
|
+
Args:
|
|
291
|
+
code: Code to explain
|
|
292
|
+
include_visuals: Whether to include visual diagrams
|
|
293
|
+
|
|
294
|
+
Returns:
|
|
295
|
+
Dictionary with step-by-step explanation, related examples, and visual aids
|
|
296
|
+
"""
|
|
297
|
+
try:
|
|
298
|
+
# Get step-by-step explanation
|
|
299
|
+
explanations = self.learning_system.get_step_by_step_explanation(code)
|
|
300
|
+
|
|
301
|
+
# Find related examples based on concepts in the code
|
|
302
|
+
related_examples = []
|
|
303
|
+
concepts = set()
|
|
304
|
+
for explanation in explanations:
|
|
305
|
+
concepts.update(explanation.related_concepts)
|
|
306
|
+
|
|
307
|
+
# Search for examples covering these concepts
|
|
308
|
+
for concept in concepts:
|
|
309
|
+
examples = self.example_repository.search_examples(concept)
|
|
310
|
+
related_examples.extend(examples[:2]) # Limit to avoid overwhelming
|
|
311
|
+
|
|
312
|
+
result = {
|
|
313
|
+
'step_explanations': explanations,
|
|
314
|
+
'related_examples': related_examples,
|
|
315
|
+
'concepts_covered': list(concepts)
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
# Add visual aids if requested
|
|
319
|
+
if include_visuals and explanations:
|
|
320
|
+
try:
|
|
321
|
+
# Create a simple flowchart for the code structure
|
|
322
|
+
flowchart = self.visual_docs.create_algorithm_flowchart(code)
|
|
323
|
+
result['flowchart'] = flowchart
|
|
324
|
+
except Exception as e:
|
|
325
|
+
logging.warning(f"Failed to create flowchart: {e}")
|
|
326
|
+
|
|
327
|
+
return result
|
|
328
|
+
|
|
329
|
+
except Exception as e:
|
|
330
|
+
logging.error(f"Failed to explain code: {e}")
|
|
331
|
+
raise FishertoolsError(f"Code explanation failed: {e}")
|
|
332
|
+
|
|
333
|
+
def update_configuration(self, new_config: Dict[str, Any]) -> None:
|
|
334
|
+
"""
|
|
335
|
+
Update system configuration and apply changes to all components.
|
|
336
|
+
|
|
337
|
+
Args:
|
|
338
|
+
new_config: New configuration values
|
|
339
|
+
"""
|
|
340
|
+
try:
|
|
341
|
+
# Merge with current configuration
|
|
342
|
+
updated_config = self.config_manager.merge_configs(self.config, new_config)
|
|
343
|
+
|
|
344
|
+
# Validate the new configuration
|
|
345
|
+
validation_result = self.config_manager.validate_config(updated_config)
|
|
346
|
+
if not validation_result.is_valid:
|
|
347
|
+
error_messages = [error.message for error in validation_result.errors]
|
|
348
|
+
raise ValueError(f"Invalid configuration: {'; '.join(error_messages)}")
|
|
349
|
+
|
|
350
|
+
# Apply the configuration
|
|
351
|
+
self.config_manager.apply_config(updated_config)
|
|
352
|
+
self.config = updated_config
|
|
353
|
+
|
|
354
|
+
# Update components with new configuration
|
|
355
|
+
self._apply_config_to_components()
|
|
356
|
+
|
|
357
|
+
logging.info("Configuration updated successfully")
|
|
358
|
+
|
|
359
|
+
except Exception as e:
|
|
360
|
+
logging.error(f"Failed to update configuration: {e}")
|
|
361
|
+
raise FishertoolsError(f"Configuration update failed: {e}")
|
|
362
|
+
|
|
363
|
+
def _apply_config_to_components(self) -> None:
|
|
364
|
+
"""Apply current configuration to all components."""
|
|
365
|
+
try:
|
|
366
|
+
# Apply configuration to learning system
|
|
367
|
+
if hasattr(self.config, 'default_level'):
|
|
368
|
+
# Update default difficulty level in learning system
|
|
369
|
+
pass # Implementation depends on specific config options
|
|
370
|
+
|
|
371
|
+
# Apply configuration to documentation generator
|
|
372
|
+
if hasattr(self.config, 'docs_output_dir'):
|
|
373
|
+
self.doc_generator.output_dir = self.config.docs_output_dir
|
|
374
|
+
|
|
375
|
+
# Apply other configuration options as needed
|
|
376
|
+
|
|
377
|
+
except Exception as e:
|
|
378
|
+
logging.warning(f"Some configuration options could not be applied: {e}")
|
|
379
|
+
|
|
380
|
+
def get_system_status(self) -> Dict[str, Any]:
|
|
381
|
+
"""
|
|
382
|
+
Get the current status of all system components.
|
|
383
|
+
|
|
384
|
+
Returns:
|
|
385
|
+
Dictionary with status information for each component
|
|
386
|
+
"""
|
|
387
|
+
status = {
|
|
388
|
+
'learning_system': 'initialized' if self.learning_system else 'failed',
|
|
389
|
+
'documentation_generator': 'initialized' if self.doc_generator else 'failed',
|
|
390
|
+
'example_repository': 'initialized' if self.example_repository else 'failed',
|
|
391
|
+
'visual_documentation': 'initialized' if self.visual_docs else 'failed',
|
|
392
|
+
'configuration_manager': 'initialized' if self.config_manager else 'failed',
|
|
393
|
+
'current_config': self.config.__dict__ if self.config else None,
|
|
394
|
+
'total_examples': len(self.example_repository._examples) if self.example_repository else 0
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
return status
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
# Global integration instance for easy access
|
|
401
|
+
_integration_instance: Optional[FishertoolsIntegration] = None
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
def get_integration(config_path: Optional[str] = None, project_name: str = "fishertools") -> FishertoolsIntegration:
|
|
405
|
+
"""
|
|
406
|
+
Get or create the global fishertools integration instance.
|
|
407
|
+
|
|
408
|
+
Args:
|
|
409
|
+
config_path: Optional path to configuration file
|
|
410
|
+
project_name: Name of the project
|
|
411
|
+
|
|
412
|
+
Returns:
|
|
413
|
+
FishertoolsIntegration: The global integration instance
|
|
414
|
+
"""
|
|
415
|
+
global _integration_instance
|
|
416
|
+
|
|
417
|
+
if _integration_instance is None:
|
|
418
|
+
_integration_instance = FishertoolsIntegration(config_path, project_name)
|
|
419
|
+
|
|
420
|
+
return _integration_instance
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
def reset_integration() -> None:
|
|
424
|
+
"""Reset the global integration instance."""
|
|
425
|
+
global _integration_instance
|
|
426
|
+
_integration_instance = None
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
# Convenience functions for common operations
|
|
430
|
+
def start_learning(topic: str, level: str = "beginner", user_id: Optional[str] = None):
|
|
431
|
+
"""Convenience function to start a learning session."""
|
|
432
|
+
integration = get_integration()
|
|
433
|
+
return integration.start_learning_session(topic, level, user_id)
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
def explain_code(code: str, include_visuals: bool = True):
|
|
437
|
+
"""Convenience function to explain code with examples."""
|
|
438
|
+
integration = get_integration()
|
|
439
|
+
return integration.explain_code_with_examples(code, include_visuals)
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
def generate_docs(module_paths: List[str]):
|
|
443
|
+
"""Convenience function to generate comprehensive documentation."""
|
|
444
|
+
integration = get_integration()
|
|
445
|
+
return integration.generate_comprehensive_documentation(module_paths)
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
def get_recommendations(user_id: str, current_topic: Optional[str] = None):
|
|
449
|
+
"""Convenience function to get learning recommendations."""
|
|
450
|
+
integration = get_integration()
|
|
451
|
+
return integration.get_learning_recommendations(user_id, current_topic)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Learning tools module for fishertools.
|
|
3
|
+
|
|
4
|
+
This module provides educational utilities that help beginners
|
|
5
|
+
learn Python best practices and concepts.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .examples import generate_example, list_available_concepts, get_concept_info
|
|
9
|
+
from .tips import show_best_practice, list_available_topics, get_topic_summary
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"generate_example",
|
|
13
|
+
"list_available_concepts",
|
|
14
|
+
"get_concept_info",
|
|
15
|
+
"show_best_practice",
|
|
16
|
+
"list_available_topics",
|
|
17
|
+
"get_topic_summary"
|
|
18
|
+
]
|