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
|
@@ -0,0 +1,550 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Code example generation for learning.
|
|
3
|
+
|
|
4
|
+
This module contains functions to generate educational code examples
|
|
5
|
+
for common Python concepts that beginners need to learn.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Dict, Optional
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# Database of code examples for different Python concepts
|
|
12
|
+
CODE_EXAMPLES: Dict[str, Dict[str, str]] = {
|
|
13
|
+
"variables": {
|
|
14
|
+
"title": "Переменные и типы данных",
|
|
15
|
+
"description": "Основы работы с переменными в Python",
|
|
16
|
+
"code": '''# Основные типы данных в Python
|
|
17
|
+
|
|
18
|
+
# Строки (str)
|
|
19
|
+
name = "Анна"
|
|
20
|
+
message = 'Привет, мир!'
|
|
21
|
+
multiline = """Это многострочная
|
|
22
|
+
строка в Python"""
|
|
23
|
+
|
|
24
|
+
# Числа
|
|
25
|
+
age = 25 # Целое число (int)
|
|
26
|
+
height = 1.75 # Число с плавающей точкой (float)
|
|
27
|
+
temperature = -5.5 # Отрицательное число
|
|
28
|
+
|
|
29
|
+
# Логические значения (bool)
|
|
30
|
+
is_student = True
|
|
31
|
+
is_working = False
|
|
32
|
+
|
|
33
|
+
# Вывод информации о переменных
|
|
34
|
+
print(f"Имя: {name}, тип: {type(name)}")
|
|
35
|
+
print(f"Возраст: {age}, тип: {type(age)}")
|
|
36
|
+
print(f"Рост: {height}, тип: {type(height)}")
|
|
37
|
+
print(f"Студент: {is_student}, тип: {type(is_student)}")
|
|
38
|
+
|
|
39
|
+
# Преобразование типов
|
|
40
|
+
age_str = str(age) # Число в строку
|
|
41
|
+
height_int = int(height) # Дробное в целое (обрезает дробную часть)
|
|
42
|
+
number_from_str = int("42") # Строка в число
|
|
43
|
+
|
|
44
|
+
print(f"Возраст как строка: '{age_str}'")
|
|
45
|
+
print(f"Рост как целое: {height_int}")
|
|
46
|
+
print(f"Число из строки: {number_from_str}")'''
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
"lists": {
|
|
50
|
+
"title": "Списки и операции с ними",
|
|
51
|
+
"description": "Работа со списками - основной структурой данных Python",
|
|
52
|
+
"code": '''# Создание и работа со списками
|
|
53
|
+
|
|
54
|
+
# Создание списков
|
|
55
|
+
fruits = ["яблоко", "банан", "апельсин"]
|
|
56
|
+
numbers = [1, 2, 3, 4, 5]
|
|
57
|
+
mixed_list = ["текст", 42, True, 3.14]
|
|
58
|
+
empty_list = []
|
|
59
|
+
|
|
60
|
+
print("Исходный список фруктов:", fruits)
|
|
61
|
+
|
|
62
|
+
# Доступ к элементам (индексация начинается с 0)
|
|
63
|
+
first_fruit = fruits[0] # Первый элемент
|
|
64
|
+
last_fruit = fruits[-1] # Последний элемент
|
|
65
|
+
print(f"Первый фрукт: {first_fruit}")
|
|
66
|
+
print(f"Последний фрукт: {last_fruit}")
|
|
67
|
+
|
|
68
|
+
# Добавление элементов
|
|
69
|
+
fruits.append("груша") # Добавить в конец
|
|
70
|
+
fruits.insert(1, "киви") # Вставить на позицию 1
|
|
71
|
+
print("После добавления:", fruits)
|
|
72
|
+
|
|
73
|
+
# Удаление элементов
|
|
74
|
+
fruits.remove("банан") # Удалить по значению
|
|
75
|
+
removed_fruit = fruits.pop() # Удалить и вернуть последний элемент
|
|
76
|
+
print(f"Удален фрукт: {removed_fruit}")
|
|
77
|
+
print("После удаления:", fruits)
|
|
78
|
+
|
|
79
|
+
# Полезные операции
|
|
80
|
+
print(f"Количество фруктов: {len(fruits)}")
|
|
81
|
+
print(f"Есть ли яблоко: {'яблоко' in fruits}")
|
|
82
|
+
|
|
83
|
+
# Срезы (slicing)
|
|
84
|
+
first_two = fruits[:2] # Первые два элемента
|
|
85
|
+
last_two = fruits[-2:] # Последние два элемента
|
|
86
|
+
print(f"Первые два: {first_two}")
|
|
87
|
+
print(f"Последние два: {last_two}")
|
|
88
|
+
|
|
89
|
+
# Итерация по списку
|
|
90
|
+
print("Все фрукты:")
|
|
91
|
+
for i, fruit in enumerate(fruits):
|
|
92
|
+
print(f"{i + 1}. {fruit}")'''
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
"dictionaries": {
|
|
96
|
+
"title": "Словари для хранения данных",
|
|
97
|
+
"description": "Словари позволяют хранить данные в формате ключ-значение",
|
|
98
|
+
"code": '''# Создание и работа со словарями
|
|
99
|
+
|
|
100
|
+
# Создание словаря
|
|
101
|
+
student = {
|
|
102
|
+
"name": "Алексей",
|
|
103
|
+
"age": 20,
|
|
104
|
+
"course": 2,
|
|
105
|
+
"subjects": ["математика", "физика", "программирование"]
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
print("Информация о студенте:")
|
|
109
|
+
print(student)
|
|
110
|
+
|
|
111
|
+
# Доступ к значениям
|
|
112
|
+
student_name = student["name"] # Прямой доступ
|
|
113
|
+
student_age = student.get("age", 0) # Безопасный доступ с значением по умолчанию
|
|
114
|
+
student_gpa = student.get("gpa") # Вернет None, если ключа нет
|
|
115
|
+
|
|
116
|
+
print(f"Имя: {student_name}")
|
|
117
|
+
print(f"Возраст: {student_age}")
|
|
118
|
+
print(f"Средний балл: {student_gpa or 'не указан'}")
|
|
119
|
+
|
|
120
|
+
# Добавление и изменение данных
|
|
121
|
+
student["gpa"] = 4.5 # Добавить новый ключ
|
|
122
|
+
student["age"] = 21 # Изменить существующий
|
|
123
|
+
student["subjects"].append("английский") # Изменить список внутри словаря
|
|
124
|
+
|
|
125
|
+
print("\\nОбновленная информация:")
|
|
126
|
+
print(student)
|
|
127
|
+
|
|
128
|
+
# Проверка наличия ключей
|
|
129
|
+
if "email" in student:
|
|
130
|
+
print(f"Email: {student['email']}")
|
|
131
|
+
else:
|
|
132
|
+
print("Email не указан")
|
|
133
|
+
|
|
134
|
+
# Итерация по словарю
|
|
135
|
+
print("\\nВся информация о студенте:")
|
|
136
|
+
for key, value in student.items():
|
|
137
|
+
if key == "subjects":
|
|
138
|
+
print(f"{key}: {', '.join(value)}")
|
|
139
|
+
else:
|
|
140
|
+
print(f"{key}: {value}")
|
|
141
|
+
|
|
142
|
+
# Получение всех ключей и значений
|
|
143
|
+
all_keys = list(student.keys())
|
|
144
|
+
all_values = list(student.values())
|
|
145
|
+
print(f"\\nВсе ключи: {all_keys}")
|
|
146
|
+
print(f"Количество полей: {len(student)}")'''
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
"functions": {
|
|
150
|
+
"title": "Функции для организации кода",
|
|
151
|
+
"description": "Функции помогают организовать код и избежать повторений",
|
|
152
|
+
"code": '''# Определение и использование функций
|
|
153
|
+
|
|
154
|
+
def greet(name):
|
|
155
|
+
"""Простая функция приветствия."""
|
|
156
|
+
return f"Привет, {name}!"
|
|
157
|
+
|
|
158
|
+
def calculate_area(length, width):
|
|
159
|
+
"""Вычисляет площадь прямоугольника."""
|
|
160
|
+
area = length * width
|
|
161
|
+
return area
|
|
162
|
+
|
|
163
|
+
def create_user_profile(name, age, city="Не указан"):
|
|
164
|
+
"""
|
|
165
|
+
Создает профиль пользователя.
|
|
166
|
+
|
|
167
|
+
Args:
|
|
168
|
+
name: Имя пользователя
|
|
169
|
+
age: Возраст пользователя
|
|
170
|
+
city: Город (необязательный параметр)
|
|
171
|
+
|
|
172
|
+
Returns:
|
|
173
|
+
Словарь с информацией о пользователе
|
|
174
|
+
"""
|
|
175
|
+
profile = {
|
|
176
|
+
"name": name,
|
|
177
|
+
"age": age,
|
|
178
|
+
"city": city,
|
|
179
|
+
"is_adult": age >= 18
|
|
180
|
+
}
|
|
181
|
+
return profile
|
|
182
|
+
|
|
183
|
+
# Использование функций
|
|
184
|
+
print(greet("Мария"))
|
|
185
|
+
|
|
186
|
+
room_area = calculate_area(5, 4)
|
|
187
|
+
print(f"Площадь комнаты: {room_area} кв.м")
|
|
188
|
+
|
|
189
|
+
# Создание профилей пользователей
|
|
190
|
+
user1 = create_user_profile("Иван", 25, "Москва")
|
|
191
|
+
user2 = create_user_profile("Анна", 17) # Город не указан
|
|
192
|
+
|
|
193
|
+
print("\\nПрофиль пользователя 1:")
|
|
194
|
+
for key, value in user1.items():
|
|
195
|
+
print(f" {key}: {value}")
|
|
196
|
+
|
|
197
|
+
print("\\nПрофиль пользователя 2:")
|
|
198
|
+
for key, value in user2.items():
|
|
199
|
+
print(f" {key}: {value}")
|
|
200
|
+
|
|
201
|
+
# Функция с несколькими возвращаемыми значениями
|
|
202
|
+
def get_name_parts(full_name):
|
|
203
|
+
"""Разделяет полное имя на части."""
|
|
204
|
+
parts = full_name.split()
|
|
205
|
+
first_name = parts[0] if len(parts) > 0 else ""
|
|
206
|
+
last_name = parts[-1] if len(parts) > 1 else ""
|
|
207
|
+
return first_name, last_name
|
|
208
|
+
|
|
209
|
+
first, last = get_name_parts("Петр Иванович Сидоров")
|
|
210
|
+
print(f"\\nИмя: {first}, Фамилия: {last}")'''
|
|
211
|
+
},
|
|
212
|
+
|
|
213
|
+
"loops": {
|
|
214
|
+
"title": "Циклы для повторения действий",
|
|
215
|
+
"description": "Циклы позволяют выполнять код многократно",
|
|
216
|
+
"code": '''# Различные виды циклов в Python
|
|
217
|
+
|
|
218
|
+
# Цикл for для итерации по последовательности
|
|
219
|
+
print("=== Цикл FOR ===")
|
|
220
|
+
|
|
221
|
+
# Итерация по списку
|
|
222
|
+
colors = ["красный", "зеленый", "синий"]
|
|
223
|
+
print("Цвета:")
|
|
224
|
+
for color in colors:
|
|
225
|
+
print(f" - {color}")
|
|
226
|
+
|
|
227
|
+
# Итерация по строке
|
|
228
|
+
word = "Python"
|
|
229
|
+
print(f"\\nБуквы в слове '{word}':")
|
|
230
|
+
for letter in word:
|
|
231
|
+
print(f" {letter}")
|
|
232
|
+
|
|
233
|
+
# Использование range() для числовых последовательностей
|
|
234
|
+
print("\\nЧисла от 1 до 5:")
|
|
235
|
+
for i in range(1, 6):
|
|
236
|
+
print(f" Число: {i}")
|
|
237
|
+
|
|
238
|
+
# Enumerate для получения индекса и значения
|
|
239
|
+
print("\\nЦвета с номерами:")
|
|
240
|
+
for index, color in enumerate(colors, 1):
|
|
241
|
+
print(f" {index}. {color}")
|
|
242
|
+
|
|
243
|
+
# Цикл while для повторения пока условие истинно
|
|
244
|
+
print("\\n=== Цикл WHILE ===")
|
|
245
|
+
|
|
246
|
+
count = 0
|
|
247
|
+
print("Обратный отсчет:")
|
|
248
|
+
while count < 5:
|
|
249
|
+
print(f" {5 - count}")
|
|
250
|
+
count += 1
|
|
251
|
+
print(" Пуск!")
|
|
252
|
+
|
|
253
|
+
# Практический пример: поиск в списке
|
|
254
|
+
numbers = [2, 7, 1, 8, 3, 9, 4]
|
|
255
|
+
target = 8
|
|
256
|
+
found_index = -1
|
|
257
|
+
|
|
258
|
+
print(f"\\nПоиск числа {target} в списке {numbers}:")
|
|
259
|
+
for i, number in enumerate(numbers):
|
|
260
|
+
if number == target:
|
|
261
|
+
found_index = i
|
|
262
|
+
break # Прерываем цикл при нахождении
|
|
263
|
+
|
|
264
|
+
if found_index != -1:
|
|
265
|
+
print(f" Число {target} найдено на позиции {found_index}")
|
|
266
|
+
else:
|
|
267
|
+
print(f" Число {target} не найдено")
|
|
268
|
+
|
|
269
|
+
# Вложенные циклы
|
|
270
|
+
print("\\n=== Вложенные циклы ===")
|
|
271
|
+
print("Таблица умножения 3x3:")
|
|
272
|
+
for i in range(1, 4):
|
|
273
|
+
for j in range(1, 4):
|
|
274
|
+
result = i * j
|
|
275
|
+
print(f" {i} × {j} = {result}")
|
|
276
|
+
print() # Пустая строка после каждой строки таблицы'''
|
|
277
|
+
},
|
|
278
|
+
|
|
279
|
+
"conditionals": {
|
|
280
|
+
"title": "Условные конструкции",
|
|
281
|
+
"description": "Условия позволяют выполнять разный код в зависимости от ситуации",
|
|
282
|
+
"code": '''# Условные конструкции в Python
|
|
283
|
+
|
|
284
|
+
# Простое условие if
|
|
285
|
+
age = 18
|
|
286
|
+
print("=== Простые условия ===")
|
|
287
|
+
|
|
288
|
+
if age >= 18:
|
|
289
|
+
print("Вы совершеннолетний")
|
|
290
|
+
else:
|
|
291
|
+
print("Вы несовершеннолетний")
|
|
292
|
+
|
|
293
|
+
# Множественные условия if-elif-else
|
|
294
|
+
score = 85
|
|
295
|
+
print(f"\\nОценка за тест: {score}")
|
|
296
|
+
|
|
297
|
+
if score >= 90:
|
|
298
|
+
grade = "Отлично"
|
|
299
|
+
elif score >= 80:
|
|
300
|
+
grade = "Хорошо"
|
|
301
|
+
elif score >= 70:
|
|
302
|
+
grade = "Удовлетворительно"
|
|
303
|
+
else:
|
|
304
|
+
grade = "Неудовлетворительно"
|
|
305
|
+
|
|
306
|
+
print(f"Результат: {grade}")
|
|
307
|
+
|
|
308
|
+
# Логические операторы
|
|
309
|
+
temperature = 22
|
|
310
|
+
is_sunny = True
|
|
311
|
+
print(f"\\nТемпература: {temperature}°C, Солнечно: {is_sunny}")
|
|
312
|
+
|
|
313
|
+
if temperature > 20 and is_sunny:
|
|
314
|
+
print("Отличная погода для прогулки!")
|
|
315
|
+
elif temperature > 20 or is_sunny:
|
|
316
|
+
print("Неплохая погода")
|
|
317
|
+
else:
|
|
318
|
+
print("Лучше остаться дома")
|
|
319
|
+
|
|
320
|
+
# Проверка принадлежности
|
|
321
|
+
fruits = ["яблоко", "банан", "апельсин"]
|
|
322
|
+
user_choice = "банан"
|
|
323
|
+
|
|
324
|
+
if user_choice in fruits:
|
|
325
|
+
print(f"\\n{user_choice} есть в наличии")
|
|
326
|
+
else:
|
|
327
|
+
print(f"\\n{user_choice} нет в наличии")
|
|
328
|
+
|
|
329
|
+
# Проверка типа данных
|
|
330
|
+
value = "123"
|
|
331
|
+
print(f"\\nЗначение: '{value}'")
|
|
332
|
+
|
|
333
|
+
if isinstance(value, str):
|
|
334
|
+
if value.isdigit():
|
|
335
|
+
number = int(value)
|
|
336
|
+
print(f"Это строка с числом: {number}")
|
|
337
|
+
else:
|
|
338
|
+
print("Это обычная строка")
|
|
339
|
+
elif isinstance(value, int):
|
|
340
|
+
print("Это целое число")
|
|
341
|
+
else:
|
|
342
|
+
print("Это что-то другое")
|
|
343
|
+
|
|
344
|
+
# Тернарный оператор (краткая форма if-else)
|
|
345
|
+
number = 7
|
|
346
|
+
result = "четное" if number % 2 == 0 else "нечетное"
|
|
347
|
+
print(f"\\nЧисло {number} - {result}")
|
|
348
|
+
|
|
349
|
+
# Практический пример: валидация пользовательского ввода
|
|
350
|
+
username = "user123"
|
|
351
|
+
password = "mypassword"
|
|
352
|
+
|
|
353
|
+
print(f"\\nПроверка данных пользователя:")
|
|
354
|
+
print(f"Логин: {username}")
|
|
355
|
+
|
|
356
|
+
# Проверка логина
|
|
357
|
+
if len(username) < 3:
|
|
358
|
+
print("❌ Логин слишком короткий (минимум 3 символа)")
|
|
359
|
+
elif len(username) > 20:
|
|
360
|
+
print("❌ Логин слишком длинный (максимум 20 символов)")
|
|
361
|
+
elif not username.isalnum():
|
|
362
|
+
print("❌ Логин должен содержать только буквы и цифры")
|
|
363
|
+
else:
|
|
364
|
+
print("✅ Логин корректный")
|
|
365
|
+
|
|
366
|
+
# Проверка пароля
|
|
367
|
+
if len(password) < 8:
|
|
368
|
+
print("❌ Пароль слишком короткий (минимум 8 символов)")
|
|
369
|
+
elif password.lower() == password:
|
|
370
|
+
print("⚠️ Пароль должен содержать заглавные буквы")
|
|
371
|
+
else:
|
|
372
|
+
print("✅ Пароль достаточно сложный")'''
|
|
373
|
+
},
|
|
374
|
+
|
|
375
|
+
"file_operations": {
|
|
376
|
+
"title": "Работа с файлами",
|
|
377
|
+
"description": "Чтение и запись файлов - важная часть многих программ",
|
|
378
|
+
"code": '''# Работа с файлами в Python
|
|
379
|
+
|
|
380
|
+
# Запись в файл
|
|
381
|
+
print("=== Запись в файл ===")
|
|
382
|
+
|
|
383
|
+
# Создание и запись текстового файла
|
|
384
|
+
filename = "example.txt"
|
|
385
|
+
content = """Это пример файла.
|
|
386
|
+
Он содержит несколько строк текста.
|
|
387
|
+
Python делает работу с файлами простой!"""
|
|
388
|
+
|
|
389
|
+
# Безопасная запись с автоматическим закрытием файла
|
|
390
|
+
with open(filename, 'w', encoding='utf-8') as file:
|
|
391
|
+
file.write(content)
|
|
392
|
+
|
|
393
|
+
print(f"Файл '{filename}' создан и записан")
|
|
394
|
+
|
|
395
|
+
# Чтение файла
|
|
396
|
+
print("\\n=== Чтение файла ===")
|
|
397
|
+
|
|
398
|
+
try:
|
|
399
|
+
with open(filename, 'r', encoding='utf-8') as file:
|
|
400
|
+
file_content = file.read()
|
|
401
|
+
print("Содержимое файла:")
|
|
402
|
+
print(file_content)
|
|
403
|
+
except FileNotFoundError:
|
|
404
|
+
print(f"Файл '{filename}' не найден")
|
|
405
|
+
|
|
406
|
+
# Чтение файла построчно
|
|
407
|
+
print("\\n=== Чтение по строкам ===")
|
|
408
|
+
|
|
409
|
+
try:
|
|
410
|
+
with open(filename, 'r', encoding='utf-8') as file:
|
|
411
|
+
line_number = 1
|
|
412
|
+
for line in file:
|
|
413
|
+
print(f"Строка {line_number}: {line.strip()}")
|
|
414
|
+
line_number += 1
|
|
415
|
+
except FileNotFoundError:
|
|
416
|
+
print(f"Файл '{filename}' не найден")
|
|
417
|
+
|
|
418
|
+
# Добавление в существующий файл
|
|
419
|
+
print("\\n=== Добавление в файл ===")
|
|
420
|
+
|
|
421
|
+
additional_content = "\\nЭта строка добавлена позже."
|
|
422
|
+
|
|
423
|
+
with open(filename, 'a', encoding='utf-8') as file:
|
|
424
|
+
file.write(additional_content)
|
|
425
|
+
|
|
426
|
+
print("Содержимое добавлено в файл")
|
|
427
|
+
|
|
428
|
+
# Чтение обновленного файла
|
|
429
|
+
with open(filename, 'r', encoding='utf-8') as file:
|
|
430
|
+
updated_content = file.read()
|
|
431
|
+
print("\\nОбновленное содержимое:")
|
|
432
|
+
print(updated_content)
|
|
433
|
+
|
|
434
|
+
# Работа с CSV-подобными данными
|
|
435
|
+
print("\\n=== Работа с данными ===")
|
|
436
|
+
|
|
437
|
+
# Создание файла с данными о студентах
|
|
438
|
+
students_data = """Имя,Возраст,Курс
|
|
439
|
+
Анна,20,2
|
|
440
|
+
Борис,19,1
|
|
441
|
+
Вера,21,3
|
|
442
|
+
Григорий,22,4"""
|
|
443
|
+
|
|
444
|
+
with open("students.txt", 'w', encoding='utf-8') as file:
|
|
445
|
+
file.write(students_data)
|
|
446
|
+
|
|
447
|
+
# Чтение и обработка данных
|
|
448
|
+
print("Список студентов:")
|
|
449
|
+
with open("students.txt", 'r', encoding='utf-8') as file:
|
|
450
|
+
lines = file.readlines()
|
|
451
|
+
|
|
452
|
+
# Пропускаем заголовок (первую строку)
|
|
453
|
+
for line in lines[1:]:
|
|
454
|
+
name, age, course = line.strip().split(',')
|
|
455
|
+
print(f" {name}: {age} лет, {course} курс")
|
|
456
|
+
|
|
457
|
+
# Безопасная работа с файлами
|
|
458
|
+
print("\\n=== Безопасная работа ===")
|
|
459
|
+
|
|
460
|
+
def safe_read_file(filepath):
|
|
461
|
+
"""Безопасное чтение файла с обработкой ошибок."""
|
|
462
|
+
try:
|
|
463
|
+
with open(filepath, 'r', encoding='utf-8') as file:
|
|
464
|
+
return file.read()
|
|
465
|
+
except FileNotFoundError:
|
|
466
|
+
return f"Ошибка: файл '{filepath}' не найден"
|
|
467
|
+
except PermissionError:
|
|
468
|
+
return f"Ошибка: нет прав для чтения файла '{filepath}'"
|
|
469
|
+
except Exception as e:
|
|
470
|
+
return f"Неожиданная ошибка: {e}"
|
|
471
|
+
|
|
472
|
+
# Тестирование безопасной функции
|
|
473
|
+
result1 = safe_read_file("example.txt")
|
|
474
|
+
result2 = safe_read_file("nonexistent.txt")
|
|
475
|
+
|
|
476
|
+
print("Результат чтения существующего файла:")
|
|
477
|
+
print(result1[:50] + "..." if len(result1) > 50 else result1)
|
|
478
|
+
print("\\nРезультат чтения несуществующего файла:")
|
|
479
|
+
print(result2)'''
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
def generate_example(concept: str) -> str:
|
|
485
|
+
"""
|
|
486
|
+
Generate a code example for a Python concept.
|
|
487
|
+
|
|
488
|
+
Args:
|
|
489
|
+
concept: The Python concept to generate an example for.
|
|
490
|
+
Available concepts: variables, lists, dictionaries, functions,
|
|
491
|
+
loops, conditionals, file_operations
|
|
492
|
+
|
|
493
|
+
Returns:
|
|
494
|
+
A formatted code example as a string, or an error message if concept not found.
|
|
495
|
+
"""
|
|
496
|
+
concept_lower = concept.lower().strip()
|
|
497
|
+
|
|
498
|
+
if concept_lower not in CODE_EXAMPLES:
|
|
499
|
+
available_concepts = ", ".join(CODE_EXAMPLES.keys())
|
|
500
|
+
return f"❌ Концепция '{concept}' не найдена.\n📚 Доступные концепции: {available_concepts}"
|
|
501
|
+
|
|
502
|
+
example_data = CODE_EXAMPLES[concept_lower]
|
|
503
|
+
|
|
504
|
+
result = f"""
|
|
505
|
+
{'=' * 60}
|
|
506
|
+
📖 {example_data['title']}
|
|
507
|
+
{'=' * 60}
|
|
508
|
+
|
|
509
|
+
📝 Описание: {example_data['description']}
|
|
510
|
+
|
|
511
|
+
💻 Пример кода:
|
|
512
|
+
|
|
513
|
+
{example_data['code']}
|
|
514
|
+
|
|
515
|
+
{'=' * 60}
|
|
516
|
+
💡 Совет: Попробуйте запустить этот код и поэкспериментировать с ним!
|
|
517
|
+
{'=' * 60}
|
|
518
|
+
"""
|
|
519
|
+
return result.strip()
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
def list_available_concepts() -> list:
|
|
523
|
+
"""
|
|
524
|
+
Get a list of all available code example concepts.
|
|
525
|
+
|
|
526
|
+
Returns:
|
|
527
|
+
List of available concept names
|
|
528
|
+
"""
|
|
529
|
+
return list(CODE_EXAMPLES.keys())
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
def get_concept_info(concept: str) -> Optional[Dict[str, str]]:
|
|
533
|
+
"""
|
|
534
|
+
Get information about a specific concept.
|
|
535
|
+
|
|
536
|
+
Args:
|
|
537
|
+
concept: The concept to get information for
|
|
538
|
+
|
|
539
|
+
Returns:
|
|
540
|
+
Dictionary with concept information or None if not found
|
|
541
|
+
"""
|
|
542
|
+
concept_lower = concept.lower().strip()
|
|
543
|
+
|
|
544
|
+
if concept_lower not in CODE_EXAMPLES:
|
|
545
|
+
return None
|
|
546
|
+
|
|
547
|
+
return {
|
|
548
|
+
"title": CODE_EXAMPLES[concept_lower]["title"],
|
|
549
|
+
"description": CODE_EXAMPLES[concept_lower]["description"]
|
|
550
|
+
}
|