anb-python-components 1.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.
Files changed (48) hide show
  1. anb_python_components/__init__.py +1 -0
  2. anb_python_components/classes/__init__.py +1 -0
  3. anb_python_components/classes/action_state.py +211 -0
  4. anb_python_components/classes/directory.py +115 -0
  5. anb_python_components/classes/file.py +226 -0
  6. anb_python_components/classes/shortcode_parser.py +195 -0
  7. anb_python_components/custom_types/__init__.py +3 -0
  8. anb_python_components/custom_types/guid.py +169 -0
  9. anb_python_components/custom_types/object_array.py +625 -0
  10. anb_python_components/custom_types/shortcode_attributes.py +128 -0
  11. anb_python_components/custom_types/two_dim_size.py +413 -0
  12. anb_python_components/custom_types/version_info.py +461 -0
  13. anb_python_components/enums/__init__.py +1 -0
  14. anb_python_components/enums/message_type.py +44 -0
  15. anb_python_components/enums/not_bool_action.py +24 -0
  16. anb_python_components/enums/type_copy_strategy.py +47 -0
  17. anb_python_components/exceptions/__init__.py +1 -0
  18. anb_python_components/exceptions/wrong_type_exception.py +20 -0
  19. anb_python_components/extensions/__init__.py +1 -0
  20. anb_python_components/extensions/array_extension.py +34 -0
  21. anb_python_components/extensions/bool_extension.py +87 -0
  22. anb_python_components/extensions/string_extension.py +259 -0
  23. anb_python_components/extensions/string_extension_constant.py +80 -0
  24. anb_python_components/extensions/type_extension.py +112 -0
  25. anb_python_components/models/__init__.py +1 -0
  26. anb_python_components/models/action_state_message.py +27 -0
  27. anb_python_components/models/shortcode_model.py +31 -0
  28. anb_python_components-1.2.1.dist-info/METADATA +12 -0
  29. anb_python_components-1.2.1.dist-info/RECORD +48 -0
  30. anb_python_components-1.2.1.dist-info/WHEEL +5 -0
  31. anb_python_components-1.2.1.dist-info/licenses/LICENSE +235 -0
  32. anb_python_components-1.2.1.dist-info/top_level.txt +2 -0
  33. tests/__init__.py +1 -0
  34. tests/classes/__init__.py +1 -0
  35. tests/classes/action_state_test.py +138 -0
  36. tests/classes/directory_test.py +19 -0
  37. tests/classes/file_test.py +79 -0
  38. tests/classes/shortcode_parser_test.py +105 -0
  39. tests/custom_types/__init__.py +1 -0
  40. tests/custom_types/guid_test.py +14 -0
  41. tests/custom_types/object_array_test.py +160 -0
  42. tests/custom_types/two_dim_size_test.py +37 -0
  43. tests/custom_types/version_info_test.py +51 -0
  44. tests/extensions/__init__.py +1 -0
  45. tests/extensions/array_extension_test.py +21 -0
  46. tests/extensions/bool_extension_test.py +19 -0
  47. tests/extensions/string_extension_test.py +55 -0
  48. tests/extensions/type_extension_test.py +38 -0
@@ -0,0 +1,625 @@
1
+ # anb_python_components/custom_types/object_array.py
2
+ from __future__ import annotations
3
+
4
+ import copy
5
+ from functools import cmp_to_key, reduce
6
+ from typing import Any, Callable, get_args, get_type_hints
7
+
8
+ from anb_python_components.enums.type_copy_strategy import TypeCopyStrategy
9
+ from anb_python_components.extensions.type_extension import TypeExtension
10
+
11
+ class ObjectArray[T]:
12
+ """
13
+ Класс для хранения массива объектов.
14
+ """
15
+
16
+ # Добавление слотов для хранения массива
17
+ __slots__ = ['__container']
18
+
19
+ def __init__ (self, array: list[T] | None = None, copy_strategy: TypeCopyStrategy = TypeCopyStrategy.AUTO):
20
+ """
21
+ Инициализация массива объектов.
22
+
23
+ :param array: Список объектов или None.
24
+ :type array: list[T] | None
25
+ """
26
+ # Если массив не задан
27
+ if array is None:
28
+ # - то создаем пустой массив
29
+ self.__container: list[T] = []
30
+
31
+ # Если массив задан, то присваиваем его согласно стратегии копирования
32
+ match copy_strategy:
33
+ # - если копировать не нужно
34
+ case TypeCopyStrategy.IGNORE:
35
+ # -- то просто присваиваем его
36
+ self.__container: list[T] = array
37
+
38
+ # - если это примитивный тип
39
+ case TypeCopyStrategy.COPY:
40
+ # -- то копируем его
41
+ self.__container: list[T] = array.copy()
42
+ # - если это сложный тип
43
+ case TypeCopyStrategy.DEEP_COPY:
44
+ # -- то глубоко копируем его
45
+ self.__container: list[T] = copy.deepcopy(array)
46
+ # - если стратегия - автоматический выбор
47
+ case TypeCopyStrategy.AUTO:
48
+ # -- получаем тип аргумента T
49
+ t_type = get_args(get_type_hints(self.__class__).get('T'))
50
+
51
+ # -- анализируем его
52
+ if TypeExtension.is_immutable_type(t_type):
53
+ # --- если тип T - примитивный, то просто копируем его
54
+ self.__container: list[T] = array.copy()
55
+ else:
56
+ # --- иначе глубоко копируем его
57
+ self.__container: list[T] = copy.deepcopy(array)
58
+
59
+ def __iter__ (self):
60
+ """
61
+ Итератор.
62
+ :return: Итератор.
63
+ :rtype: Iterator[T]
64
+ """
65
+ return iter(self.__container)
66
+
67
+ def __getitem__ (self, key: int) -> T | None:
68
+ """
69
+ Доступ к атрибутам по ключу.
70
+ :param key: Ключ атрибута.
71
+ :type key: int
72
+ :return: Значение атрибута или None, если атрибут не найден.
73
+ :rtype: T | None
74
+ """
75
+ # Если ключ отрицательный или больше или равен длине массива
76
+ if key < 0 or key >= len(self.__container):
77
+ # - то возвращаем None
78
+ return None
79
+
80
+ # Возвращаем значение
81
+ return self.__container[key]
82
+
83
+ def __setitem__ (self, key: int, value: T) -> None:
84
+ """
85
+ Установить значение атрибута.
86
+ :param key: Ключ атрибута.
87
+ :type key: int
88
+ :param value: Значение атрибута.
89
+ :type value: T
90
+ :return: None
91
+ """
92
+ self.__container[key] = value
93
+
94
+ def __contains__ (self, item: T) -> bool:
95
+ """
96
+ Проверка наличия элемента в массиве.
97
+ :param item: Проверяемый элемент.
98
+ :type item: T
99
+ :return: True, если элемент найден, False, если элемент не найден.
100
+ """
101
+ return self.is_exists(lambda elem: elem == item)
102
+
103
+ def __len__ (self) -> int:
104
+ """
105
+ Количество атрибутов.
106
+ :return: Количество атрибутов.
107
+ :rtype: int
108
+ """
109
+ return self.count()
110
+
111
+ @staticmethod
112
+ def default_compare () -> Callable[[T, T], bool]:
113
+ """
114
+ Статический метод для получения функции сравнения по умолчанию.
115
+ :return: Функция сравнения по умолчанию.
116
+ :rtype: Callable[[T, T], bool]
117
+ """
118
+ return lambda x, y: x == y
119
+
120
+ ### Специальные методы ###
121
+ def clear (self) -> None:
122
+ """
123
+ Очистка массива.
124
+ """
125
+ self.__container.clear()
126
+
127
+ def add (self, value: T) -> None:
128
+ """
129
+ Добавление значения в массив.
130
+ :param value: Значение.
131
+ :type value: T
132
+ """
133
+ # Если значения нет в массиве
134
+ if value not in self.__container:
135
+ # - то добавляем
136
+ self.__container.append(value)
137
+
138
+ def add_range (self, values: list[T] | ObjectArray[T]) -> None:
139
+ """
140
+ Добавление диапазона значений в массив.
141
+ :param values: Значения, которые нужно добавить. Можно передавать массив или объект класса ObjectArray.
142
+ :type values: list[T] | ObjectArray[T]
143
+ """
144
+ # Если передан массив, то не изменяем его, а если передан объект класса ObjectArray, то конвертируем его в массив объектов
145
+ object_array = values.to_array() if isinstance(values, ObjectArray) else values
146
+
147
+ # Если значения есть
148
+ if len(object_array) > 0:
149
+ # - то добавляем их
150
+ self.__container += object_array
151
+
152
+ def to_array (self) -> list[T]:
153
+ """
154
+ Получение массива.
155
+ :return: Массив.
156
+ :rtype: list[T]
157
+ """
158
+ # Если массив не пустой
159
+ if len(self.__container) > 0:
160
+ # - то возвращаем его
161
+ return self.__container
162
+ else:
163
+ # - иначе возвращаем пустой массив
164
+ return []
165
+
166
+ ### Поиск и сортировка ###
167
+ def find (self, value: Any, compare: Callable[[T, Any], bool] = default_compare()) -> T | None:
168
+ """
169
+ Поиск значения в массиве.
170
+ :param value: Значение, которое нужно найти.
171
+ :type value: Any
172
+ :param compare: Функция сравнения.
173
+ :type value: Callable[[T, Any], bool]
174
+ :return: Найденное значение или None.
175
+ :rtype: T | None
176
+ """
177
+
178
+ # Для каждого элемента массива
179
+ for item in self.__container:
180
+ # - выполняем сравнение по функции сравнения
181
+ if compare(item, value):
182
+ # -- и возвращаем элемент, если он найден
183
+ return item
184
+
185
+ # Если мы сюда дошли, значить объект не найден - возвращаем None
186
+ return None
187
+
188
+ def sort (self, object_property: str, descending: bool = False) -> None:
189
+ """
190
+ Сортирует контейнер объектов по указанному атрибуту.
191
+
192
+ :param object_property: Имя атрибута объекта для сортировки
193
+ :type object_property: str
194
+ :param descending: если True — сортировка по убыванию
195
+ :type descending: bool
196
+ """
197
+ # Копируем список (чтобы не сортировать исходный напрямую)
198
+ result: list[T] = self.__container[:]
199
+
200
+ # Сортируем по указанному атрибуту
201
+ result.sort(
202
+ key = lambda obj: getattr(obj, object_property),
203
+ reverse = descending
204
+ )
205
+
206
+ # Присваиваем результат обратно в контейнер
207
+ self.__container = result
208
+
209
+ def sort_callback (
210
+ self,
211
+ predicate: Callable[[T], Any],
212
+ descending: bool = False
213
+ ) -> None:
214
+ """
215
+ Сортирует контейнер, используя пользовательскую функцию-предикат.
216
+
217
+ :param predicate: Функция, принимающая объект и возвращающая значение свойства для сравнения.
218
+ :type predicate: Callable[[T], Any]
219
+ :param descending: если True — сортировка по убыванию.
220
+ :type descending: bool
221
+ """
222
+ # Копируем список (чтобы не сортировать исходный напрямую)
223
+ result: list[T] = self.__container[:]
224
+
225
+ # Определяем компаратор
226
+ def comparator (a: Any, b: Any) -> int:
227
+ """
228
+ Функция сравнения двух значений.
229
+ :param a: Значение 1.
230
+ :type a: Any
231
+ :param b: Значение 2.
232
+ :type b: Any
233
+ :return: -1, если значение 1 меньше значения 2, 1, если значение 1 больше значения 2 и 0, если значения равны.
234
+ :rtype: int
235
+ """
236
+ # - получаем значения для сравнения по переданной функции
237
+ # -- значение 1
238
+ val_a = predicate(a)
239
+ # -- значение 2
240
+ val_b = predicate(b)
241
+
242
+ # - если значение 1 меньше значения 2
243
+ if val_a < val_b:
244
+ # -- то возвращаем -1
245
+ return -1
246
+ # - если значение 1 больше значения 2
247
+ elif val_a > val_b:
248
+ # -- то возвращаем 1
249
+ return 1
250
+ # - если значения равны
251
+ else:
252
+ # -- то возвращаем 0
253
+ return 0
254
+
255
+ # Если нужен обратный порядок
256
+ if descending:
257
+ # - то создаем компаратор, который меняет порядок
258
+ def reversed_comparator (a: Any, b: Any) -> int:
259
+ """
260
+ Функция для создания компаратора, который меняет порядок.
261
+ :param a: Значение 1.
262
+ :type a: Any
263
+ :param b: Значение 2.
264
+ :type b: Any
265
+ :return: -1, если значение 1 больше значения 2, 1, если значение 1 меньше значения 2 и 0, если значения равны.
266
+ :rtype: int
267
+ """
268
+ return -comparator(a, b)
269
+
270
+ # - сортируем по компаратору, который меняет порядок
271
+ result.sort(key = cmp_to_key(reversed_comparator))
272
+ else:
273
+ # - иначе сортируем по компаратору по умолчанию
274
+ result.sort(key = cmp_to_key(comparator))
275
+
276
+ # Присваиваем результат обратно в контейнер
277
+ self.__container = result
278
+
279
+ ### Операторы LINQ ###
280
+ ### 1. Операторы проверки существования и количества ###
281
+ def count (self, where: Callable[[T], bool] = None) -> int:
282
+ """
283
+ Количество элементов в массиве.
284
+ :param where: Функция выборки элементов. Вместо неё можно передать None, тогда будут возвращено общее
285
+ количество объектов в массиве. По умолчанию, None.
286
+ :type where: Callable[[T], bool] | None
287
+ :return: Количество элементов.
288
+ :rtype: int
289
+ """
290
+ # Если массив пустой
291
+ if not self.__container:
292
+ # - то возвращаем 0
293
+ return 0
294
+
295
+ # Если функция выборки не задана
296
+ if where is None:
297
+ # - то возвращаем длину массива
298
+ return len(self.__container)
299
+
300
+ # Задаём счетчик
301
+ result = 0
302
+
303
+ # Для каждого элемента массива
304
+ for item in self.__container:
305
+ # - выполняем выборку
306
+ if where(item):
307
+ # -- и если элемент удовлетворяет условию, то увеличиваем счетчик на 1
308
+ result += 1
309
+ else:
310
+ # -- иначе переходим к следующему элементу
311
+ continue
312
+
313
+ # Возвращаем результат
314
+ return result
315
+
316
+ def is_exists (self, where: Callable[[T], bool]) -> bool:
317
+ """
318
+ Проверка наличия элементов в массиве.
319
+ :param where: Функция выборки элементов.
320
+ :type where: Callable[[T], bool]
321
+ :return: True, если есть хотя бы один элемент, удовлетворяющий условию, иначе False.
322
+ :rtype: bool
323
+ """
324
+ return self.count(where) > 0
325
+
326
+ ### 2. Операторы выбора минимума и максимума ###
327
+ def min (self, by_value: Callable[[T], Any]) -> T | None:
328
+ """
329
+ Минимальное значение.
330
+ :param by_value: Функция, возвращающая значение для сравнения.
331
+ :type by_value: Callable[[T], Any]
332
+ :return: Минимальное значение или None.
333
+ :rtype: T | None
334
+ """
335
+ # Если массив пустой
336
+ if not self.__container:
337
+ # - то возвращаем None
338
+ return None
339
+
340
+ # Возвращаем минимальное значение
341
+ return reduce(
342
+ lambda current, value: value if current is None or by_value(value) < by_value(current) else current,
343
+ self.__container,
344
+ None
345
+ )
346
+
347
+ def max (self, by_value: Callable[[T], Any]) -> T | None:
348
+ """
349
+ Максимальное значение.
350
+ :param by_value: Функция, возвращающая значение для сравнения.
351
+ :type by_value: Callable[[T], Any]
352
+ :return: Максимальное значение или None.
353
+ :rtype: T | None
354
+ """
355
+ # Если массив пустой
356
+ if not self.__container:
357
+ # - то возвращаем None
358
+ return None
359
+
360
+ # Возвращаем максимальное значение
361
+ return reduce(
362
+ lambda current, value: value if current is None or by_value(value) > by_value(current) else current,
363
+ self.__container,
364
+ None
365
+ )
366
+
367
+ ### 3. Операторы выбора элементов ###
368
+ def get_rows (self, where: Callable[[T], bool] = None) -> ObjectArray[T]:
369
+ """
370
+ Выделяет из массива объектов объекты, удовлетворяющие условию.
371
+ :param where: Функция выборки объектов. Вместо неё можно передать None, тогда будут возвращены все объекты.
372
+ По умолчанию, None.
373
+ :type where: Callable[[T], bool] | None
374
+ :return: Массив объектов, удовлетворяющих условию.
375
+ :rtype: ObjectArray[T]
376
+ """
377
+ # Если функция выборки не задана или массив пустой
378
+ if where is None or not self.__container:
379
+ # - то просто копируем массив
380
+ return ObjectArray(self.__container)
381
+
382
+ # Выбираем элементы, удовлетворяющие условию
383
+ items = [item for item in self.__container if where(item)]
384
+
385
+ # И создаём новый массив
386
+ return ObjectArray(items)
387
+
388
+ def get_row (self, where: Callable[[T], bool] = None) -> T | None:
389
+ """
390
+ Выбирает из массива объектов объект, удовлетворяющий условию.
391
+ :param where: Функция выборки объектов. Вместо неё можно передать None, тогда будет возвращён первый объект.
392
+ По умолчанию, None.
393
+ :type where: Callable[[T], bool] | None
394
+ :return: Объект, удовлетворяющий условию или None, если объект не найден.
395
+ :rtype: T | None
396
+ """
397
+ # Если массив пустой
398
+ if not self.__container:
399
+ # - то возвращаем None
400
+ return None
401
+
402
+ # Если функция выборки не задана
403
+ if where is None:
404
+ # - то возвращаем первый элемент
405
+ return self.__container[0]
406
+
407
+ # Выбираем элементы, удовлетворяющие условию
408
+ rows: ObjectArray[T] = self.get_rows(where)
409
+
410
+ # Если элементов не найдено
411
+ if len(rows) == 0:
412
+ # - то возвращаем None
413
+ return None
414
+
415
+ # Возвращаем первый найденный элемент
416
+ return rows[0]
417
+
418
+ def where (self, where: Callable[[T], bool]) -> T | ObjectArray[T] | None:
419
+ """
420
+ Выбирает из массива объектов объекты, удовлетворяющие условию.
421
+ :param where: Функция выборки объектов.
422
+ :type where: Callable[[T], bool]
423
+ :return: Массив объектов, удовлетворяющих условию, если объектов несколько, или объект, удовлетворяющий условию,
424
+ если объект единственный, или None, если объект не найден.
425
+ :rtype: T | ObjectArray[T] | None
426
+ """
427
+ # Получаем массив объектов, удовлетворяющих условию
428
+ rows: ObjectArray[T] = self.get_rows(where)
429
+
430
+ # Если массив пустой
431
+ if len(rows) == 0:
432
+ # - то возвращаем None
433
+ return None
434
+ # - если массив содержит только один элемент
435
+ elif len(rows) == 1:
436
+ # -- то возвращаем его
437
+ return rows[0]
438
+ # - если массив содержит более одного элемента
439
+ else:
440
+ # -- то возвращаем массив
441
+ return rows
442
+
443
+ def get_column (self, column_name: str, where: Callable[[T], bool] = None) -> ObjectArray[Any]:
444
+ """
445
+ Выбирает из массива объектов значения свойства.
446
+ :param column_name: Имя свойства.
447
+ :type column_name: str
448
+ :param where: Функция выборки объектов. По умолчанию, None. Если None, то возвращаются свойства всех объектов.
449
+ :type where: Callable[[T], bool] | None
450
+ :return: Массив значений свойства.
451
+ :rtype: ObjectArray[Any]
452
+ """
453
+ return self.get_column_callback(
454
+ lambda item: getattr(item, column_name, None) if hasattr(item, column_name) else None,
455
+ where
456
+ )
457
+
458
+ def get_column_callback (self, column: Callable[[T], Any], where: Callable[[T], bool] = None) -> ObjectArray[Any]:
459
+ """
460
+ Выбирает из массива объектов значения свойства.
461
+ :param column: Функция получения значения свойства.
462
+ :type column: Callable[[T], Any]
463
+ :param where: Функция выборки объектов. По умолчанию, None. Если None, то возвращаются все объекты.
464
+ :type where: Callable[[T], bool] | None
465
+ :return: Массив значений свойства.
466
+ :rtype: ObjectArray[Any]
467
+ """
468
+ # Получаем массив объектов, удовлетворяющих условию
469
+ items = [column(item) for item in self.__container if where is None or where(item)]
470
+
471
+ # Возвращаем массив
472
+ return ObjectArray(items)
473
+
474
+ def get_value (self, column: str, where: Callable[[T], bool] = None) -> Any | None:
475
+ """
476
+ Получение значение единичного поля. Если полей по выборке будет больше одного, то вернёт первое из них.
477
+ :param column: Требуемый столбец.
478
+ :type column: str
479
+ :param where:Условие выборки., которое проверяет, подходит элемент или нет. Можно передать None, тогда будет
480
+ пробран весь массив. По умолчанию, None.
481
+ :type where: Callable[[T], bool] | None
482
+ :return: Значение поля или None, если поля нет.
483
+ :rtype: Any | None
484
+ """
485
+ # Получаю колонку
486
+ result = self.get_column(column, where)
487
+
488
+ # Если колонка пустая
489
+ if len(result) == 0:
490
+ # -- возвращаю None
491
+ return None
492
+
493
+ # Возвращаю первый элемент колонки
494
+ return result[0]
495
+
496
+ ### 4. Операторы удаления ###
497
+ def delete (self, where: Callable[[T], bool] = None) -> bool:
498
+ """
499
+ Удаление элементов из массива.
500
+ :param where: Функция выборки элементов. По умолчанию, None. Если None, то будут удалены все элементы.
501
+ :type where: Callable[[T], bool] | None
502
+ :return: True, если удаление успешно, False, если удаление не удалось.
503
+ :rtype: bool
504
+ """
505
+ # Если функция выборки не задана
506
+ if where is None:
507
+ # - то очищаем массив
508
+ self.clear()
509
+ # - и прерываем функцию
510
+ return True
511
+
512
+ # Получаем индексы элементов для удаления
513
+ remove_indices: list[int] = [i for i, item in enumerate(self.__container) if where(item)]
514
+
515
+ # Если индексы элементов для удаления не найдены
516
+ if not remove_indices:
517
+ # - то прерываем функцию
518
+ return False
519
+
520
+ # Проходим по индексам элементов для удаления в обратном порядке
521
+ for i in reversed(remove_indices):
522
+ # - удаляем элемент
523
+ del self.__container[i]
524
+
525
+ # Возвращаем True
526
+ return True
527
+
528
+ ### 5. Операторы получения ###
529
+ def first (self, default: T | None = None) -> T | None:
530
+ """
531
+ Безопасное получение первого элемента массива.
532
+ :param default: Значение по умолчанию или None. По умолчанию, None.
533
+ :return: Первый элемент массива, значение по умолчанию или None.
534
+ :rtype: T | None
535
+ """
536
+ return self.__container[0] if self.__container else default
537
+
538
+ def last (self, default: T | None = None) -> T | None:
539
+ """
540
+ Безопасное получение последнего элемента массива.
541
+ :param default: Значение по умолчанию или None. По умолчанию, None.
542
+ :return: Последний элемент массива, значение по умолчанию или None.
543
+ :rtype: T | None
544
+ """
545
+ return self.__container[-1] if self.__container else default
546
+
547
+ def skip (self, count: int) -> ObjectArray[T]:
548
+ """
549
+ Пропускает первые count элементов в массиве.
550
+ :param count: Количество пропускаемых элементов.
551
+ :type count: int
552
+ :return: Массив без первых count элементов.
553
+ :rtype: ObjectArray[T]
554
+ """
555
+ # Если требуется пропустить отрицательное количество элементов или нуль
556
+ if count <= 0:
557
+ # - то просто копируем массив
558
+ return ObjectArray(self.__container)
559
+
560
+ # Если требуется пропустить больше элементов, чем есть в массиве
561
+ if count >= len(self.__container):
562
+ # - то возвращаем пустой массив
563
+ return ObjectArray()
564
+
565
+ # Возвращаем массив без первых count элементов
566
+ return ObjectArray(self.__container[count:], TypeCopyStrategy.IGNORE)
567
+
568
+ def take (self, count: int) -> ObjectArray[T]:
569
+ """
570
+ Возвращает первые count элементов в массиве.
571
+ :param count: Количество возвращаемых элементов.
572
+ :type count: int
573
+ :return: Массив с первыми count элементами.
574
+ :rtype: ObjectArray[T]
575
+ """
576
+ # Если требуется взять отрицательное количество элементов или нуль
577
+ if count <= 0:
578
+ # - то возвращаем пустой массив
579
+ return ObjectArray()
580
+
581
+ # Если требуется взять больше элементов, чем есть в массиве
582
+ if count >= len(self.__container):
583
+ # - то просто копируем массив
584
+ return ObjectArray(self.__container)
585
+
586
+ # Возвращаем массив с первыми count элементами
587
+ return ObjectArray(self.__container[:count], TypeCopyStrategy.IGNORE)
588
+
589
+ def skip_and_take (self, skip_count: int, take_count: int) -> ObjectArray[T]:
590
+ """
591
+ Пропускает skip_count элементов и возвращает take_count элементов.
592
+ :param skip_count: Количество пропускаемых элементов.
593
+ :type skip_count: int
594
+ :param take_count: Количество возвращаемых элементов.
595
+ :type skip_count: int
596
+ :return: Массив с пропущенными skip_count элементами и take_count элементами.
597
+ :rtype: ObjectArray[T]
598
+ """
599
+ # Если требуется пропустить отрицательное количество элементов
600
+ if skip_count < 0:
601
+ # - то приравниваем skip_count к нулю
602
+ skip_count = 0
603
+
604
+ # Если требуется взять отрицательное количество элементов
605
+ if take_count <= 0:
606
+ # - то возвращаем пустой массив
607
+ return ObjectArray([])
608
+
609
+ # Задаём начало
610
+ start = skip_count
611
+ # Задаём конец - начало + количество элементов, которые нужно взять
612
+ end = start + take_count
613
+
614
+ # Если начало больше длины массива
615
+ if start >= len(self.__container):
616
+ # - то возвращаем пустой массив
617
+ return ObjectArray([])
618
+
619
+ # Если конец больше длины массива
620
+ if end >= len(self.__container):
621
+ # - то обрезаем массив до конца
622
+ end = len(self.__container)
623
+
624
+ # Делаем обрезку массива по началу и концу и возвращаем результат
625
+ return ObjectArray(self.__container[start:end], TypeCopyStrategy.IGNORE)