aisp 0.1.41__py3-none-any.whl → 0.1.42__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.
aisp/utils/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """Utility functions and helpers for development."""
2
+
2
3
  from ._multiclass import slice_index_list_by_class
3
4
 
4
5
  __author__ = "João Paulo da Silva Barros"
5
6
  __all__ = ["slice_index_list_by_class"]
6
- __version__ = "0.1.35"
aisp/utils/_multiclass.py CHANGED
@@ -6,24 +6,30 @@ import numpy.typing as npt
6
6
 
7
7
 
8
8
  def slice_index_list_by_class(classes: Union[npt.NDArray, list], y: npt.NDArray) -> dict:
9
- """
10
- The function ``slice_index_list_by_class(...)``, separates the indices of the lines according
11
- to the output class, to loop through the sample array, only in positions where the output is the
12
- class being trained.
9
+ """Separate indices of samples by class for targeted iteration.
13
10
 
14
11
  Parameters
15
12
  ----------
16
- * classes (``list or npt.NDArray``): list with unique classes.
17
- * y (``npt.NDArray``): Receives a ``y``[``N sample``] array with the output classes of the
18
- ``X`` sample array.
13
+ classes: list or npt.NDArray
14
+ list with unique classes.
15
+ y : npt.NDArray
16
+ Receives a ``y``[``N sample``] array with the output classes of the ``X`` sample array.
19
17
 
20
- returns
21
- ----------
22
- * dict: A dictionary with the list of array positions(``y``), with the classes as key.
18
+ Returns
19
+ -------
20
+ position_samples : dict
21
+ A dictionary with the list of array positions(``y``), with the classes as key.
22
+
23
+ Examples
24
+ --------
25
+ >>> import numpy as np
26
+ >>> labels = ['a', 'b', 'c']
27
+ >>> y = np.array(['a', 'c', 'b', 'a', 'c', 'b'])
28
+ >>> slice_index_list_by_class(labels, y)
29
+ {'a': [0, 3], 1: [2, 5], 2: [1, 4]}
23
30
  """
24
31
  position_samples = {}
25
32
  for _class_ in classes:
26
33
  # Gets the sample positions by class from y.
27
- position_samples[_class_] = list(np.nonzero(y == _class_)[0])
28
-
34
+ position_samples[_class_] = np.flatnonzero(y == _class_).tolist()
29
35
  return position_samples
aisp/utils/distance.py CHANGED
@@ -3,6 +3,7 @@
3
3
  import numpy as np
4
4
  import numpy.typing as npt
5
5
  from numba import njit, types
6
+ from numpy import float64
6
7
 
7
8
  EUCLIDEAN = 0
8
9
  MANHATTAN = 1
@@ -11,95 +12,105 @@ HAMMING = 3
11
12
 
12
13
 
13
14
  @njit([(types.boolean[:], types.boolean[:])], cache=True)
14
- def hamming(u: npt.NDArray[np.bool_], v: npt.NDArray[np.bool_]) -> np.float64:
15
- """
16
- Function to calculate the normalized Hamming distance between two points.
15
+ def hamming(u: npt.NDArray[np.bool_], v: npt.NDArray[np.bool_]) -> float64:
16
+ """Calculate the normalized Hamming distance between two points.
17
17
 
18
18
  ((x₁ ≠ x₂) + (y₁ ≠ y₂) + ... + (yn ≠ yn)) / n
19
19
 
20
20
  Parameters
21
21
  ----------
22
- * u (``npt.NDArray``): Coordinates of the first point.
23
- * v (``npt.NDArray``): Coordinates of the second point.
22
+ u : npt.NDArray[np.bool_]
23
+ Coordinates of the first point.
24
+ v : npt.NDArray[np.bool_]
25
+ Coordinates of the second point.
24
26
 
25
- returns
26
- ----------
27
- * Distance (``float``) between the two points.
27
+ Returns
28
+ -------
29
+ Distance : np.float64
30
+ Distance : float``) between the two points.
28
31
  """
29
32
  n = len(u)
30
33
  if n == 0:
31
- return 0.0
34
+ return float64(0.0)
32
35
 
33
- return np.sum(u != v) / n
36
+ return np.float64(np.sum(u != v) / n)
34
37
 
35
38
 
36
39
  @njit()
37
- def euclidean(u: npt.NDArray[np.float64], v: npt.NDArray[np.float64]) -> np.float64:
38
- """
39
- Function to calculate the normalized Euclidean distance between two points.
40
+ def euclidean(u: npt.NDArray[np.float64], v: npt.NDArray[np.float64]) -> float64:
41
+ """Calculate the normalized Euclidean distance between two points.
40
42
 
41
43
  √( (x₁ – x₂)² + (y₁ – y₂)² + ... + (yn – yn)²)
42
44
 
43
45
  Parameters
44
46
  ----------
45
- * u (``npt.NDArray``): Coordinates of the first point.
46
- * v (``npt.NDArray``): Coordinates of the second point.
47
+ u : npt.NDArray[float64]
48
+ Coordinates of the first point.
49
+ v : npt.NDArray[float64]
50
+ Coordinates of the second point.
47
51
 
48
- returns
49
- ----------
50
- * Distance (``float``) between the two points.
52
+ Returns
53
+ -------
54
+ distance : float64
55
+ Distance : float``) between the two points.
51
56
  """
52
- return np.linalg.norm(u - v)
57
+ return float64(np.linalg.norm(u - v))
53
58
 
54
59
 
55
60
  @njit()
56
- def cityblock(u: npt.NDArray[np.float64], v: npt.NDArray[np.float64]) -> np.float64:
57
- """
58
- Function to calculate the normalized Manhattan distance between two points.
61
+ def cityblock(u: npt.NDArray[float64], v: npt.NDArray[float64]) -> float64:
62
+ """Calculate the normalized Manhattan distance between two points.
59
63
 
60
64
  (|x₁ – x₂| + |y₁ – y₂| + ... + |yn – yn|) / n
61
65
 
62
66
  Parameters
63
67
  ----------
64
- * u (``npt.NDArray``): Coordinates of the first point.
65
- * v (``npt.NDArray``): Coordinates of the second point.
68
+ u : npt.NDArray[float64]
69
+ Coordinates of the first point.
70
+ v : npt.NDArray[float64]
71
+ Coordinates of the second point.
66
72
 
67
- returns
68
- ----------
69
- * Distance (``float``) between the two points.
73
+ Returns
74
+ -------
75
+ distance : float64
76
+ Distance (``float``) between the two points.
70
77
  """
71
78
  n = len(u)
72
79
  if n == 0:
73
- return -1.0
80
+ return float64(-1.0)
74
81
 
75
- return np.sum(np.abs(u - v)) / n
82
+ return float64(np.sum(np.abs(u - v)) / n)
76
83
 
77
84
 
78
85
  @njit()
79
- def minkowski(u: npt.NDArray[np.float64], v: npt.NDArray[np.float64], p: float = 2.0):
80
- """
81
- Function to calculate the normalized Minkowski distance between two points.
86
+ def minkowski(u: npt.NDArray[float64], v: npt.NDArray[float64], p: float = 2.0) -> float64:
87
+ """Calculate the normalized Minkowski distance between two points.
82
88
 
83
89
  (( |X₁ – Y₁|p + |X₂ – Y₂|p + ... + |Xn – Yn|p) ¹/ₚ.) / n
84
90
 
85
91
  Parameters
86
92
  ----------
87
- * u (``npt.NDArray``): Coordinates of the first point.
88
- * v (``npt.NDArray``): Coordinates of the second point.
89
- * p float: The p parameter defines the type of distance to be calculated:
93
+ u : npt.NDArray[float64]
94
+ Coordinates of the first point.
95
+ v : npt.NDArray[float64]
96
+ Coordinates of the second point.
97
+ p : float
98
+ The p parameter defines the type of distance to be calculated:
99
+
90
100
  - p = 1: **Manhattan** distance — sum of absolute differences.
91
101
  - p = 2: **Euclidean** distance — sum of squared differences (square root).
92
102
  - p > 2: **Minkowski** distance with an increasing penalty as p increases.
93
103
 
94
- returns
95
- ----------
96
- * Distance (``float``) between the two points.
104
+ Returns
105
+ -------
106
+ float64
107
+ Distance (``float``) between the two points.
97
108
  """
98
109
  n = len(u)
99
110
  if n == 0:
100
- return -1.0
111
+ return float64(-1.0)
101
112
 
102
- return (np.sum(np.abs(u - v) ** p) ** (1 / p)) / n
113
+ return float64((np.sum(np.abs(u - v) ** p) ** (1 / p)) / n)
103
114
 
104
115
 
105
116
  @njit(
@@ -110,26 +121,29 @@ def minkowski(u: npt.NDArray[np.float64], v: npt.NDArray[np.float64], p: float =
110
121
  cache=True
111
122
  )
112
123
  def compute_metric_distance(
113
- u: npt.NDArray[np.float64],
114
- v: npt.NDArray[np.float64],
124
+ u: npt.NDArray[float64],
125
+ v: npt.NDArray[float64],
115
126
  metric: int,
116
- p: np.float64 = 2.0
117
- ) -> np.float64:
118
- """
119
- Function to calculate the distance between two points by the chosen ``metric``.
127
+ p: float64 = 2.0
128
+ ) -> float64:
129
+ """Calculate the distance between two points by the chosen metric.
120
130
 
121
131
  Parameters
122
132
  ----------
123
- * u (``npt.NDArray``): Coordinates of the first point.
124
- * v (``npt.NDArray``): Coordinates of the second point.
125
- * metric (``int``): Distance metric to be used. Available options:
126
- [0 (Euclidean), 1 (Manhattan), 2 (Minkowski)]
127
- * p (``float``): Parameter for the Minkowski distance (used only if `metric`
128
- is "minkowski").
129
-
130
- returns
131
- ----------
132
- * Distance (``double``) between the two points with the selected metric.
133
+ u : npt.NDArray[float64]
134
+ Coordinates of the first point.
135
+ v : npt.NDArray[float64]
136
+ Coordinates of the second point.
137
+ metric : int
138
+ Distance metric to be used. Available options: [0 (Euclidean), 1 (Manhattan),
139
+ 2 (Minkowski)]
140
+ p : float, default=2.0
141
+ Parameter for the Minkowski distance (used only if `metric` is "minkowski").
142
+
143
+ Returns
144
+ -------
145
+ float64
146
+ Distance (``float``) between the two points with the selected metric.
133
147
  """
134
148
  if metric == MANHATTAN:
135
149
  return cityblock(u, v)
@@ -147,29 +161,31 @@ def compute_metric_distance(
147
161
  cache=True
148
162
  )
149
163
  def min_distance_to_class_vectors(
150
- x_class: npt.NDArray[np.float64],
151
- vector_x: npt.NDArray[np.float64],
164
+ x_class: npt.NDArray[float64],
165
+ vector_x: npt.NDArray[float64],
152
166
  metric: int,
153
167
  p: float = 2.0
154
168
  ) -> float:
155
- """
156
- Calculates the minimum distance between an input vector and the vectors of a class.
169
+ """Calculate the minimum distance between an input vector and the vectors of a class.
157
170
 
158
171
  Parameters
159
172
  ----------
160
- * x_class (``npt.NDArray``): Array containing the class vectors to be compared
161
- with the input vector. Expected shape: (n_samples, n_features).
162
- * vector_x (``npt.NDArray``): Vector to be compared with the class vectors.
163
- Expected shape: (n_features,).
164
- * metric (``str``): Distance metric to be used. Available options:
165
- ["hamming", "cityblock", "minkowski", "euclidean"]
166
- * p (``float``): Parameter for the Minkowski distance (used only if `metric`
167
- is "minkowski").
173
+ x_class : npt.NDArray[float64]
174
+ Array containing the class vectors to be compared with the input vector. Expected shape:
175
+ (n_samples, n_features).
176
+ vector_x : npt.NDArray[float64]
177
+ Vector to be compared with the class vectors. Expected shape: (n_features,).
178
+ metric : int
179
+ Distance metric to be used. Available options: ["hamming", "cityblock", "minkowski",
180
+ "euclidean"]
181
+ p : float, default=2.0
182
+ Parameter for the Minkowski distance (used only if `metric` is "minkowski").
168
183
 
169
184
  Returns
170
- ----------
171
- * float: The minimum distance calculated between the input vector and the class vectors.
172
- * Returns -1.0 if the input dimensions are incompatible.
185
+ -------
186
+ min_distance : float:
187
+ The minimum distance calculated between the input vector and the class vectors.
188
+ Returns -1.0 if the input dimensions are incompatible.
173
189
  """
174
190
  n = x_class.shape[1]
175
191
  if n != vector_x.shape[0]:
@@ -184,20 +200,22 @@ def min_distance_to_class_vectors(
184
200
 
185
201
 
186
202
  def get_metric_code(metric: str) -> int:
187
- """
188
- Returns the numeric code associated with a distance metric.
203
+ """Get the numeric code associated with a distance metric.
189
204
 
190
205
  Parameters
191
206
  ----------
192
- * metric (str): Name of the metric. Can be "euclidean", "manhattan", "minkowski" or "hamming".
207
+ metric : str
208
+ Name of the metric. Can be "euclidean", "manhattan", "minkowski" or "hamming".
193
209
 
194
210
  Raises
195
- ----------
196
- * ValueError: If the metric provided is not supported.
211
+ ------
212
+ ValueError
213
+ If the metric provided is not supported.
197
214
 
198
215
  Returns
199
- ----------
200
- * int: Numeric code corresponding to the metric.
216
+ -------
217
+ int
218
+ Numeric code corresponding to the metric.
201
219
  """
202
220
  metric_map = {
203
221
  "euclidean": EUCLIDEAN,
aisp/utils/metrics.py CHANGED
@@ -1,4 +1,5 @@
1
1
  """Utility functions for measuring accuracy and performance."""
2
+
2
3
  from typing import Union
3
4
 
4
5
  import numpy as np
@@ -9,23 +10,24 @@ def accuracy_score(
9
10
  y_true: Union[npt.NDArray, list],
10
11
  y_pred: Union[npt.NDArray, list]
11
12
  ) -> float:
12
- """
13
- Function to calculate the accuracy score based on true and predicted labels.
13
+ """Calculate the accuracy score based on true and predicted labels.
14
14
 
15
15
  Parameters
16
16
  ----------
17
- * y_true ()``Union[npt.NDArray, list]``):
17
+ y_true : Union[npt.NDArray, list]
18
18
  Ground truth (correct) labels. Expected to be of the same length as `y_pred`.
19
- * y_pred (``Union[npt.NDArray, list]``):
19
+ y_pred : Union[npt.NDArray, list]
20
20
  Predicted labels. Expected to be of the same length as `y_true`.
21
21
 
22
22
  Returns
23
- ----------
24
- * float: The ratio of correct predictions to the total number of predictions.
23
+ -------
24
+ accuracy : float
25
+ The ratio of correct predictions to the total number of predictions.
25
26
 
26
27
  Raises
27
- ----------
28
- * ValueError: If `y_true` or `y_pred` are empty or if they do not have the same length.
28
+ ------
29
+ ValueError
30
+ If `y_true` or `y_pred` are empty or if they do not have the same length.
29
31
  """
30
32
  n = len(y_true)
31
33
  if n == 0:
aisp/utils/sanitizers.py CHANGED
@@ -1,4 +1,5 @@
1
1
  """Utility functions for validation and treatment of parameters."""
2
+
2
3
  from typing import TypeVar, Iterable, Callable, Any, Optional
3
4
 
4
5
  T = TypeVar('T')
@@ -6,50 +7,58 @@ T = TypeVar('T')
6
7
 
7
8
  def sanitize_choice(value: T, valid_choices: Iterable[T], default: T) -> T:
8
9
  """
9
- Returns the value if it is present in the set of valid choices; otherwise,
10
- returns the default value.
10
+ Value if present in the set of valid choices; otherwise, the default value.
11
11
 
12
12
  Parameters
13
13
  ----------
14
- * value (``T``): The value to be checked.
15
- * valid_choices (``Iterable[T]``): A collection of valid choices.
16
- * default: The default value to be returned if 'value' is not in 'valid_choices'.
14
+ value : T
15
+ The value to be checked.
16
+ valid_choices : Iterable[T]
17
+ A collection of valid choices.
18
+ default : T
19
+ The default value to be returned if 'value' is not in 'valid_choices'.
17
20
 
18
21
  Returns
19
- ----------
20
- * The original value if valid, or the default value if not.
22
+ -------
23
+ value : T
24
+ The original value if valid, or the default value if not.
21
25
  """
22
26
  return value if value in valid_choices else default
23
27
 
24
28
 
25
29
  def sanitize_param(value: T, default: T, condition: Callable[[T], bool]) -> T:
26
30
  """
27
- Returns the value if it satisfies the specified condition; otherwise, returns the default value.
31
+ Value if it satisfies the specified condition; otherwise, the default value.
28
32
 
29
33
  Parameters
30
34
  ----------
31
- * value: The value to be checked.
32
- * default (``T``): The default value to be returned if the condition is not satisfied.
33
- * condition (``Callable[[T], bool]``): A function that takes a value and returns a boolean,
34
- determining if the value is valid.
35
+ value : T
36
+ The value to be checked.
37
+ default : T
38
+ The default value to be returned if the condition is not satisfied.
39
+ condition : Callable[[T], bool]
40
+ A function that takes a value and returns a boolean, determining if the value is valid.
35
41
 
36
42
  Returns
37
- ----------
38
- * T: The original value if the condition is satisfied, or the default value if not.
43
+ -------
44
+ value : T
45
+ The original value if the condition is satisfied, or the default value if not.
39
46
  """
40
47
  return value if condition(value) else default
41
48
 
42
49
 
43
50
  def sanitize_seed(seed: Any) -> Optional[int]:
44
51
  """
45
- Returns the seed if it is a non-negative integer; otherwise, returns None.
52
+ Seed if it is a non-negative integer; otherwise, None.
46
53
 
47
54
  Parameters
48
55
  ----------
49
- * seed (``Any``): The seed value to be validated.
56
+ seed : Any
57
+ The seed value to be validated.
50
58
 
51
59
  Returns
52
- ----------
53
- * Optional[int]: The original seed if it is a non-negative integer, or None if it is invalid.
60
+ -------
61
+ seed : Optional[int]
62
+ The original seed if it is a non-negative integer, or None if it is invalid.
54
63
  """
55
64
  return seed if isinstance(seed, int) and seed >= 0 else None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aisp
3
- Version: 0.1.41
3
+ Version: 0.1.42
4
4
  Summary: Package with techniques of artificial immune systems.
5
5
  Author-email: João Paulo da Silva Barros <jpsilvabarr@gmail.com>
6
6
  Maintainer-email: Alison Zille Lopes <alisonzille@gmail.com>
@@ -0,0 +1,18 @@
1
+ aisp/__init__.py,sha256=N5aAyup46_tqU9cXfYfGuR3bdfAjcvaPc1xwFdGdD7A,112
2
+ aisp/exceptions.py,sha256=M2H_oM-ccIkDGpeFA3CyklZlgMcjTVvOCTGLU2sxFi8,1447
3
+ aisp/base/__init__.py,sha256=k2Ww9hej_32ekYhhCiYGEMLgOmDKwRt261HZ8rEurwA,102
4
+ aisp/base/_classifier.py,sha256=_HJiL1fCNqoB5KlNUN5pH9Yuu_btOze39h0SdnBw7ug,3672
5
+ aisp/nsa/__init__.py,sha256=3cXuBmO-_Dp3-8ZG3Eu8e_bD1JDb-RH4Wu0UDNVD1bs,385
6
+ aisp/nsa/_base.py,sha256=D_N-VIESvGFhdf_A2NETV-JaZJ6ISankrbRzWXSMiXM,4140
7
+ aisp/nsa/_negative_selection.py,sha256=-hqMspYvtPAb38qV1_NF5HmDCOGDWGL89BZ3M4eHiao,28141
8
+ aisp/nsa/_ns_core.py,sha256=SXkZL-p2VQygU4Pf6J5AP_yPzU4cR6aU6wx-e_vlm-c,5021
9
+ aisp/utils/__init__.py,sha256=RzpKhkg8nCZi4G0C4il97f3ESYs7Bbxq6EjTeOQQUGk,195
10
+ aisp/utils/_multiclass.py,sha256=nWd58ayVfxgdopBQc9b_xywkolJ2fGW3AN-JoD2A9Fw,1134
11
+ aisp/utils/distance.py,sha256=pIt76OUiwCry6eNEuWLYvUiW4KkeU6egjjnnmroFet8,6556
12
+ aisp/utils/metrics.py,sha256=zDAScDbHRnfu24alRcZ6fEIUaWNoCD-QCtOCFBWPPo8,1277
13
+ aisp/utils/sanitizers.py,sha256=u1GizdJ-RKfPWJLnuFiM09lpItZMhDR_EvK8YdVHwDk,1858
14
+ aisp-0.1.42.dist-info/licenses/LICENSE,sha256=fTqV5eBpeAZO0_jit8j4Ref9ikBSlHJ8xwj5TLg7gFk,7817
15
+ aisp-0.1.42.dist-info/METADATA,sha256=rsVoFnO5H9UV643wtHx7vvNWBxxg6QPcgjrbfQGOF0Y,4818
16
+ aisp-0.1.42.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
17
+ aisp-0.1.42.dist-info/top_level.txt,sha256=Q5aJi_rAVT5UNS1As0ZafoyS5dwNibnoyOYV7RWUB9s,5
18
+ aisp-0.1.42.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.3.1)
2
+ Generator: setuptools (80.8.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,18 +0,0 @@
1
- aisp/__init__.py,sha256=pKOdkhFxWup_lhQPofFTk4rpqd0_IlYygHnkBhE2g2w,111
2
- aisp/exceptions.py,sha256=ONiKCZrBhfUaMO1vYHnOr1_eL9PtVJ7b_HRroMbORpc,1405
3
- aisp/base/__init__.py,sha256=rpb9ADmBtNpRAEJw61c7CsbZhHA2vGQOvjFmpk7w39c,100
4
- aisp/base/_classifier.py,sha256=Dvimv7JVfqeg4ws9NqZPj0Ue_fNh9kEEXrspOrLdBoQ,3845
5
- aisp/nsa/__init__.py,sha256=3-fSIJCMB_jcLGTr6DcVkloRfWyQJ8-JzD0CLhvpvgc,411
6
- aisp/nsa/_base.py,sha256=cT404V5onduK19WW6ajxy_yUZha3Fk8KZJvJHt_UZBM,4250
7
- aisp/nsa/_negative_selection.py,sha256=mWyjRmTMOJxtL8xHDooN3RreyLgq5JqmEb_CYAHBaCk,28485
8
- aisp/nsa/_ns_core.py,sha256=VWt_L2ODXtngJ7BVmSVT7i7kK98axibOmCzbYCkjeqI,4934
9
- aisp/utils/__init__.py,sha256=-r--qdfTq4dVJU-VoJ7dvXTNS5_I1q1aGAQ02zNBOGw,217
10
- aisp/utils/_multiclass.py,sha256=t0RLIdUoUbvFL30a8XfO3BMXc8MimtLCHNbGCDL2BQk,1051
11
- aisp/utils/distance.py,sha256=SZTE5KEB7QX9vKoY9GfFOfFGbswVhQM6-9baLq4ZXns,6304
12
- aisp/utils/metrics.py,sha256=o6aD6qTLQtXhWNOMGjgweHMQ6SMQ2hh42NcSEmgY3RI,1292
13
- aisp/utils/sanitizers.py,sha256=7wJSo5ZkRX1g16C9sEN8TWQ5l9Gzfl0-8CgLULnPNlk,1873
14
- aisp-0.1.41.dist-info/licenses/LICENSE,sha256=fTqV5eBpeAZO0_jit8j4Ref9ikBSlHJ8xwj5TLg7gFk,7817
15
- aisp-0.1.41.dist-info/METADATA,sha256=W0BxdV6IefnxXgDIe-eSa1XvGgFsqqsAnvIDxzL8EGE,4818
16
- aisp-0.1.41.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
17
- aisp-0.1.41.dist-info/top_level.txt,sha256=Q5aJi_rAVT5UNS1As0ZafoyS5dwNibnoyOYV7RWUB9s,5
18
- aisp-0.1.41.dist-info/RECORD,,