pythonic-fp-circulararray 6.0.1__py3-none-any.whl → 6.0.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- # Copyright 2023-202 Geoffrey R. Scheller
1
+ # Copyright 2023-2026 Geoffrey R. Scheller
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -13,7 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """
16
- .. admonition:: Variable storage capacity circular array.**
16
+ .. admonition:: Variable storage capacity circular array CA
17
17
 
18
18
  - O(1) pops either end
19
19
  - O(1) amortized pushes either end
@@ -35,25 +35,25 @@ __all__ = ['CA', 'ca']
35
35
  nada: Final[NoValue] = NoValue()
36
36
 
37
37
 
38
- class CA[I]:
39
- __slots__ = '_items', '_cnt', '_cap', '_front', '_rear'
38
+ class CA[X]:
39
+ __slots__ = '_xs', '_cnt', '_cap', '_front', '_rear'
40
40
 
41
- def __init__(self, *items: Iterable[I]) -> None:
41
+ def __init__(self, *xs: Iterable[X]) -> None:
42
42
  """
43
- :param items: Optionally takes a single iterable to
44
- initially populate the circular array.
45
- :raises TypeError: When ``items[0]`` not iterable.
43
+ :param xs: Optionally takes a single iterable to initially populate the circular array.
44
+ :raises TypeError: When ``xs[0]`` not iterable.
46
45
  :raises ValueError: If more than 1 iterable is given.
46
+
47
47
  """
48
- if (size := len(items)) > 1:
48
+ if (size := len(xs)) > 1:
49
49
  msg = f'CA expects at most 1 argument, got {size}'
50
50
  raise ValueError(msg)
51
51
  if size:
52
- values: list[I | NoValue] = list(cast(Iterable[I | NoValue], items[0]))
53
- self._items = [nada] + values + [nada]
52
+ values: list[X | NoValue] = list(cast(Iterable[X | NoValue], xs[0]))
53
+ self._xs = [nada] + values + [nada]
54
54
  else:
55
- self._items = [nada, nada]
56
- self._cap = (cap := len(self._items))
55
+ self._xs = [nada, nada]
56
+ self._cap = (cap := len(self._xs))
57
57
  self._cnt = cap - 2
58
58
  if cap == 2:
59
59
  self._front = 0
@@ -65,21 +65,21 @@ class CA[I]:
65
65
  def _double_storage_capacity(self) -> None:
66
66
  if self._front <= self._rear:
67
67
  (
68
- self._items,
68
+ self._xs,
69
69
  self._cap,
70
70
  ) = (
71
- self._items + [nada] * self._cap,
71
+ self._xs + [nada] * self._cap,
72
72
  self._cap * 2,
73
73
  )
74
74
  else:
75
75
  (
76
- self._items,
76
+ self._xs,
77
77
  self._front,
78
78
  self._cap,
79
79
  ) = (
80
- self._items[: self._front]
80
+ self._xs[: self._front]
81
81
  + [nada] * self._cap
82
- + self._items[self._front :],
82
+ + self._xs[self._front :],
83
83
  self._front + self._cap,
84
84
  2 * self._cap,
85
85
  )
@@ -91,7 +91,7 @@ class CA[I]:
91
91
  self._cap,
92
92
  self._front,
93
93
  self._rear,
94
- self._items,
94
+ self._xs,
95
95
  ) = (
96
96
  2,
97
97
  0,
@@ -103,12 +103,12 @@ class CA[I]:
103
103
  self._cap,
104
104
  self._front,
105
105
  self._rear,
106
- self._items,
106
+ self._xs,
107
107
  ) = (
108
108
  3,
109
109
  1,
110
110
  1,
111
- [nada, self._items[self._front], nada],
111
+ [nada, self._xs[self._front], nada],
112
112
  )
113
113
  case _:
114
114
  if self._front <= self._rear:
@@ -116,30 +116,30 @@ class CA[I]:
116
116
  self._cap,
117
117
  self._front,
118
118
  self._rear,
119
- self._items,
119
+ self._xs,
120
120
  ) = (
121
121
  self._cnt + 2,
122
122
  1,
123
123
  self._cnt,
124
- [nada] + self._items[self._front : self._rear + 1] + [nada],
124
+ [nada] + self._xs[self._front : self._rear + 1] + [nada],
125
125
  )
126
126
  else:
127
127
  (
128
128
  self._cap,
129
129
  self._front,
130
130
  self._rear,
131
- self._items,
131
+ self._xs,
132
132
  ) = (
133
133
  self._cnt + 2,
134
134
  1,
135
135
  self._cnt,
136
136
  [nada]
137
- + self._items[self._front :]
138
- + self._items[: self._rear + 1]
137
+ + self._xs[self._front :]
138
+ + self._xs[: self._rear + 1]
139
139
  + [nada],
140
140
  )
141
141
 
142
- def __iter__(self) -> Iterator[I]:
142
+ def __iter__(self) -> Iterator[X]:
143
143
  if self._cnt > 0:
144
144
  (
145
145
  capacity,
@@ -150,15 +150,15 @@ class CA[I]:
150
150
  self._cap,
151
151
  self._rear,
152
152
  self._front,
153
- self._items.copy(),
153
+ self._xs.copy(),
154
154
  )
155
155
 
156
156
  while position != rear:
157
- yield cast(I, current_state[position])
157
+ yield cast(X, current_state[position])
158
158
  position = (position + 1) % capacity
159
- yield cast(I, current_state[position])
159
+ yield cast(X, current_state[position])
160
160
 
161
- def __reversed__(self) -> Iterator[I]:
161
+ def __reversed__(self) -> Iterator[X]:
162
162
  if self._cnt > 0:
163
163
  (
164
164
  capacity,
@@ -169,18 +169,26 @@ class CA[I]:
169
169
  self._cap,
170
170
  self._front,
171
171
  self._rear,
172
- self._items.copy(),
172
+ self._xs.copy(),
173
173
  )
174
174
 
175
175
  while position != front:
176
- yield cast(I, current_state[position])
176
+ yield cast(X, current_state[position])
177
177
  position = (position - 1) % capacity
178
- yield cast(I, current_state[position])
178
+ yield cast(X, current_state[position])
179
179
 
180
180
  def __repr__(self) -> str:
181
+ """
182
+ :returns: String of the form ``ca(x1, x2, ..., xn)``.
183
+
184
+ """
181
185
  return 'ca(' + ', '.join(map(repr, self)) + ')'
182
186
 
183
187
  def __str__(self) -> str:
188
+ """
189
+ :returns: String of the form ``(|x1, x2, ..., xn|)``.
190
+
191
+ """
184
192
  return '(|' + ', '.join(map(str, self)) + '|)'
185
193
 
186
194
  def __bool__(self) -> bool:
@@ -190,20 +198,20 @@ class CA[I]:
190
198
  return self._cnt
191
199
 
192
200
  @overload
193
- def __getitem__(self, idx: int) -> I: ...
201
+ def __getitem__(self, idx: int) -> X: ...
194
202
  @overload
195
- def __getitem__(self, idx: slice) -> 'CA[I]': ...
203
+ def __getitem__(self, idx: slice) -> 'CA[X]': ...
196
204
 
197
- def __getitem__(self, idx: int | slice) -> I | 'CA[I]':
205
+ def __getitem__(self, idx: int | slice) -> X | 'CA[X]':
198
206
  if isinstance(idx, slice):
199
207
  return CA(list(self)[idx])
200
208
 
201
209
  cnt = self._cnt
202
210
  if 0 <= idx < cnt:
203
- return cast(I, self._items[(self._front + idx) % self._cap])
211
+ return cast(X, self._xs[(self._front + idx) % self._cap])
204
212
 
205
213
  if -cnt <= idx < 0:
206
- return cast(I, self._items[(self._front + cnt + idx) % self._cap])
214
+ return cast(X, self._xs[(self._front + cnt + idx) % self._cap])
207
215
 
208
216
  if cnt == 0:
209
217
  msg0 = 'Trying to get a value from an empty CA.'
@@ -215,24 +223,24 @@ class CA[I]:
215
223
  raise IndexError(msg1 + msg2 + msg3)
216
224
 
217
225
  @overload
218
- def __setitem__(self, idx: int, vals: I) -> None: ...
226
+ def __setitem__(self, idx: int, vals: X) -> None: ...
219
227
  @overload
220
- def __setitem__(self, idx: slice, vals: Iterable[I]) -> None: ...
228
+ def __setitem__(self, idx: slice, vals: Iterable[X]) -> None: ...
221
229
 
222
- def __setitem__(self, idx: int | slice, vals: I | Iterable[I]) -> None:
230
+ def __setitem__(self, idx: int | slice, vals: X | Iterable[X]) -> None:
223
231
  if isinstance(idx, slice):
224
232
  if isinstance(vals, Iterable):
225
233
  item_list = list(self)
226
234
  item_list[idx] = vals
227
235
  _ca = CA(item_list)
228
236
  (
229
- self._items,
237
+ self._xs,
230
238
  self._cnt,
231
239
  self._cap,
232
240
  self._front,
233
241
  self._rear,
234
242
  ) = (
235
- _ca._items,
243
+ _ca._xs,
236
244
  _ca._cnt,
237
245
  _ca._cap,
238
246
  _ca._front,
@@ -245,9 +253,9 @@ class CA[I]:
245
253
 
246
254
  cnt = self._cnt
247
255
  if 0 <= idx < cnt:
248
- self._items[(self._front + idx) % self._cap] = cast(I, vals)
256
+ self._xs[(self._front + idx) % self._cap] = cast(X, vals)
249
257
  elif -cnt <= idx < 0:
250
- self._items[(self._front + cnt + idx) % self._cap] = cast(I, vals)
258
+ self._xs[(self._front + cnt + idx) % self._cap] = cast(X, vals)
251
259
  else:
252
260
  if cnt < 1:
253
261
  msg0 = 'Trying to index into an empty CA.'
@@ -267,13 +275,13 @@ class CA[I]:
267
275
  del item_list[idx]
268
276
  _ca = CA(item_list)
269
277
  (
270
- self._items,
278
+ self._xs,
271
279
  self._cnt,
272
280
  self._cap,
273
281
  self._front,
274
282
  self._rear,
275
283
  ) = (
276
- _ca._items,
284
+ _ca._xs,
277
285
  _ca._cnt,
278
286
  _ca._cap,
279
287
  _ca._front,
@@ -284,9 +292,10 @@ class CA[I]:
284
292
  def __eq__(self, other: object) -> bool:
285
293
  """
286
294
  :param other: The object to be compared to.
287
- :returns: ``True`` if object is another CA whose items compare
288
- as equal to the corresponding items in the CA,
295
+ :returns: ``True`` if object is another ``CA`` whose items compare
296
+ as equal to the corresponding items in the ``CA``,
289
297
  otherwise ``False``.
298
+
290
299
  """
291
300
  if self is other:
292
301
  return True
@@ -314,28 +323,33 @@ class CA[I]:
314
323
 
315
324
  for nn in range(cnt1):
316
325
  if (
317
- self._items[(front1 + nn) % capacity1]
318
- is other._items[(front2 + nn) % capacity2]
326
+ self._xs[(front1 + nn) % capacity1]
327
+ is other._xs[(front2 + nn) % capacity2]
319
328
  ):
320
329
  continue
321
330
  if (
322
- self._items[(front1 + nn) % capacity1]
323
- != other._items[(front2 + nn) % capacity2]
331
+ self._xs[(front1 + nn) % capacity1]
332
+ != other._xs[(front2 + nn) % capacity2]
324
333
  ):
325
334
  return False
326
335
  return True
327
336
 
328
- def pushl(self, *items: I) -> None:
329
- """Push ``items`` on from left.
337
+ def pushl(self, *xs: X) -> None:
338
+ """
339
+ .. admonition:: Push left
340
+
341
+ Push items from the left onto the ``CA`` in the
342
+ order they were iterated.
343
+
344
+ :param xs: Items to be pushed onto the front of the circular array from the left.
330
345
 
331
- :param items: Items pushed onto circular array from left (front).
332
346
  """
333
- for item in items:
347
+ for item in xs:
334
348
  if self._cnt == self._cap:
335
349
  self._double_storage_capacity()
336
350
  (
337
351
  self._front,
338
- self._items[self._front],
352
+ self._xs[self._front],
339
353
  self._cnt,
340
354
  ) = (
341
355
  (self._front - 1) % self._cap,
@@ -343,17 +357,22 @@ class CA[I]:
343
357
  self._cnt + 1,
344
358
  )
345
359
 
346
- def pushr(self, *items: I) -> None:
347
- """Push ``items`` on from right.
360
+ def pushr(self, *xs: X) -> None:
361
+ """
362
+ .. admonition:: Push right
363
+
364
+ Push items from the right onto the ``CA`` in the
365
+ order they were iterated.
366
+
367
+ :param xs: Items to be pushed onto the rear of the ``CA`` from the right.
348
368
 
349
- :param items: Items pushed onto circular array from right (rear).
350
369
  """
351
- for item in items:
370
+ for item in xs:
352
371
  if self._cnt == self._cap:
353
372
  self._double_storage_capacity()
354
373
  (
355
374
  self._rear,
356
- self._items[self._rear],
375
+ self._xs[self._rear],
357
376
  self._cnt,
358
377
  ) = (
359
378
  (self._rear + 1) % self._cap,
@@ -361,20 +380,24 @@ class CA[I]:
361
380
  self._cnt + 1,
362
381
  )
363
382
 
364
- def popl(self) -> I:
365
- """Pop single item off from left side.
383
+ def popl(self) -> X:
384
+ """
385
+ .. admonition:: Pop left
386
+
387
+ Pop a single items off the left side of the ``CA``.
366
388
 
367
389
  :returns: Item popped from left side (front) of circular array.
368
390
  :raises ValueError: When called on an empty circular array.
391
+
369
392
  """
370
393
  if self._cnt > 1:
371
394
  (
372
395
  d,
373
- self._items[self._front],
396
+ self._xs[self._front],
374
397
  self._front,
375
398
  self._cnt,
376
399
  ) = (
377
- self._items[self._front],
400
+ self._xs[self._front],
378
401
  nada,
379
402
  (self._front + 1) % self._cap,
380
403
  self._cnt - 1,
@@ -382,12 +405,12 @@ class CA[I]:
382
405
  elif self._cnt == 1:
383
406
  (
384
407
  d,
385
- self._items[self._front],
408
+ self._xs[self._front],
386
409
  self._cnt,
387
410
  self._front,
388
411
  self._rear,
389
412
  ) = (
390
- self._items[self._front],
413
+ self._xs[self._front],
391
414
  nada,
392
415
  0,
393
416
  0,
@@ -396,22 +419,26 @@ class CA[I]:
396
419
  else:
397
420
  msg = 'Method popl called on an empty CA'
398
421
  raise ValueError(msg)
399
- return cast(I, d)
422
+ return cast(X, d)
423
+
424
+ def popr(self) -> X:
425
+ """
426
+ .. admonition:: Pop right
400
427
 
401
- def popr(self) -> I:
402
- """Pop single item off from right.
428
+ Pop a single items off the right side of the ``CA``.
403
429
 
404
430
  :returns: Item popped from right side (rear) of circular array.
405
431
  :raises ValueError: When called on an empty circular array.
432
+
406
433
  """
407
434
  if self._cnt > 1:
408
435
  (
409
436
  d,
410
- self._items[self._rear],
437
+ self._xs[self._rear],
411
438
  self._rear,
412
439
  self._cnt,
413
440
  ) = (
414
- self._items[self._rear],
441
+ self._xs[self._rear],
415
442
  nada,
416
443
  (self._rear - 1) % self._cap,
417
444
  self._cnt - 1,
@@ -419,12 +446,12 @@ class CA[I]:
419
446
  elif self._cnt == 1:
420
447
  (
421
448
  d,
422
- self._items[self._front],
449
+ self._xs[self._front],
423
450
  self._cnt,
424
451
  self._front,
425
452
  self._rear,
426
453
  ) = (
427
- self._items[self._front],
454
+ self._xs[self._front],
428
455
  nada,
429
456
  0,
430
457
  0,
@@ -433,40 +460,53 @@ class CA[I]:
433
460
  else:
434
461
  msg = 'Method popr called on an empty CA'
435
462
  raise ValueError(msg)
436
- return cast(I, d)
463
+ return cast(X, d)
437
464
 
438
- def popld(self, default: I) -> I:
439
- """Pop one item from left side of the circular array, provide
440
- a mandatory default value. "Safe" version of ``popl``.
465
+ def popld(self, default: X) -> X:
466
+ """
467
+ .. admonition:: Pop Left with default
468
+
469
+ Pop a single items off the left side of the ``CA``.
470
+
471
+ :param default: Default value to return if ``CA`` is empty.
472
+ :returns: Item popped from left side (front) of circular array
473
+ if not empty, otherwise return the provided default
474
+ value.
441
475
 
442
- :param default: Item returned if circular array is empty.
443
- :returns: Item popped from left side or default item if empty.
444
476
  """
445
477
  try:
446
478
  return self.popl()
447
479
  except ValueError:
448
480
  return default
449
481
 
450
- def poprd(self, default: I) -> I:
451
- """Pop one item from right side of the circular array, provide
452
- a mandatory default value. "Safe" version of ``popr``.
482
+ def poprd(self, default: X) -> X:
483
+ """
484
+ .. admonition:: Pop Right with default
485
+
486
+ Pop a single items off the right side of the ``CA``.
487
+
488
+ :param default: Default value to return if ``CA`` is empty.
489
+ :returns: Item popped from right side (rear) of circular array
490
+ if not empty, otherwise return the provided default
491
+ value.
453
492
 
454
- :param default: Item returned if circular array is empty.
455
- :returns: Item popped from right side or default item if empty.
456
493
  """
457
494
  try:
458
495
  return self.popr()
459
496
  except ValueError:
460
497
  return default
461
498
 
462
- def poplt(self, maximum: int) -> tuple[I, ...]:
463
- """Pop multiple items from left side of circular array.
499
+ def poplt(self, maximum: int) -> tuple[X, ...]:
500
+ """
501
+ .. admonition:: Pop multiple items from left
502
+
503
+ Pop items off the left side of the ``CA``.
504
+
505
+ :param maximum: Maximum number of items to pop, may pop less if not enough items in ``CA``.
506
+ :returns: A ``tuple`` of the items popped, left to right.
464
507
 
465
- :param maximum: Maximum number of items to pop, may pop less
466
- if not enough items.
467
- :returns: Tuple of items in the order popped, left to right.
468
508
  """
469
- item_list: list[I] = []
509
+ item_list: list[X] = []
470
510
 
471
511
  while maximum > 0:
472
512
  try:
@@ -478,14 +518,17 @@ class CA[I]:
478
518
 
479
519
  return tuple(item_list)
480
520
 
481
- def poprt(self, maximum: int) -> tuple[I, ...]:
482
- """Pop multiple items from right side of circular array.
521
+ def poprt(self, maximum: int) -> tuple[X, ...]:
522
+ """
523
+ .. admonition:: Pop multiple items from right
524
+
525
+ Pop items off the right side of the ``CA``.
526
+
527
+ :param maximum: Maximum number of items to pop, may pop less if not enough items in ``CA``.
528
+ :returns: A ``tuple`` of the items popped, right to left.
483
529
 
484
- :param maximum: Maximum number of items to pop, may pop less
485
- if not enough items.
486
- :returns: Tuple of items in the order popped, right to left.
487
530
  """
488
- item_list: list[I] = []
531
+ item_list: list[X] = []
489
532
  while maximum > 0:
490
533
  try:
491
534
  item_list.append(self.popr())
@@ -496,9 +539,14 @@ class CA[I]:
496
539
  return tuple(item_list)
497
540
 
498
541
  def rotl(self, n: int = 1) -> None:
499
- """Rotate items to the left.
542
+ """
543
+ .. admonition:: Rotate left
544
+
545
+ Rotate contents of ``CA`` to the left putting first
546
+ item onto rear.
547
+
548
+ :param n: Number of times to shift items left. Default 1 time.
500
549
 
501
- :param n: Number of times to shift elements to the left.
502
550
  """
503
551
  if self._cnt < 2:
504
552
  return
@@ -506,37 +554,48 @@ class CA[I]:
506
554
  self.pushr(self.popl())
507
555
 
508
556
  def rotr(self, n: int = 1) -> None:
509
- """Rotate items to the right.
557
+ """
558
+ .. admonition:: Rotate right
559
+
560
+ Rotate contents of ``CA`` to the right putting last
561
+ item onto front.
562
+
563
+ :param n: Number of times to shift items right. Default 1 time.
510
564
 
511
- :param n: Number of times to shift elements to the right.
512
565
  """
513
566
  if self._cnt < 2:
514
567
  return
515
568
  for _ in range(n, 0, -1):
516
569
  self.pushl(self.popr())
517
570
 
518
- def map[U](self, f: Callable[[I], U]) -> 'CA[U]':
519
- """Apply function ``f`` over the circular array's contents.
571
+ def map[Y](self, f: Callable[[X], Y]) -> 'CA[Y]':
572
+ """
573
+ .. admonition:: Map function over the CA
574
+
575
+ Apply function ``f`` over the circular array's contents.
520
576
 
521
- :param f: Callable from type ``I`` to type ``U``.
577
+ :param f: Callable from type ``X`` to type ``Y``.
522
578
  :returns: New auto-resizing circular array instance.
579
+
523
580
  """
524
581
  return CA(map(f, self))
525
582
 
526
583
  @overload
527
- def foldl[L](self, f: Callable[[I, I], I]) -> I: ...
584
+ def foldl[L](self, f: Callable[[X, X], X]) -> X: ...
528
585
  @overload
529
- def foldl[L](self, f: Callable[[L, I], L], start: L) -> L: ...
586
+ def foldl[L](self, f: Callable[[L, X], L], start: L) -> L: ...
587
+
588
+ def foldl[L](self, f: Callable[[L, X], L], start: L | NoValue = NoValue()) -> L:
589
+ """
590
+ .. admonition:: Fold left
530
591
 
531
- def foldl[L](self, f: Callable[[L, I], L], start: L | NoValue = NoValue()) -> L:
532
- """Fold left with a function and optional starting item.
592
+ Fold ``CA`` left with a function and optional starting item.
533
593
 
534
- :param f: Folding function, first argument to ``f`` is for
535
- the accumulator.
536
- :param start: "Optional" starting item.
594
+ :param f: Folding function, first argument to ``f`` is for the accumulator.
595
+ :param start: Optional starting item.
537
596
  :returns: Reduced value produced by the left fold.
538
- :raises ValueError: When circular array empty and no starting
539
- item given.
597
+ :raises ValueError: When circular array empty and ``start`` not given.
598
+
540
599
  """
541
600
  if self._cnt == 0:
542
601
  if start is nada:
@@ -556,19 +615,21 @@ class CA[I]:
556
615
  return acc
557
616
 
558
617
  @overload
559
- def foldr[R](self, f: Callable[[I, I], I]) -> I: ...
618
+ def foldr[R](self, f: Callable[[X, X], X]) -> X: ...
560
619
  @overload
561
- def foldr[R](self, f: Callable[[I, R], R], start: R) -> R: ...
620
+ def foldr[R](self, f: Callable[[X, R], R], start: R) -> R: ...
621
+
622
+ def foldr[R](self, f: Callable[[X, R], R], start: R | NoValue = nada) -> R:
623
+ """
624
+ .. admonition:: Fold right
562
625
 
563
- def foldr[R](self, f: Callable[[I, R], R], start: R | NoValue = nada) -> R:
564
- """Fold right with a function and an optional starting item.
626
+ Fold ``CA`` right with a function and optional starting item.
565
627
 
566
- :param f: Folding function, second argument to ``f`` is for
567
- the accumulator.
628
+ :param f: Folding function, second argument to ``f`` is for the accumulator.
568
629
  :param start: Optional starting item.
569
630
  :returns: Reduced value produced by the right fold.
570
- :raises ValueError: When circular array empty and no starting
571
- item given.
631
+ :raises ValueError: When circular array empty and ``start`` not given.
632
+
572
633
  """
573
634
  if self._cnt == 0:
574
635
  if start is nada:
@@ -588,16 +649,25 @@ class CA[I]:
588
649
  return acc
589
650
 
590
651
  def capacity(self) -> int:
591
- """Return current storage capacity of the circular array.
652
+ """
653
+ .. admonition:: Get capacity
654
+
655
+ Get the current storage capacity of the circular array.
592
656
 
593
657
  :returns: Current storage capacity.
658
+
594
659
  """
595
660
  return self._cap
596
661
 
597
662
  def empty(self) -> None:
598
- """Empty the circular array, keep current storage capacity."""
663
+ """
664
+ .. admonition:: Empty circular array
665
+
666
+ Empty the circular array, keep current storage capacity.
667
+
668
+ """
599
669
  (
600
- self._items,
670
+ self._xs,
601
671
  self._front,
602
672
  self._rear,
603
673
  self._cnt,
@@ -609,37 +679,48 @@ class CA[I]:
609
679
  )
610
680
 
611
681
  def fraction_filled(self) -> float:
612
- """Find fraction of the storage capacity which is filled.
682
+ """
683
+ .. admonition:: Get fraction filled
684
+
685
+ Find fraction of the storage capacity which is filled.
613
686
 
614
687
  :returns: The ratio count/capacity.
688
+
615
689
  """
616
690
  return self._cnt / self._cap
617
691
 
618
692
  def resize(self, minimum_capacity: int = 2) -> None:
619
- """Compact circular array and, if necessary, resize to a minimum
620
- storage capacity. To just compact the circular array, do not
621
- provide ``minimum_capacity``.
693
+ """
694
+ .. admonition:: Resize
695
+
696
+ Compact circular array and, if necessary, resize to a
697
+ minimum storage capacity. To just compact the circular
698
+ array, do not provide ``minimum_capacity``.
699
+
700
+ :param minimum_capacity: Minimum storage capacity to compact the circular array.
622
701
 
623
- :param minimum_capacity: Minimum storage capacity to compact
624
- the circular array.
625
702
  """
626
703
  self._compact_storage_capacity()
627
704
  if (min_cap := minimum_capacity) > self._cap:
628
705
  (
629
706
  self._cap,
630
- self._items,
707
+ self._xs,
631
708
  ) = (
632
709
  min_cap,
633
- self._items + [nada] * (min_cap - self._cap),
710
+ self._xs + [nada] * (min_cap - self._cap),
634
711
  )
635
712
  if self._cnt == 0:
636
713
  self._front, self._rear = 0, self._cap - 1
637
714
 
638
715
 
639
- def ca[T](*items: T) -> CA[T]:
640
- """Produce circular array from a variable number of arguments.
716
+ def ca[T](*ts: T) -> CA[T]:
717
+ """
718
+ .. admonition:: Circular array factory function
719
+
720
+ Produce a circular array from a variable number of arguments.
641
721
 
642
- :param items: Initial items for a new auto-resizing circular array.
722
+ :param ts: Initial items for a new auto-resizing circular array.
643
723
  :returns: New variable storage capacity circular array.
724
+
644
725
  """
645
- return CA(items)
726
+ return CA(ts)