flightdata 0.3.3__tar.gz → 0.3.4__tar.gz

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 (99) hide show
  1. {flightdata-0.3.3 → flightdata-0.3.4}/PKG-INFO +3 -3
  2. {flightdata-0.3.3 → flightdata-0.3.4}/pyproject.toml +3 -3
  3. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/base/collection.py +31 -4
  4. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/base/table/labelgroup.py +27 -6
  5. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/flight/flight.py +16 -11
  6. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/flight/parameters.py +1 -1
  7. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/state/state.py +1 -0
  8. {flightdata-0.3.3 → flightdata-0.3.4}/test/base/test_labels.py +32 -5
  9. flightdata-0.3.3/src/flightdata/base/labeling.py +0 -9
  10. {flightdata-0.3.3 → flightdata-0.3.4}/.github/workflows/publish_pypi.yml +0 -0
  11. {flightdata-0.3.3 → flightdata-0.3.4}/.gitignore +0 -0
  12. {flightdata-0.3.3 → flightdata-0.3.4}/.vscode/launch.json +0 -0
  13. {flightdata-0.3.3 → flightdata-0.3.4}/.vscode/settings.json +0 -0
  14. {flightdata-0.3.3 → flightdata-0.3.4}/LICENSE +0 -0
  15. {flightdata-0.3.3 → flightdata-0.3.4}/README.md +0 -0
  16. {flightdata-0.3.3 → flightdata-0.3.4}/examples/__init__.py +0 -0
  17. {flightdata-0.3.3 → flightdata-0.3.4}/examples/data/__init__.py +0 -0
  18. {flightdata-0.3.3 → flightdata-0.3.4}/examples/data/manual_F3A_F23_22_04_28_00000231.json +0 -0
  19. {flightdata-0.3.3 → flightdata-0.3.4}/examples/data/manual_F3A_P23_22_05_31_00000350.json +0 -0
  20. {flightdata-0.3.3 → flightdata-0.3.4}/examples/data/manual_F3A_P23_23_08_11_00000094.json +0 -0
  21. {flightdata-0.3.3 → flightdata-0.3.4}/examples/flight_dynamics/00000150.json +0 -0
  22. {flightdata-0.3.3 → flightdata-0.3.4}/examples/flight_dynamics/__init__.py +0 -0
  23. {flightdata-0.3.3 → flightdata-0.3.4}/examples/flight_dynamics/box.f3a +0 -0
  24. {flightdata-0.3.3 → flightdata-0.3.4}/examples/flight_dynamics/param_id.py +0 -0
  25. {flightdata-0.3.3 → flightdata-0.3.4}/examples/interpolation/slice_linear_interpolation.py +0 -0
  26. {flightdata-0.3.3 → flightdata-0.3.4}/examples/interpolation/st.json +0 -0
  27. {flightdata-0.3.3 → flightdata-0.3.4}/examples/interpolation/temp.py +0 -0
  28. {flightdata-0.3.3 → flightdata-0.3.4}/examples/state_analysis/__init__.py +0 -0
  29. {flightdata-0.3.3 → flightdata-0.3.4}/examples/state_analysis/axes.py +0 -0
  30. {flightdata-0.3.3 → flightdata-0.3.4}/examples/state_analysis/state_fill_plot.py +0 -0
  31. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/__init__.py +0 -0
  32. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/base/__init__.py +0 -0
  33. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/base/numpy_encoder.py +0 -0
  34. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/base/table/__init__.py +0 -0
  35. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/base/table/constructs.py +0 -0
  36. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/base/table/label.py +0 -0
  37. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/base/table/labelgroups.py +0 -0
  38. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/base/table/slicer.py +0 -0
  39. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/base/table/table.py +0 -0
  40. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/bindata.py +0 -0
  41. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/coefficients.py +0 -0
  42. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/environment/__init__.py +0 -0
  43. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/environment/environment.py +0 -0
  44. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/environment/wind.py +0 -0
  45. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/flight/__init__.py +0 -0
  46. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/flight/ardupilot.py +0 -0
  47. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/flight/fields.py +0 -0
  48. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/flow.py +0 -0
  49. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/model/__init__.py +0 -0
  50. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/model/aerodynamic.py +0 -0
  51. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/model/thrust.py +0 -0
  52. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/origin.py +0 -0
  53. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/py.typed +0 -0
  54. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/scripts/collect_logs.py +0 -0
  55. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/scripts/flightline.py +0 -0
  56. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/state/__init__.py +0 -0
  57. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/state/alignment.py +0 -0
  58. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/state/kinematics.py +0 -0
  59. {flightdata-0.3.3 → flightdata-0.3.4}/src/flightdata/state_maker.py +0 -0
  60. {flightdata-0.3.3 → flightdata-0.3.4}/test/EmailedBox.f3a +0 -0
  61. {flightdata-0.3.3 → flightdata-0.3.4}/test/__init__.py +0 -0
  62. {flightdata-0.3.3 → flightdata-0.3.4}/test/base/__init__.py +0 -0
  63. {flightdata-0.3.3 → flightdata-0.3.4}/test/base/test_base_constructs.py +0 -0
  64. {flightdata-0.3.3 → flightdata-0.3.4}/test/base/test_table.py +0 -0
  65. {flightdata-0.3.3 → flightdata-0.3.4}/test/conftest.py +0 -0
  66. {flightdata-0.3.3 → flightdata-0.3.4}/test/data/bin_parser_GPS.csv +0 -0
  67. {flightdata-0.3.3 → flightdata-0.3.4}/test/data/bin_parser_POS.csv +0 -0
  68. {flightdata-0.3.3 → flightdata-0.3.4}/test/data/make_inputs.py +0 -0
  69. {flightdata-0.3.3 → flightdata-0.3.4}/test/data/manual_F3A_P23.json +0 -0
  70. {flightdata-0.3.3 → flightdata-0.3.4}/test/data/old_state.json +0 -0
  71. {flightdata-0.3.3 → flightdata-0.3.4}/test/data/p23.BIN +0 -0
  72. {flightdata-0.3.3 → flightdata-0.3.4}/test/data/p23.json +0 -0
  73. {flightdata-0.3.3 → flightdata-0.3.4}/test/data/p23_box.f3a +0 -0
  74. {flightdata-0.3.3 → flightdata-0.3.4}/test/data/p23_fc.json +0 -0
  75. {flightdata-0.3.3 → flightdata-0.3.4}/test/data/p23_flight.json +0 -0
  76. {flightdata-0.3.3 → flightdata-0.3.4}/test/data/script_tests/c6_on_0001.BIN +0 -0
  77. {flightdata-0.3.3 → flightdata-0.3.4}/test/data/script_tests/center_0003.bin +0 -0
  78. {flightdata-0.3.3 → flightdata-0.3.4}/test/data/script_tests/pilot_0004.BIN +0 -0
  79. {flightdata-0.3.3 → flightdata-0.3.4}/test/data/vtol_hover.bin +0 -0
  80. {flightdata-0.3.3 → flightdata-0.3.4}/test/data/vtol_hover.json +0 -0
  81. {flightdata-0.3.3 → flightdata-0.3.4}/test/data/web_bin_parse.json +0 -0
  82. {flightdata-0.3.3 → flightdata-0.3.4}/test/test_bindata.py +0 -0
  83. {flightdata-0.3.3 → flightdata-0.3.4}/test/test_dtw.py +0 -0
  84. {flightdata-0.3.3 → flightdata-0.3.4}/test/test_environment/__init__.py +0 -0
  85. {flightdata-0.3.3 → flightdata-0.3.4}/test/test_environment/test_environment.py +0 -0
  86. {flightdata-0.3.3 → flightdata-0.3.4}/test/test_environment/test_environment_wind.py +0 -0
  87. {flightdata-0.3.3 → flightdata-0.3.4}/test/test_fields.py +0 -0
  88. {flightdata-0.3.3 → flightdata-0.3.4}/test/test_flight.py +0 -0
  89. {flightdata-0.3.3 → flightdata-0.3.4}/test/test_model/__init__.py +0 -0
  90. {flightdata-0.3.3 → flightdata-0.3.4}/test/test_model/test_model_coefficients.py +0 -0
  91. {flightdata-0.3.3 → flightdata-0.3.4}/test/test_model/test_model_flow.py +0 -0
  92. {flightdata-0.3.3 → flightdata-0.3.4}/test/test_origin.py +0 -0
  93. {flightdata-0.3.3 → flightdata-0.3.4}/test/test_scripts.py +0 -0
  94. {flightdata-0.3.3 → flightdata-0.3.4}/test/test_state/__init__.py +0 -0
  95. {flightdata-0.3.3 → flightdata-0.3.4}/test/test_state/test_state.py +0 -0
  96. {flightdata-0.3.3 → flightdata-0.3.4}/test/test_state/test_state_builders.py +0 -0
  97. {flightdata-0.3.3 → flightdata-0.3.4}/test/test_state/test_state_conversions.py +0 -0
  98. {flightdata-0.3.3 → flightdata-0.3.4}/test/test_state/test_state_measurements.py +0 -0
  99. {flightdata-0.3.3 → flightdata-0.3.4}/uv.lock +0 -0
@@ -1,14 +1,14 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flightdata
3
- Version: 0.3.3
3
+ Version: 0.3.4
4
4
  Summary: Python tools for handling flight data
5
5
  Author-email: Thomas David <thomasdavid0@gmail.com>
6
6
  License-File: LICENSE
7
7
  Requires-Python: >=3.12
8
8
  Requires-Dist: numpy>=2.1.3
9
9
  Requires-Dist: pandas>=2.2.3
10
- Requires-Dist: pfc-geometry>=0.2.17
11
- Requires-Dist: pfcschemas>=0.1.10
10
+ Requires-Dist: pfc-geometry>=0.2.19
11
+ Requires-Dist: pfcschemas>=0.1.12
12
12
  Requires-Dist: simplejson>=3.20.1
13
13
  Provides-Extra: dataflash
14
14
  Requires-Dist: ardupilot-log-reader; extra == 'dataflash'
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "flightdata"
3
- version = "0.3.3"
3
+ version = "0.3.4"
4
4
  description = "Python tools for handling flight data"
5
5
  readme = "README.md"
6
6
  authors = [{ name = "Thomas David", email = "thomasdavid0@gmail.com" }]
@@ -8,8 +8,8 @@ requires-python = ">=3.12"
8
8
  dependencies = [
9
9
  "numpy>=2.1.3",
10
10
  "pandas>=2.2.3",
11
- "pfc-geometry>=0.2.17",
12
- "pfcschemas>=0.1.10",
11
+ "pfc-geometry>=0.2.19",
12
+ "pfcschemas>=0.1.12",
13
13
  "simplejson>=3.20.1",
14
14
  ]
15
15
 
@@ -70,6 +70,11 @@ class Collection:
70
70
 
71
71
  def filter_items(self, fun: Callable[[str, T], bool]):
72
72
  return self.__class__({k: v for k, v in self.items() if fun(k, v)})
73
+
74
+ def index(self, key: str) -> int:
75
+ if key in self.data:
76
+ return list(self.data.keys()).index(key)
77
+ raise KeyError(f"{key} not found in {self.__class__}")
73
78
 
74
79
  def to_list(self) -> list[T]:
75
80
  return list(self.values())
@@ -93,17 +98,18 @@ class Collection:
93
98
  if isinstance(v, self.VType):
94
99
  odata[getattr(v, self.uid)] = v
95
100
  elif isinstance(v, self.__class__):
96
- odata = dict(**odata, **v.data)
101
+ odata = odata | v.data #dict(**odata, **v.data)
97
102
  elif isinstance(v, list):
98
- odata = dict(**odata, **{getattr(d, self.uid): d for d in v})
103
+ odata = odata | {getattr(d, self.uid): d for d in v}
99
104
  if inplace:
100
105
  self.data = odata
101
106
  return v
102
107
  else:
103
108
  return self.__class__(odata)
104
109
 
105
- def concat(self, vs: list[Self]) -> Self:
106
- coll = self.__class__([])
110
+ @classmethod
111
+ def concat(Cls, vs: list) -> Self:
112
+ coll = Cls([])
107
113
  for v in vs:
108
114
  coll.add(v)
109
115
  return coll
@@ -144,6 +150,27 @@ class Collection:
144
150
  def __len__(self) -> int:
145
151
  return len(self.data)
146
152
 
153
+ def remove(self, key_or_id: str | int) -> Self:
154
+ if isinstance(key_or_id, int):
155
+ key_or_id = list(self.data.keys())[key_or_id]
156
+ return self.__class__({k: v for k, v in self.data.items() if k != key_or_id})
157
+
158
+ def replace(self, key_or_id: str | int, v: T, inplace=False) -> Self:
159
+ if isinstance(key_or_id, int):
160
+ key_or_id = list(self.data.keys())[key_or_id]
161
+ if not hasattr(v, self.uid):
162
+ raise ValueError(f"Value {v} does not have a {self.uid} attribute")
163
+ if not inplace:
164
+ new_data = self.data.copy()
165
+ new_data[key_or_id] = v
166
+ return self.__class__(new_data)
167
+ else:
168
+ if key_or_id in self.data:
169
+ self.data[key_or_id] = v
170
+ else:
171
+ raise KeyError(f"{key_or_id} not found in {self.__class__}")
172
+ return self
173
+
147
174
  @property
148
175
  def uids(self) -> list[str]:
149
176
  return list(self.data.keys())
@@ -1,4 +1,5 @@
1
1
  from __future__ import annotations
2
+ import enum
2
3
  import numpy as np
3
4
  import pandas as pd
4
5
  import numpy.typing as npt
@@ -73,6 +74,20 @@ class LabelGroup:
73
74
  if len(labels) == len(t):
74
75
  labels= labels[:-1]
75
76
  assert len(labels) == len(t) - 1
77
+ labels=labels.astype(object)
78
+ change_ids = np.where(labels[:-1] != labels[1:])[0] + 1
79
+
80
+ newlabnames = [labels[0]]
81
+ for i, oldlabname in enumerate(labels[change_ids]):
82
+ newlabname = oldlabname
83
+ suffix=1
84
+ while newlabname in newlabnames:
85
+ newlabname = f"{oldlabname}_{suffix}"
86
+ suffix+=1
87
+ newlabnames.append(newlabname)
88
+ if not newlabname == oldlabname:
89
+ labels[change_ids[i]:change_ids[i+1] if i+1<len(change_ids) else None] = newlabname
90
+
76
91
  labnames = pd.unique(labels)
77
92
  data = {}
78
93
  for i, label_name in enumerate(labnames):
@@ -173,7 +188,7 @@ class LabelGroup:
173
188
  )
174
189
 
175
190
  #st: Self = flown.__class__(flown.data).label(**mans.to_dict(orient="list"))
176
- return LabelGroup.read_array(b, mans.a)
191
+ return LabelGroup.read_array(b, mans.a.values)
177
192
  # return self.update(lambda v: v.transfer(a, b, path))
178
193
  @property
179
194
  def widths(self):
@@ -181,7 +196,7 @@ class LabelGroup:
181
196
 
182
197
  @property
183
198
  def boundaries(self) -> list[float]:
184
- return [v.stop for v in self.values()]
199
+ return np.array([v.stop for v in self.values()])
185
200
 
186
201
  @property
187
202
  def boundary_dict(self) -> dict[str, float]:
@@ -220,13 +235,13 @@ class LabelGroup:
220
235
  def step_boundary(self, key: str | int, steps: int, t: npt.NDArray, min_len: int):
221
236
  """Step the stop time of a label, and the start of the next label by steps timesteps"""
222
237
  ilg = self.to_iloc(t)
223
- iboundaries = [0] + ilg.boundaries
238
+ iboundaries = np.concatenate([np.array([0]), ilg.boundaries])
224
239
  lengths = [b1-b0 for b0, b1 in zip(iboundaries[:-1], iboundaries[1:])]
225
240
  index = list(self.keys()).index(key) if isinstance(key, str) else key
226
241
  # new_iloc = np.where(t==self[index].stop)[0][0] + steps
227
242
 
228
243
 
229
- if lengths[index] >= -steps + min_len -1 and lengths[index+1] >= steps + min_len - 1:
244
+ if lengths[index] + steps + 1 >= min_len and lengths[index+1] - steps + 1>= min_len :
230
245
 
231
246
  ilg[index].stop = ilg[index].stop + steps
232
247
  if index < len(ilg) - 1:
@@ -275,7 +290,10 @@ class LabelGroup:
275
290
  """
276
291
 
277
292
  if len(names) > 1:
278
- return self.insert(names[:-1], loc)
293
+ new = self.copy()
294
+ for i, name in enumerate(names):
295
+ new = new.insert(loc+i, [name])
296
+ return new
279
297
 
280
298
  new_labels = {}
281
299
  for i, (k, v) in enumerate(self.items()):
@@ -297,7 +315,7 @@ class LabelGroup:
297
315
  inserts = []
298
316
  new_labs = {}
299
317
  while ii < len(keys):
300
- if labs[il] == keys[ii]:
318
+ if il<len(labs) and labs[il] == keys[ii]:
301
319
  if len(inserts):
302
320
  new_labs[il] = inserts
303
321
  inserts = []
@@ -306,6 +324,9 @@ class LabelGroup:
306
324
  else:
307
325
  inserts.append(keys[ii])
308
326
  ii += 1
327
+ else:
328
+ if len(inserts):
329
+ new_labs[il] = inserts
309
330
  for loc in list(new_labs.keys())[::-1]:
310
331
  self=self.insert(loc, new_labs[loc])
311
332
  return self
@@ -11,20 +11,25 @@ this program. If not, see <http://www.gnu.org/licenses/>.
11
11
  """
12
12
 
13
13
  from __future__ import annotations
14
+
15
+ from datetime import datetime
16
+ from json import dump, load
17
+ from numbers import Number
14
18
  from typing import Self, Union
19
+
20
+ from pathlib import Path
15
21
  import numpy as np
16
22
  import pandas as pd
17
- from .fields import fields, Field
18
- from geometry import GPS, Point, P0
23
+ from geometry import GPS, P0, Point
19
24
  from geometry.checks import assert_almost_equal
20
- from json import load, dump
25
+ from schemas import fcj
26
+ from scipy.signal import butter, filtfilt
27
+
28
+ from flightdata import Origin
21
29
  from flightdata.base.numpy_encoder import NumpyEncoder
30
+
22
31
  from .ardupilot import flightmodes
23
- from flightdata import Origin
24
- from schemas import fcj
25
- from numbers import Number
26
- from scipy.signal import filtfilt, butter
27
- from datetime import datetime
32
+ from .fields import Field, fields
28
33
 
29
34
 
30
35
  def filter(data, cutoff=25, order=5, fs=25):
@@ -311,13 +316,13 @@ class Flight:
311
316
  return False
312
317
 
313
318
  def boot_time(self):
314
- timestamp = self.time_actual.iloc[0]
319
+ timestamp = self.time_actual.iloc[0]
315
320
  return datetime.fromtimestamp(timestamp) if not np.isnan(timestamp) else None
316
321
 
317
322
  @staticmethod
318
323
  def from_log(
319
- log: str,
320
- extra_types: list[str] = None,
324
+ log: str | Path,
325
+ extra_types: list[str] | None = None,
321
326
  ppsource: str = "pos",
322
327
  imu_instance=0,
323
328
  **kwargs,
@@ -7,6 +7,6 @@ from dataclasses import dataclass
7
7
  class Parameters:
8
8
  parms: dict[str, pd.DataFrame]
9
9
 
10
- def __getattr(self, name: str) -> np.Any:
10
+ def __getattr(self, name: str):
11
11
  return self.parms[name]
12
12
 
@@ -586,6 +586,7 @@ class State(Table):
586
586
  )
587
587
 
588
588
  def move(self: State, transform: g.Transformation) -> State:
589
+ """Move the state by a transformation"""
589
590
  return State.from_constructs(
590
591
  time=self.time,
591
592
  pos=transform.point(self.pos),
@@ -45,6 +45,12 @@ def test_labelgroup_read_array(tab_full, label_array):
45
45
  assert lg.a2.stop == tab_full.data.index[-1]
46
46
 
47
47
 
48
+ def test_labelgroup_read_array_repeats(tab_full):
49
+ label_array = np.array(["a0", "a0", "a1", "a1", "a0", "a0"])
50
+ lg = LabelGroup.read_array(tab_full.t, label_array)
51
+ assert len(lg) == 3
52
+
53
+
48
54
  def test_label_array(tab_lab):
49
55
  assert len(tab_lab.labels) == 1
50
56
  assert isinstance(tab_lab.labels.a, LabelGroup)
@@ -181,26 +187,47 @@ def test_from_boundaries():
181
187
  lg = LabelGroup.from_boundaries(0, dict(a=2, b=5))
182
188
  assert lg.a.start == 0
183
189
  assert lg.a.stop == 2
184
- assert lg.b.start==2
190
+ assert lg.b.start == 2
185
191
  assert lg.b.stop == 5
186
192
  assert lg.is_tesselated(np.arange(5))
187
193
 
194
+
188
195
  def test_expand_one():
189
196
  lg = LabelGroup.from_boundaries(0, dict(a=2, b=2, c=6))
190
- lg = lg.expand_one('b', 1)
191
- np.testing.assert_array_equal(lg.boundaries, [2,3,6])
197
+ lg = lg.expand_one("b", 1)
198
+ np.testing.assert_array_equal(lg.boundaries, [2, 3, 6])
199
+
192
200
 
193
201
  def test_expand():
194
202
  lg = LabelGroup.from_boundaries(0, dict(a=2, b=2, c=6))
195
203
  lg = lg.expand(2)
196
204
  np.testing.assert_array_equal(lg.boundaries, [2, 4, 6])
197
205
 
206
+
198
207
  def test_expand_difficult():
199
208
  lg = LabelGroup.from_boundaries(0, dict(a=0, b=1, c=7))
200
-
209
+
201
210
  np.testing.assert_array_equal(lg.expand(1).boundaries, [1, 2, 7])
202
211
  np.testing.assert_array_equal(lg.expand(2).boundaries, [2, 4, 7])
203
212
 
213
+
204
214
  def test_expand_infinite_loop():
205
215
  lg = LabelGroup.from_boundaries(0, dict(a=1, b=5, c=6, d=8))
206
- np.testing.assert_array_equal(lg.expand(2).boundaries, [2, 4, 6, 8])
216
+ np.testing.assert_array_equal(lg.expand(2).boundaries, [2, 4, 6, 8])
217
+
218
+
219
+ def test_labelgroup_insert_list(tab_lab: Table):
220
+ np.testing.assert_array_equal(
221
+ list(tab_lab.labels.a.insert_list(["a0", "a1", "new", "a2"]).keys()),
222
+ ["a0", "a1", "new", "a2"],
223
+ )
224
+
225
+ np.testing.assert_array_equal(
226
+ list(tab_lab.labels.a.insert_list(["a0", "a1", "a2", "new"]).keys()),
227
+ ["a0", "a1", "a2", "new"],
228
+ )
229
+
230
+ np.testing.assert_array_equal(
231
+ list(tab_lab.labels.a.insert_list(["a0", "a1", "a2", "new", "new2"]).keys()),
232
+ ["a0", "a1", "a2", "new", "new2"],
233
+ )
@@ -1,9 +0,0 @@
1
-
2
-
3
-
4
- def get_appended_id(source: str, seperator='_'):
5
- try:
6
- sloc = source.rfind(seperator)
7
- return source[:sloc], source[sloc+1:]
8
- except Exception:
9
- return source, None
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes