pythonic-fp-circulararray 6.0.0__py3-none-any.whl → 6.0.2__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.
@@ -0,0 +1,49 @@
1
+ from collections.abc import Callable, Iterable, Iterator
2
+ from typing import overload
3
+
4
+ __all__ = ['CA', 'ca']
5
+
6
+ class CA[X]:
7
+ def __init__(self, *xs: Iterable[X]) -> None: ...
8
+ def __iter__(self) -> Iterator[X]: ...
9
+ def __reversed__(self) -> Iterator[X]: ...
10
+ def __bool__(self) -> bool: ...
11
+ def __len__(self) -> int: ...
12
+ @overload
13
+ def __getitem__(self, idx: int) -> X: ...
14
+ @overload
15
+ def __getitem__(self, idx: slice) -> CA[X]: ...
16
+ @overload
17
+ def __setitem__(self, idx: int, vals: X) -> None: ...
18
+ @overload
19
+ def __setitem__(self, idx: slice, vals: Iterable[X]) -> None: ...
20
+ @overload
21
+ def __delitem__(self, idx: int) -> None: ...
22
+ @overload
23
+ def __delitem__(self, idx: slice) -> None: ...
24
+ def __eq__(self, other: object) -> bool: ...
25
+ def pushl(self, *xs: X) -> None: ...
26
+ def pushr(self, *xs: X) -> None: ...
27
+ def popl(self) -> X: ...
28
+ def popr(self) -> X: ...
29
+ def popld(self, default: X) -> X: ...
30
+ def poprd(self, default: X) -> X: ...
31
+ def poplt(self, maximum: int) -> tuple[X, ...]: ...
32
+ def poprt(self, maximum: int) -> tuple[X, ...]: ...
33
+ def rotl(self, n: int = 1) -> None: ...
34
+ def rotr(self, n: int = 1) -> None: ...
35
+ def map[Y](self, f: Callable[[X], Y]) -> CA[Y]: ...
36
+ @overload
37
+ def foldl[L](self, f: Callable[[X, X], X]) -> X: ...
38
+ @overload
39
+ def foldl[L](self, f: Callable[[L, X], L], start: L) -> L: ...
40
+ @overload
41
+ def foldr[R](self, f: Callable[[X, X], X]) -> X: ...
42
+ @overload
43
+ def foldr[R](self, f: Callable[[X, R], R], start: R) -> R: ...
44
+ def capacity(self) -> int: ...
45
+ def empty(self) -> None: ...
46
+ def fraction_filled(self) -> float: ...
47
+ def resize(self, minimum_capacity: int = 2) -> None: ...
48
+
49
+ def ca[T](*ts: T) -> CA[T]: ...
@@ -1,4 +1,4 @@
1
- # Copyright 2023-2025 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,18 +13,15 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """
16
- Fixed Storage Capacity
17
- ======================
16
+ .. admonition:: Fixed storage capacity circular array CAF
18
17
 
19
- **Circular array with fixed storage capacity.**
20
-
21
- - O(1) pops and pushes either end
22
- - O(1) indexing, does not support slicing
23
- - fixed total storage capacity
24
- - iterable, safely mutates while iterators iterating over previous state
25
- - comparisons compare identity before equality, like builtins
26
- - in boolean context, falsy when either empty or full, otherwise truthy
27
- - function ``caf`` produces fixed capacity circular array from arguments
18
+ - O(1) pops and pushes either end
19
+ - O(1) indexing, does not support slicing
20
+ - fixed total storage capacity
21
+ - iterable, safely mutates while iterators iterating over previous state
22
+ - comparisons compare identity before equality, like builtins
23
+ - in boolean context, falsy when either empty or full, otherwise truthy
24
+ - function ``caf`` produces fixed capacity circular array from arguments
28
25
 
29
26
  """
30
27
 
@@ -37,27 +34,28 @@ __all__ = ['CAF', 'caf']
37
34
  nada: Final[NoValue] = NoValue()
38
35
 
39
36
 
40
- class CAF[I]:
41
- __slots__ = '_items', '_cnt', '_cap', '_front', '_rear'
37
+ class CAF[X]:
38
+ __slots__ = '_xs', '_cnt', '_cap', '_front', '_rear'
42
39
 
43
- def __init__(self, *items: Iterable[I], cap: int = 2) -> None:
40
+ def __init__(self, *xs: Iterable[X], cap: int = 2) -> None:
44
41
  """
45
- :param items: "Optionally" takes a single iterable to populate circular array.
42
+ :param xs: Optionally takes a single iterable to initially populate the circular array.
46
43
  :param cap: Minimum fixed storage capacity of circular array.
47
- :raises TypeError: When ``items[0]`` not iterable,
44
+ :raises TypeError: When ``xs[0]`` not iterable,
48
45
  :raises ValueError: If more than 1 iterable is given.
46
+
49
47
  """
50
48
  cap = max(2, cap)
51
- if (size := len(items)) > 1:
49
+ if (size := len(xs)) > 1:
52
50
  msg = f'CAF expects at most 1 argument, got {size}'
53
51
  raise ValueError(msg)
54
52
  if size:
55
- values: list[I | NoValue] = list(cast(Iterable[I | NoValue], items[0]))
53
+ values: list[X | NoValue] = list(cast(Iterable[X | NoValue], xs[0]))
56
54
  cnt = len(values)
57
55
  cap = max(cnt, cap)
58
- self._items = values + [nada] * (cap - cnt)
56
+ self._xs = values + [nada] * (cap - cnt)
59
57
  else:
60
- self._items = [nada] * cap
58
+ self._xs = [nada] * cap
61
59
  cnt = 0
62
60
  self._cap: Final[int] = cap
63
61
  self._cnt = cnt
@@ -68,7 +66,7 @@ class CAF[I]:
68
66
  self._front = 0
69
67
  self._rear = cnt - 1
70
68
 
71
- def __iter__(self) -> Iterator[I]:
69
+ def __iter__(self) -> Iterator[X]:
72
70
  if self._cnt > 0:
73
71
  (
74
72
  cap,
@@ -79,15 +77,15 @@ class CAF[I]:
79
77
  self._cap,
80
78
  self._rear,
81
79
  self._front,
82
- self._items.copy(),
80
+ self._xs.copy(),
83
81
  )
84
82
 
85
83
  while position != rear:
86
- yield cast(I, current_state[position])
84
+ yield cast(X, current_state[position])
87
85
  position = (position + 1) % cap
88
- yield cast(I, current_state[position])
86
+ yield cast(X, current_state[position])
89
87
 
90
- def __reversed__(self) -> Iterator[I]:
88
+ def __reversed__(self) -> Iterator[X]:
91
89
  if self._cnt > 0:
92
90
  (
93
91
  cap,
@@ -98,18 +96,26 @@ class CAF[I]:
98
96
  self._cap,
99
97
  self._front,
100
98
  self._rear,
101
- self._items.copy(),
99
+ self._xs.copy(),
102
100
  )
103
101
 
104
102
  while position != front:
105
- yield cast(I, current_state[position])
103
+ yield cast(X, current_state[position])
106
104
  position = (position - 1) % cap
107
- yield cast(I, current_state[position])
105
+ yield cast(X, current_state[position])
108
106
 
109
107
  def __repr__(self) -> str:
108
+ """
109
+ :returns: String of the form ``caf(x1, x2, ..., xn)``.
110
+
111
+ """
110
112
  return 'caf(' + ', '.join(map(repr, self)) + ')'
111
113
 
112
114
  def __str__(self) -> str:
115
+ """
116
+ :returns: String of the form ``(|x1, x2, ..., xn|)``.
117
+
118
+ """
113
119
  return '(|' + ', '.join(map(str, self)) + '|)'
114
120
 
115
121
  def __bool__(self) -> bool:
@@ -118,13 +124,13 @@ class CAF[I]:
118
124
  def __len__(self) -> int:
119
125
  return self._cnt
120
126
 
121
- def __getitem__(self, idx: int) -> I:
127
+ def __getitem__(self, idx: int) -> X:
122
128
  cnt = self._cnt
123
129
  if 0 <= idx < cnt:
124
- return cast(I, self._items[(self._front + idx) % self._cap])
130
+ return cast(X, self._xs[(self._front + idx) % self._cap])
125
131
 
126
132
  if -cnt <= idx < 0:
127
- return cast(I, self._items[(self._front + cnt + idx) % self._cap])
133
+ return cast(X, self._xs[(self._front + cnt + idx) % self._cap])
128
134
 
129
135
  if cnt == 0:
130
136
  msg0 = 'Trying to get a value from an empty CAF.'
@@ -135,12 +141,12 @@ class CAF[I]:
135
141
  msg3 = 'while getting value from a CAF.'
136
142
  raise IndexError(msg1 + msg2 + msg3)
137
143
 
138
- def __setitem__(self, idx: int, val: I) -> None:
144
+ def __setitem__(self, idx: int, val: X) -> None:
139
145
  cnt = self._cnt
140
146
  if 0 <= idx < cnt:
141
- self._items[(self._front + idx) % self._cap] = val
147
+ self._xs[(self._front + idx) % self._cap] = val
142
148
  elif -cnt <= idx < 0:
143
- self._items[(self._front + cnt + idx) % self._cap] = val
149
+ self._xs[(self._front + cnt + idx) % self._cap] = val
144
150
  else:
145
151
  if cnt < 1:
146
152
  msg0 = 'Trying to index into an empty CAF.'
@@ -155,12 +161,12 @@ class CAF[I]:
155
161
  del item_list[idx]
156
162
  _ca = CAF(item_list, cap = self._cap)
157
163
  (
158
- self._items,
164
+ self._xs,
159
165
  self._cnt,
160
166
  self._front,
161
167
  self._rear,
162
168
  ) = (
163
- _ca._items,
169
+ _ca._xs,
164
170
  _ca._cnt,
165
171
  _ca._front,
166
172
  _ca._rear,
@@ -168,6 +174,13 @@ class CAF[I]:
168
174
  del _ca
169
175
 
170
176
  def __eq__(self, other: object) -> bool:
177
+ """
178
+ :param other: The object to be compared to.
179
+ :returns: ``True`` if object is another ``CAF`` whose items compare
180
+ as equal to the corresponding items in the ``CAF``,
181
+ otherwise ``False``.
182
+
183
+ """
171
184
  if self is other:
172
185
  return True
173
186
  if not isinstance(other, type(self)):
@@ -194,22 +207,26 @@ class CAF[I]:
194
207
 
195
208
  for nn in range(cnt1):
196
209
  if (
197
- self._items[(front1 + nn) % cap1]
198
- is other._items[(front2 + nn) % cap2]
210
+ self._xs[(front1 + nn) % cap1]
211
+ is other._xs[(front2 + nn) % cap2]
199
212
  ):
200
213
  continue
201
214
  if (
202
- self._items[(front1 + nn) % cap1]
203
- != other._items[(front2 + nn) % cap2]
215
+ self._xs[(front1 + nn) % cap1]
216
+ != other._xs[(front2 + nn) % cap2]
204
217
  ):
205
218
  return False
206
219
  return True
207
220
 
208
- def pushl(self, item: I) -> None:
209
- """Push ``item`` on from left.
221
+ def pushl(self, item: X) -> None:
222
+ """
223
+ .. admonition:: Push left
224
+
225
+ Push single item from the left onto the ``CAF``.
226
+
227
+ :param x: Single item to be pushed onto the front of the circular array from the left.
228
+ :raises ValueError: When called on a full fixed storage capacity circular array.
210
229
 
211
- :param item: Single item pushed onto circular array from left (front).
212
- :raises ValueError: When called on a full ``CAF``.
213
230
  """
214
231
  if self._cnt == self._cap:
215
232
  msg = 'Method pushl called on a full CAF'
@@ -217,7 +234,7 @@ class CAF[I]:
217
234
 
218
235
  (
219
236
  self._front,
220
- self._items[self._front],
237
+ self._xs[self._front],
221
238
  self._cnt,
222
239
  ) = (
223
240
  (self._front - 1) % self._cap,
@@ -225,11 +242,15 @@ class CAF[I]:
225
242
  self._cnt + 1,
226
243
  )
227
244
 
228
- def pushr(self, item: I) -> None:
229
- """Push ``item`` on from Right.
245
+ def pushr(self, item: X) -> None:
246
+ """
247
+ .. admonition:: Push right
248
+
249
+ Push single item from the right onto the ``CAF``.
230
250
 
231
- :param item: Single ``item`` pushed onto circular array from right (rear).
251
+ :param x: Single item to be pushed onto the rear of the circular array from the right.
232
252
  :raises ValueError: When called on a full fixed storage capacity circular array.
253
+
233
254
  """
234
255
  if self._cnt == self._cap:
235
256
  msg = 'Method pushr called on a full CAF'
@@ -237,7 +258,7 @@ class CAF[I]:
237
258
 
238
259
  (
239
260
  self._rear,
240
- self._items[self._rear],
261
+ self._xs[self._rear],
241
262
  self._cnt,
242
263
  ) = (
243
264
  (self._rear + 1) % self._cap,
@@ -245,20 +266,24 @@ class CAF[I]:
245
266
  self._cnt + 1,
246
267
  )
247
268
 
248
- def popl(self) -> I:
249
- """Pop single item off from left side.
269
+ def popl(self) -> X:
270
+ """
271
+ .. admonition:: Pop left
272
+
273
+ Pop a single items off the left side of the ``CAF``.
250
274
 
251
275
  :returns: Item popped from left side (front) of circular array.
252
276
  :raises ValueError: When called on an empty circular array.
277
+
253
278
  """
254
279
  if self._cnt > 1:
255
280
  (
256
281
  d,
257
- self._items[self._front],
282
+ self._xs[self._front],
258
283
  self._front,
259
284
  self._cnt,
260
285
  ) = (
261
- self._items[self._front],
286
+ self._xs[self._front],
262
287
  nada,
263
288
  (self._front + 1) % self._cap,
264
289
  self._cnt - 1,
@@ -266,12 +291,12 @@ class CAF[I]:
266
291
  elif self._cnt == 1:
267
292
  (
268
293
  d,
269
- self._items[self._front],
294
+ self._xs[self._front],
270
295
  self._cnt,
271
296
  self._front,
272
297
  self._rear,
273
298
  ) = (
274
- self._items[self._front],
299
+ self._xs[self._front],
275
300
  nada,
276
301
  0,
277
302
  0,
@@ -280,22 +305,26 @@ class CAF[I]:
280
305
  else:
281
306
  msg = 'Method popl called on an empty CAF'
282
307
  raise ValueError(msg)
283
- return cast(I, d)
308
+ return cast(X, d)
284
309
 
285
- def popr(self) -> I:
286
- """Pop single item off from right side.
310
+ def popr(self) -> X:
311
+ """
312
+ .. admonition:: Pop right
313
+
314
+ Pop a single items off the right side of the ``CAF``.
287
315
 
288
316
  :returns: Item popped from right side (rear) of circular array.
289
317
  :raises ValueError: When called on an empty circular array.
318
+
290
319
  """
291
320
  if self._cnt > 1:
292
321
  (
293
322
  d,
294
- self._items[self._rear],
323
+ self._xs[self._rear],
295
324
  self._rear,
296
325
  self._cnt,
297
326
  ) = (
298
- self._items[self._rear],
327
+ self._xs[self._rear],
299
328
  nada,
300
329
  (self._rear - 1) % self._cap,
301
330
  self._cnt - 1,
@@ -303,12 +332,12 @@ class CAF[I]:
303
332
  elif self._cnt == 1:
304
333
  (
305
334
  d,
306
- self._items[self._front],
335
+ self._xs[self._front],
307
336
  self._cnt,
308
337
  self._front,
309
338
  self._rear,
310
339
  ) = (
311
- self._items[self._front],
340
+ self._xs[self._front],
312
341
  nada,
313
342
  0,
314
343
  0,
@@ -317,39 +346,53 @@ class CAF[I]:
317
346
  else:
318
347
  msg = 'Method popr called on an empty CAF'
319
348
  raise ValueError(msg)
320
- return cast(I, d)
349
+ return cast(X, d)
350
+
351
+ def popld(self, default: X) -> X:
352
+ """
353
+ .. admonition:: Pop Left with default
354
+
355
+ Pop a single items off the left side of the ``CAF``.
321
356
 
322
- def popld(self, default: I) -> I:
323
- """Pop one item from left side of the circular array, provide
324
- a mandatory default value. "Safe" version of popl.
357
+ :param default: Default value to return if ``CAF`` is empty.
358
+ :returns: Item popped from left side (front) of circular array
359
+ if not empty, otherwise return the provided default
360
+ value.
325
361
 
326
- :param default: Item returned if circular array is empty.
327
- :returns: Item popped from left side or default item if empty.
328
362
  """
329
363
  try:
330
364
  return self.popl()
331
365
  except ValueError:
332
366
  return default
333
367
 
334
- def poprd(self, default: I) -> I:
335
- """Pop one item from right side of the circular array, provide
336
- a mandatory default value. "Safe" version of popr.
368
+ def poprd(self, default: X) -> X:
369
+ """
370
+ .. admonition:: Pop Right with default
371
+
372
+ Pop a single items off the right side of the ``CAF``.
373
+
374
+ :param default: Default value to return if ``CAF`` is empty.
375
+ :returns: Item popped from right side (rear) of circular array
376
+ if not empty, otherwise return the provided default
377
+ value.
337
378
 
338
- :param default: Item returned if circular array is empty.
339
- :returns: Item popped from right side or default item if empty.
340
379
  """
341
380
  try:
342
381
  return self.popr()
343
382
  except ValueError:
344
383
  return default
345
384
 
346
- def poplt(self, maximum: int) -> tuple[I, ...]:
347
- """Pop multiple items from left side of circular array.
385
+ def poplt(self, maximum: int) -> tuple[X, ...]:
386
+ """
387
+ .. admonition:: Pop multiple items from left
388
+
389
+ Pop items off the left side of the ``CAF``.
390
+
391
+ :param maximum: Maximum number of items to pop, may pop less if not enough items in ``CAF``.
392
+ :returns: A ``tuple`` of the items popped, left to right.
348
393
 
349
- :param maximum: Maximum number of items to pop, may pop less if not enough items.
350
- :returns: Tuple of items in the order popped, left to right.
351
394
  """
352
- item_list: list[I] = []
395
+ item_list: list[X] = []
353
396
 
354
397
  while maximum > 0:
355
398
  try:
@@ -361,13 +404,17 @@ class CAF[I]:
361
404
 
362
405
  return tuple(item_list)
363
406
 
364
- def poprt(self, maximum: int) -> tuple[I, ...]:
365
- """Pop multiple items from right side of circular array.
407
+ def poprt(self, maximum: int) -> tuple[X, ...]:
408
+ """
409
+ .. admonition:: Pop multiple items from right
410
+
411
+ Pop items off the right side of the ``CAF``.
412
+
413
+ :param maximum: Maximum number of items to pop, may pop less if not enough items in ``CAF``.
414
+ :returns: A ``tuple`` of the items popped, right to left.
366
415
 
367
- :param maximum: Maximum number of items to pop, may pop less if not enough items.
368
- :returns: Tuple of items in the order popped, right to left.
369
416
  """
370
- item_list: list[I] = []
417
+ item_list: list[X] = []
371
418
  while maximum > 0:
372
419
  try:
373
420
  item_list.append(self.popr())
@@ -378,9 +425,14 @@ class CAF[I]:
378
425
  return tuple(item_list)
379
426
 
380
427
  def rotl(self, n: int = 1) -> None:
381
- """Rotate items to the left.
428
+ """
429
+ .. admonition:: Rotate left
430
+
431
+ Rotate contents of ``CAF`` to the left putting first
432
+ item onto rear.
433
+
434
+ :param n: Number of times to shift items left. Default 1 time.
382
435
 
383
- :param n: Number of times to shift elements to the left.
384
436
  """
385
437
  if self._cnt < 2:
386
438
  return
@@ -388,35 +440,48 @@ class CAF[I]:
388
440
  self.pushr(self.popl())
389
441
 
390
442
  def rotr(self, n: int = 1) -> None:
391
- """Rotate items to the right.
443
+ """
444
+ .. admonition:: Rotate right
445
+
446
+ Rotate contents of ``CAF`` to the right putting last
447
+ item onto front.
448
+
449
+ :param n: Number of times to shift items right. Default 1 time.
392
450
 
393
- :param n: Number of times to shift elements to the right.
394
451
  """
395
452
  if self._cnt < 2:
396
453
  return
397
454
  for _ in range(n, 0, -1):
398
455
  self.pushl(self.popr())
399
456
 
400
- def map[U](self, f: Callable[[I], U]) -> 'CAF[U]':
401
- """Apply function ``f`` over the circular array's contents,
457
+ def map[Y](self, f: Callable[[X], Y]) -> 'CAF[Y]':
458
+ """
459
+ .. admonition:: Map function over the CAF
460
+
461
+ Apply function ``f`` over the circular array's contents.
402
462
 
403
- :param f: Callable from type ``I`` to type ``U``.
463
+ :param f: Callable from type ``X`` to type ``Y``.
404
464
  :returns: New fixed capacity circular array instance.
465
+
405
466
  """
406
467
  return CAF(map(f, self), cap = self._cap)
407
468
 
408
469
  @overload
409
- def foldl[L](self, f: Callable[[I, I], I]) -> I: ...
470
+ def foldl[L](self, f: Callable[[X, X], X]) -> X: ...
410
471
  @overload
411
- def foldl[L](self, f: Callable[[L, I], L], start: L) -> L: ...
472
+ def foldl[L](self, f: Callable[[L, X], L], start: L) -> L: ...
412
473
 
413
- def foldl[L](self, f: Callable[[L, I], L], start: L | NoValue = nada) -> L:
414
- """Fold left with a function and optional stating item.
474
+ def foldl[L](self, f: Callable[[L, X], L], start: L | NoValue = nada) -> L:
475
+ """
476
+ .. admonition:: Fold left
477
+
478
+ Fold ``CAF`` left with a function and optional starting item.
415
479
 
416
480
  :param f: Folding function, first argument to ``f`` is for the accumulator.
417
481
  :param start: Optional starting item.
418
482
  :returns: Reduced value produced by the left fold.
419
- :raises ValueError: When circular array empty and no starting item given.
483
+ :raises ValueError: When circular array empty and ``start`` not given.
484
+
420
485
  """
421
486
  if self._cnt == 0:
422
487
  if start is nada:
@@ -436,17 +501,21 @@ class CAF[I]:
436
501
  return acc
437
502
 
438
503
  @overload
439
- def foldr[R](self, f: Callable[[I, I], I]) -> I: ...
504
+ def foldr[R](self, f: Callable[[X, X], X]) -> X: ...
440
505
  @overload
441
- def foldr[R](self, f: Callable[[I, R], R], start: R) -> R: ...
506
+ def foldr[R](self, f: Callable[[X, R], R], start: R) -> R: ...
507
+
508
+ def foldr[R](self, f: Callable[[X, R], R], start: R | NoValue = nada) -> R:
509
+ """
510
+ .. admonition:: Fold right
442
511
 
443
- def foldr[R](self, f: Callable[[I, R], R], start: R | NoValue = nada) -> R:
444
- """Fold right with a function and an optional starting item.
512
+ Fold ``CAF`` right left with a function and optional starting item.
445
513
 
446
514
  :param f: Folding function, second argument to ``f`` is for the accumulator.
447
515
  :param start: Optional starting item.
448
516
  :returns: Reduced value produced by the right fold.
449
- :raises ValueError: When circular array empty and no starting item given.
517
+ :raises ValueError: When circular array empty and ``start`` not given.
518
+
450
519
  """
451
520
  if self._cnt == 0:
452
521
  if start is nada:
@@ -466,16 +535,26 @@ class CAF[I]:
466
535
  return acc
467
536
 
468
537
  def capacity(self) -> int:
469
- """Return fixed storage capacity of the circular array.
538
+ """
539
+ .. admonition:: Get capacity
540
+
541
+ Get the fixed storage capacity of the circular array.
542
+
470
543
 
471
544
  :returns: Fixed storage capacity.
545
+
472
546
  """
473
547
  return self._cap
474
548
 
475
549
  def empty(self) -> None:
476
- """Empty the circular array."""
550
+ """
551
+ .. admonition:: Empty circular array
552
+
553
+ Empty the circular array, keep current storage capacity.
554
+
555
+ """
477
556
  (
478
- self._items,
557
+ self._xs,
479
558
  self._front,
480
559
  self._rear,
481
560
  self._cnt,
@@ -487,18 +566,26 @@ class CAF[I]:
487
566
  )
488
567
 
489
568
  def fraction_filled(self) -> float:
490
- """Find fraction of the storage capacity which is filled.
569
+ """
570
+ .. admonition:: Get fraction filled
571
+
572
+ Find fraction of the storage capacity which is filled.
491
573
 
492
574
  :returns: The ratio count/capacity.
575
+
493
576
  """
494
577
  return self._cnt / self._cap
495
578
 
496
579
 
497
- def caf[T](*items: T, cap: int = 2) -> CAF[T]:
498
- """Produce a circular array from a variable number of arguments.
580
+ def caf[T](*ts: T, cap: int = 2) -> CAF[T]:
581
+ """
582
+ .. admonition:: Circular array factory function
583
+
584
+ Produce a circular array from a variable number of arguments.
499
585
 
500
- :param items: Initial items for a new fixed capacity :circular array.
586
+ :param ts: Initial items for a new fixed capacity circular array.
501
587
  :param cap: The minimum storage capacity to set.
502
588
  :returns: New fixed storage capacity circular array.
589
+
503
590
  """
504
- return CAF(items, cap=cap)
591
+ return CAF(ts, cap=cap)