sdata 1.5.0__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 (98) hide show
  1. sdata/__init__.py +140 -0
  2. sdata/base.py +684 -0
  3. sdata/contrib/__init__.py +0 -0
  4. sdata/contrib/piexif/__init__.py +12 -0
  5. sdata/contrib/piexif/_common.py +94 -0
  6. sdata/contrib/piexif/_dump.py +346 -0
  7. sdata/contrib/piexif/_exceptions.py +2 -0
  8. sdata/contrib/piexif/_exif.py +638 -0
  9. sdata/contrib/piexif/_insert.py +60 -0
  10. sdata/contrib/piexif/_load.py +270 -0
  11. sdata/contrib/piexif/_remove.py +56 -0
  12. sdata/contrib/piexif/_transplant.py +45 -0
  13. sdata/contrib/piexif/_webp.py +240 -0
  14. sdata/contrib/piexif/helper.py +66 -0
  15. sdata/contrib/ranger/__init__.py +8 -0
  16. sdata/contrib/ranger/collections/__init__.py +0 -0
  17. sdata/contrib/ranger/collections/rangebucketmap.py +346 -0
  18. sdata/contrib/ranger/collections/rangemap.py +396 -0
  19. sdata/contrib/ranger/collections/rangeset.py +483 -0
  20. sdata/contrib/ranger/range/__init__.py +0 -0
  21. sdata/contrib/ranger/range/cut.py +285 -0
  22. sdata/contrib/ranger/range/range.py +644 -0
  23. sdata/contrib/sobol_seq.py +394 -0
  24. sdata/contrib/sortedcontainers/LICENSE +13 -0
  25. sdata/contrib/sortedcontainers/__init__.py +74 -0
  26. sdata/contrib/sortedcontainers/sorteddict.py +789 -0
  27. sdata/contrib/sortedcontainers/sortedlist.py +2646 -0
  28. sdata/contrib/sortedcontainers/sortedset.py +733 -0
  29. sdata/contrib/sqlitedict.py +598 -0
  30. sdata/contrib/timeflake/__init__.py +40 -0
  31. sdata/contrib/timeflake/flake.py +69 -0
  32. sdata/contrib/timeflake/utils.py +47 -0
  33. sdata/deprecated/__init__.py +10 -0
  34. sdata/deprecated/data.py +1503 -0
  35. sdata/did/__init__.py +129 -0
  36. sdata/did/_http.py +67 -0
  37. sdata/did/base58btc.py +49 -0
  38. sdata/did/did_github.py +152 -0
  39. sdata/did/did_peer4.py +155 -0
  40. sdata/did/did_web.py +222 -0
  41. sdata/did/diddoc.py +75 -0
  42. sdata/did/ed25519.py +225 -0
  43. sdata/did/eddsa.py +107 -0
  44. sdata/did/errors.py +40 -0
  45. sdata/did/issue_vc.py +193 -0
  46. sdata/did/jose.py +126 -0
  47. sdata/did/keys.py +104 -0
  48. sdata/did/utils_didkey.py +161 -0
  49. sdata/did/verify_vp.py +158 -0
  50. sdata/doe.py +101 -0
  51. sdata/dtypes.py +510 -0
  52. sdata/experiments/__init__.py +331 -0
  53. sdata/experiments/blob0.py +131 -0
  54. sdata/experiments/file.py +42 -0
  55. sdata/experiments/filegroup.py +144 -0
  56. sdata/experiments/image_old.py +313 -0
  57. sdata/experiments/ks2.py +15 -0
  58. sdata/experiments/lapshear.py +8 -0
  59. sdata/experiments/material.py +7 -0
  60. sdata/experiments/parameters_deprecated.py +394 -0
  61. sdata/experiments/workbook.py +226 -0
  62. sdata/format.py +125 -0
  63. sdata/imagemeta.py +533 -0
  64. sdata/interactive.py +118 -0
  65. sdata/iolib/__init__.py +51 -0
  66. sdata/iolib/hashtree.py +264 -0
  67. sdata/iolib/json1sqlitestore.py +554 -0
  68. sdata/iolib/jsonsqlitestore.py +704 -0
  69. sdata/iolib/pud.py +242 -0
  70. sdata/iolib/reader.py +262 -0
  71. sdata/iolib/writer.py +419 -0
  72. sdata/metadata.py +882 -0
  73. sdata/parameter.py +414 -0
  74. sdata/schema.py +273 -0
  75. sdata/sclass/__init__.py +111 -0
  76. sdata/sclass/bfo_classes.py +362 -0
  77. sdata/sclass/blob.py +362 -0
  78. sdata/sclass/content.py +87 -0
  79. sdata/sclass/dataframe.py +1251 -0
  80. sdata/sclass/dataframegroup.py +187 -0
  81. sdata/sclass/dependency_graph.py +85 -0
  82. sdata/sclass/filereference.py +124 -0
  83. sdata/sclass/image.py +218 -0
  84. sdata/sclass/lazy_namespace.py +155 -0
  85. sdata/sclass/process.py +383 -0
  86. sdata/sclass/process_graph.py +221 -0
  87. sdata/sclass/zipfile.py +135 -0
  88. sdata/semantic.py +346 -0
  89. sdata/suuid.py +136 -0
  90. sdata/timestamp.py +336 -0
  91. sdata/tools.py +14 -0
  92. sdata/units.py +602 -0
  93. sdata/vocab.py +149 -0
  94. sdata-1.5.0.dist-info/METADATA +264 -0
  95. sdata-1.5.0.dist-info/RECORD +98 -0
  96. sdata-1.5.0.dist-info/WHEEL +5 -0
  97. sdata-1.5.0.dist-info/licenses/LICENSE-MIT +21 -0
  98. sdata-1.5.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,644 @@
1
+ from sdata.contrib.ranger.range.cut import Cut
2
+ import numpy as np
3
+
4
+ class Range(object):
5
+ """
6
+ Class used to represent a range along some 1-D domain. The range
7
+ is represented by 2 cutpoints can can be unbounded by specifying an
8
+ above_all or below_all Cut.
9
+ """
10
+
11
+ def __init__(self, lower_cut, upper_cut):
12
+ """ Instantiates a Range
13
+
14
+ Parameters
15
+ ----------
16
+ lower_cut : Cut object
17
+ Specifies the lower cut for the range
18
+ upper_cut : Cut object
19
+ Specifies the upper cut for the range
20
+
21
+ Raises
22
+ ------
23
+ ValueError
24
+ If bound(s) are not Cut objects or lower > upper
25
+ """
26
+ if not all(map(lambda x: isinstance(x, Cut), (lower_cut, upper_cut))):
27
+ raise ValueError("Bounds must be Cut objects")
28
+ elif lower_cut > upper_cut:
29
+ raise ValueError("Lower bound cannot be greater than upper bound")
30
+ self.lower_cut = lower_cut
31
+ self.upper_cut = upper_cut
32
+
33
+ @property
34
+ def min(self):
35
+ return self.lower_cut.point
36
+
37
+ @property
38
+ def max(self):
39
+ return self.upper_cut.point
40
+
41
+ def mean(self):
42
+ return (self.lower_cut.point + self.upper_cut.point) / 2.
43
+
44
+ @property
45
+ def length(self):
46
+ return self.upper_cut.point - self.lower_cut.point
47
+
48
+ @property
49
+ def values(self):
50
+ return np.array((self.lower_cut.point, self.upper_cut.point))
51
+
52
+ def __repr__(self):
53
+ try:
54
+ return_str = '[' if self.is_lower_bound_closed() else '('
55
+ except TypeError:
56
+ return_str = '('
57
+ return_str += (str(self.lower_cut.point) if not self.lower_cut.below_all else '')
58
+ return_str += ' , '
59
+ return_str += (str(self.upper_cut.point) if not self.upper_cut.above_all else '')
60
+ try:
61
+ return_str += ']' if self.is_upper_bound_closed() else ')'
62
+ except TypeError:
63
+ return_str += ')'
64
+ return return_str
65
+
66
+ def __hash__(self):
67
+ return hash(self.lower_cut) * 31 + hash(self.upper_cut)
68
+
69
+ def __eq__(self, other):
70
+ if not isinstance(other, Range):
71
+ return False
72
+ else:
73
+ return ((self.lower_cut == other.lower_cut) and
74
+ (self.upper_cut == other.upper_cut))
75
+
76
+ def __ne__(self, other):
77
+ return not self.__eq__(other)
78
+
79
+ def contains(self, val):
80
+ """ Returns true if the range contains the value
81
+
82
+ Parameters
83
+ ----------
84
+ val : Comparable object of the appropriate type for the range
85
+ Value to query whether in the range
86
+
87
+ Raises
88
+ ------
89
+ ValueError
90
+ If the value type not compatible with cutpoint type
91
+
92
+ Returns
93
+ -------
94
+ True if the range contains the value
95
+ """
96
+ return (self.lower_cut < val and
97
+ self.upper_cut > val)
98
+
99
+ def contains_all(self, vals):
100
+ """ Returns True if the range contains all values in some
101
+ iterable
102
+
103
+ Parameters
104
+ ----------
105
+ vals : Iterable of comparable object of appropriate type for range
106
+ Values to query against the range
107
+
108
+ Raises
109
+ ------
110
+ ValueError
111
+ If there is a value type not compatible with the cutpoint type
112
+
113
+ Returns
114
+ -------
115
+ True if the range contains all values
116
+ """
117
+ for val in vals:
118
+ if not self.contains(val):
119
+ return False
120
+ return True
121
+
122
+ def get_distance_from_point(self, val, dist_func=lambda x1, x2: abs(x1 - x2)):
123
+ """ Returns the minimum distance of a Range from a Point, returning 0
124
+ if there is an overlap.
125
+
126
+ Note that both upper and lower bounds must be closed for this function
127
+ to work
128
+
129
+ Parameters
130
+ ----------
131
+ val : comparable, compatible with cutpoint type
132
+ The value of the point where the distance is desired
133
+ dist_func : callable
134
+ Function that calculates the distance between two points in the
135
+ domain of the Range
136
+
137
+ Raises
138
+ ------
139
+ TypeError
140
+ If the upper and/or lower bounds of this Range are not closed
141
+ or if the dist_func not compatible with the type
142
+
143
+ Returns
144
+ -------
145
+ The minimum distance between the Range and the Point. Returns 0
146
+ if there is an overlap
147
+ """
148
+ if not all((self.is_lower_bound_closed(), self.is_upper_bound_closed())):
149
+ raise TypeError("Range is not closed")
150
+ if self.contains(val):
151
+ return 0.
152
+ else:
153
+ return min(dist_func(self.lower_cut.point, val),
154
+ dist_func(self.upper_cut.point, val))
155
+
156
+ def get_distance_from_range(self, other, dist_func=lambda x1, x2: abs(x1 - x2)):
157
+ """ Returns the minimum distance of a Range from another Range, returning
158
+ 0 if there is any overlap
159
+
160
+ Note that both Ranges must be closed for this function to work
161
+
162
+ Parameters
163
+ ----------
164
+ other : Range, compatible with this Range's domain
165
+ The Range to compare to
166
+ dist_func : callable
167
+ Function that calculates the distance between two points in the
168
+ domain of the Range
169
+
170
+ Raises
171
+ ------
172
+ TypeError
173
+ If the upper and/or lower bounds of this Range are not closed
174
+ or if the dist_func not compatible with the type
175
+
176
+ Returns
177
+ -------
178
+ Minimum distance between the ranges
179
+ """
180
+ if not isinstance(other, Range):
181
+ raise TypeError("other is not a Range")
182
+ if not all((self.is_lower_bound_closed(), self.is_upper_bound_closed(),
183
+ other.is_lower_bound_closed(), other.is_upper_bound_closed())):
184
+ raise TypeError("Not all Ranges closed")
185
+ if self.is_connected(other):
186
+ return 0.
187
+ else:
188
+ return min(dist_func(self.lower_cut.point, other.upper_cut.point),
189
+ dist_func(other.lower_cut.point, self.upper_cut.point))
190
+
191
+ def has_lower_bound(self):
192
+ """ Returns True if the range has a lower endpoint (not unbounded
193
+ at the lower end)
194
+
195
+ Returns
196
+ -------
197
+ True if the range has a lower endpoint
198
+ """
199
+ return not self.lower_cut.below_all
200
+
201
+ def has_upper_bound(self):
202
+ """ Returns True if the range has an upper endpoint (not unbounded
203
+ at the upper end)
204
+
205
+ Returns
206
+ -------
207
+ True if the range has an upper endpoint
208
+ """
209
+ return not self.upper_cut.above_all
210
+
211
+ def lower_endpoint(self):
212
+ """ Returns the lower endpoint of the range if it exists. Otherwise
213
+ raises a TypeError
214
+
215
+ Raises
216
+ ------
217
+ TypeError
218
+ If the range is unbounded below
219
+
220
+ Returns
221
+ -------
222
+ The lower endpoint of the range
223
+ """
224
+ if self.lower_cut.point is None:
225
+ raise TypeError("Range unbounded below")
226
+ else:
227
+ return self.lower_cut.point
228
+
229
+ def upper_endpoint(self):
230
+ """ Returns the upper endpoint of the range if it exists. Otherwise
231
+ raises a TypeError
232
+
233
+ Raises
234
+ ------
235
+ TypeError
236
+ If the range is unbounded above
237
+
238
+ Returns
239
+ -------
240
+ The upper endpoint of the range
241
+ """
242
+ if self.upper_cut.point is None:
243
+ raise TypeError("Range unbounded above")
244
+ else:
245
+ return self.upper_cut.point
246
+
247
+ def is_lower_bound_closed(self):
248
+ """ Returns whether the lower bound is closed (if there is a
249
+ lower bound)
250
+
251
+ Raises
252
+ ------
253
+ TypeError
254
+ If the range is unbounded below
255
+
256
+ Returns
257
+ -------
258
+ True if the lower bound is closed
259
+ """
260
+ if self.lower_cut.point is None:
261
+ raise TypeError("Range unbounded below")
262
+ else:
263
+ return self.lower_cut.below
264
+
265
+ def is_upper_bound_closed(self):
266
+ """ Returns whether the upper bound is closed (if there is an
267
+ upper bound)
268
+
269
+ Raises
270
+ ------
271
+ TypeError
272
+ If the range is unbounded above
273
+
274
+ Returns
275
+ -------
276
+ True if the upper bound is closed
277
+ """
278
+ if self.upper_cut.point is None:
279
+ raise TypeError("Range unbounded above")
280
+ else:
281
+ return not self.upper_cut.below
282
+
283
+ def is_empty(self):
284
+ """ Returns True if the range is of form [v, v) or (v, v]
285
+
286
+ Returns
287
+ -------
288
+
289
+ True if the range is of the form [v,v) or (v,v]
290
+ """
291
+ return self.lower_cut == self.upper_cut
292
+
293
+ def encloses(self, other):
294
+ """ Returns True if the bounds of the other range do not extend
295
+ outside the bounds of this range
296
+
297
+ Examples:
298
+ [3,6] encloses [4,5]
299
+ (3,6) encloses (3,6)
300
+ [3,6] encloses [4,4]
301
+ (3,6] does not enclose [3,6]
302
+ [4,5] does not enclose (3,6)
303
+
304
+ Parameters
305
+ ----------
306
+ other : A Range
307
+ The range to compare to
308
+
309
+ Raises
310
+ ------
311
+ ValueError
312
+ If object passed in is not a Range
313
+
314
+ Returns
315
+ -------
316
+ True if the bounds of the other range do not extend outside
317
+ the bounds of this range
318
+ """
319
+ if not isinstance(other, Range):
320
+ raise ValueError("Range required")
321
+ return ((self.lower_cut <= other.lower_cut) and
322
+ (self.upper_cut >= other.upper_cut))
323
+
324
+ def is_connected(self, other):
325
+ """ Returns True if there is a (possibly empty) range that is
326
+ enclosed by both this range and other
327
+
328
+ Examples:
329
+ [2,4] and [5,7] are not connected
330
+ [2,4] and [3,5] are connected
331
+ [2,4] and [4,6] are connected
332
+ [3,5] and (5,10) are connected
333
+
334
+ Parameters
335
+ ----------
336
+ other : A range
337
+ The range to compare to
338
+
339
+ Raises
340
+ ------
341
+ ValueError
342
+ If object passed in is not a Range
343
+
344
+ Returns
345
+ -------
346
+ True if there is a (possibly empty) range that is enclosed by
347
+ both this range and other
348
+ """
349
+ if not isinstance(other, Range):
350
+ raise ValueError("Range required")
351
+ return ((self.lower_cut <= other.upper_cut) and
352
+ (other.lower_cut <= self.upper_cut))
353
+
354
+ def intersection(self, other):
355
+ """ Returns the maximal range enclosed by both this range and the
356
+ other range, if such a range exists
357
+
358
+ Examples:
359
+ Intersection of [1,5] and [3,7] is [3,5]
360
+ Intersection of [1,5] and [5,7] is [5,5]
361
+
362
+ Parameters
363
+ ----------
364
+ other : A range
365
+ The range to compare to
366
+
367
+ Raises
368
+ ------
369
+ ValueError
370
+ If object passed in is not a Range or if there is no intersection
371
+
372
+ Returns
373
+ -------
374
+ The intersection range
375
+ """
376
+ if not isinstance(other, Range):
377
+ raise ValueError("Range required")
378
+ if (self.lower_cut >= other.lower_cut) and (self.upper_cut <= other.upper_cut):
379
+ return Range(self.lower_cut, self.upper_cut)
380
+ elif ((self.lower_cut <= other.lower_cut) and
381
+ (self.upper_cut >= other.upper_cut)):
382
+ return Range(other.lower_cut, other.upper_cut)
383
+ else:
384
+ new_lower = self.lower_cut if (self.lower_cut >= other.lower_cut) else other.lower_cut
385
+ new_upper = self.upper_cut if (self.upper_cut <= other.upper_cut) else other.upper_cut
386
+ return Range(new_lower, new_upper)
387
+
388
+ def span(self, other):
389
+ """ Returns the minimal range that encloses both this range and
390
+ the other. Note that if the input ranges are not connected, the span can
391
+ contain values that are not contained within either input range
392
+
393
+ Examples:
394
+ Span of [1,3] and [5,7] is [1,7]
395
+
396
+ Parameters
397
+ ----------
398
+ other : A range
399
+ A range to span with
400
+
401
+ Raises
402
+ ------
403
+ ValueError
404
+ If object passed in is not a Range or if there is no intersection
405
+
406
+ Returns
407
+ -------
408
+ The minimal range enclosing both with and the other range
409
+ """
410
+ if ((self.lower_cut <= other.lower_cut) and (self.upper_cut >= other.upper_cut)):
411
+ return Range(self.lower_cut, self.upper_cut)
412
+ elif ((self.lower_cut >= other.lower_cut) and (self.upper_cut <= other.upper_cut)):
413
+ return Range(other.lower_cut, other.upper_cut)
414
+ else:
415
+ new_lower = self.lower_cut if (self.lower_cut <= other.lower_cut) else other.lower_cut
416
+ new_upper = self.upper_cut if (self.upper_cut >= other.upper_cut) else other.upper_cut
417
+ return Range(new_lower, new_upper)
418
+
419
+ ##################
420
+ # Static methods #
421
+ ##################
422
+ @staticmethod
423
+ def _validate_cutpoints(*pts):
424
+ if not all(map(lambda x: (hasattr(x, "__lt__") and hasattr(x, "__gt__")) or hasattr(x, '__cmp__'), pts)):
425
+ raise ValueError("Cutpoint type(s) not comparable")
426
+ if len(pts) == 2:
427
+ if not (issubclass(type(pts[0]), type(pts[1])) or issubclass(type(pts[1]), type(pts[0]))):
428
+ raise ValueError("Cutpoints are not compatible")
429
+ return True
430
+
431
+ @staticmethod
432
+ def _get_type(*pts):
433
+ if len(pts) == 1:
434
+ return type(pts[0])
435
+ elif len(pts) == 2:
436
+ if issubclass(type(pts[0]), type(pts[1])):
437
+ return type(pts[1])
438
+ elif issubclass(type(pts[1]), type(pts[0])):
439
+ return type(pts[0])
440
+ else:
441
+ raise ValueError("Cutpoints are not compatible")
442
+
443
+ @staticmethod
444
+ def closed(lower, upper):
445
+ """ Creates a range including the endpoints (i.e. [lower, upper])
446
+
447
+ Parameters
448
+ ----------
449
+ lower : comparable, of same type as or subclass of upper type
450
+ The lower bound
451
+ upper : comparable, of same type as or subclass of lower type
452
+ The upper bound
453
+
454
+ Raises
455
+ ------
456
+ ValueError
457
+ If type(s) are not comparable or compatible
458
+
459
+ Returns
460
+ -------
461
+ A Range object [lower, upper]
462
+ """
463
+ # Ensure cutpoints are of compatible, appropriate types
464
+ Range._validate_cutpoints(lower, upper)
465
+ the_type = Range._get_type(lower, upper)
466
+ return Range(Cut.below_value(lower, the_type=the_type),
467
+ Cut.above_value(upper, the_type=the_type))
468
+
469
+ @staticmethod
470
+ def closed_open(lower, upper):
471
+ """ Creates a range including the lower endpoint (i.e. [lower, upper))
472
+
473
+ Parameters
474
+ ----------
475
+ lower : comparable, of same type as or subclass of upper type
476
+ The lower bound
477
+ upper : comparable, of same type as or subclass of lower type
478
+ The upper bound
479
+
480
+ Raises
481
+ ------
482
+ ValueError
483
+ If type(s) are not comparable or compatible
484
+
485
+ Returns
486
+ -------
487
+ A Range object [lower, upper)
488
+ """
489
+ # Ensure cutpoints are of compatible, appropriate types
490
+ Range._validate_cutpoints(lower, upper)
491
+ the_type = Range._get_type(lower, upper)
492
+ return Range(Cut.below_value(lower, the_type=the_type),
493
+ Cut.below_value(upper, the_type=the_type))
494
+
495
+ @staticmethod
496
+ def open_closed(lower, upper):
497
+ """ Creates a range including the upper (i.e. (lower, upper])
498
+
499
+ Parameters
500
+ ----------
501
+ lower : comparable, of same type as or subclass of upper type
502
+ The lower bound
503
+ upper : comparable, of same type as or subclass of lower type
504
+ The upper bound
505
+
506
+ Raises
507
+ ------
508
+ ValueError
509
+ If type(s) are not comparable or compatible
510
+
511
+ Returns
512
+ -------
513
+ A Range object (lower, upper]
514
+ """
515
+ # Ensure cutpoints are of compatible, appropriate types
516
+ Range._validate_cutpoints(lower, upper)
517
+ the_type = Range._get_type(lower, upper)
518
+ return Range(Cut.above_value(lower, the_type=the_type),
519
+ Cut.above_value(upper, the_type=the_type))
520
+
521
+ @staticmethod
522
+ def open(lower, upper):
523
+ """ Creates a range excluding the endpoints (i.e. (lower, upper))
524
+
525
+ Parameters
526
+ ----------
527
+ lower : comparable, of same type as or subclass of upper type
528
+ The lower bound
529
+ upper : comparable, of same type as or subclass of lower type
530
+ The upper bound
531
+
532
+ Raises
533
+ ------
534
+ ValueError
535
+ If type(s) are not comparable or compatible or if constructing
536
+ a range of type (v,v), which is invalid
537
+
538
+ Returns
539
+ -------
540
+ A Range object (lower, upper)
541
+ """
542
+ # Ensure cutpoints are of compatible, appropriate types
543
+ Range._validate_cutpoints(lower, upper)
544
+ the_type = Range._get_type(lower, upper)
545
+ if lower == upper:
546
+ raise TypeError("Range of type (v,v) is not valid")
547
+ return Range(Cut.above_value(lower, the_type=the_type),
548
+ Cut.below_value(upper, the_type=the_type))
549
+
550
+ @staticmethod
551
+ def less_than(val):
552
+ """ Makes range including all values less than some value
553
+ (i.e. (-inf, val))
554
+
555
+ Parameters
556
+ ----------
557
+ val : comparable
558
+ The upper bound
559
+
560
+ Raises
561
+ ------
562
+ ValueError
563
+ If type not comparable
564
+
565
+ Returns
566
+ -------
567
+ A Range object (-inf, val)
568
+ """
569
+ Range._validate_cutpoints(val)
570
+ the_type = Range._get_type(val)
571
+ return Range(Cut.below_all(the_type=the_type),
572
+ Cut.below_value(val, the_type=the_type))
573
+
574
+ @staticmethod
575
+ def at_most(val):
576
+ """ Makes range including all values less than or equal to
577
+ some value (i.e. (-inf, val])
578
+
579
+ Parameters
580
+ ----------
581
+ val : comparable
582
+ The upper bound
583
+
584
+ Raises
585
+ ------
586
+ ValueError
587
+ If type not comparable
588
+
589
+ Returns
590
+ -------
591
+ A Range object (-inf, val]
592
+ """
593
+ Range._validate_cutpoints(val)
594
+ the_type = Range._get_type(val)
595
+ return Range(Cut.below_all(the_type=the_type),
596
+ Cut.above_value(val, the_type=the_type))
597
+
598
+ @staticmethod
599
+ def greater_than(val):
600
+ """ Makes range including all values greater than
601
+ some value (i.e. (val, inf])
602
+
603
+ Parameters
604
+ ----------
605
+ val : comparable
606
+ The lower bound
607
+
608
+ Raises
609
+ ------
610
+ ValueError
611
+ If type not comparable
612
+
613
+ Returns
614
+ -------
615
+ A Range object (val, inf)
616
+ """
617
+ Range._validate_cutpoints(val)
618
+ the_type = Range._get_type(val)
619
+ return Range(Cut.above_value(val, the_type=the_type),
620
+ Cut.above_all(the_type=the_type))
621
+
622
+ @staticmethod
623
+ def at_least(val):
624
+ """ Makes range including all values greater than or equal to
625
+ some value (i.e. [val, inf))
626
+
627
+ Parameters
628
+ ----------
629
+ val : comparable
630
+ The lower bound
631
+
632
+ Raises
633
+ ------
634
+ ValueError
635
+ If type not comparable
636
+
637
+ Returns
638
+ -------
639
+ A Range object [val, inf)
640
+ """
641
+ Range._validate_cutpoints(val)
642
+ the_type = Range._get_type(val)
643
+ return Range(Cut.below_value(val, the_type=the_type),
644
+ Cut.above_all(the_type=the_type))