or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bags.mdbijections.mdindex.mdindexed-dicts.mdrange-maps.mdsetlists.md

range-maps.mddocs/

0

# Range Mappings

1

2

RangeMaps provide efficient mappings from continuous ranges to values using interval-based storage. They support slice notation, range operations, and are ideal for time series data, version ranges, and any scenario requiring interval-to-value mappings.

3

4

## Capabilities

5

6

### RangeMap Construction

7

8

Create range mappings from various input formats with optional default values.

9

10

```python { .api }

11

class RangeMap:

12

def __init__(self, iterable=None, default_value=NOT_SET):

13

"""Create a RangeMap.

14

15

Args:

16

iterable: Mapping (start -> value) or iterable of (start, stop, value) tuples

17

default_value: Default value for unmapped ranges

18

"""

19

20

@classmethod

21

def from_mapping(cls, mapping):

22

"""Create RangeMap from mapping of range starts to values.

23

24

Args:

25

mapping: Dict mapping start points to values

26

27

Returns:

28

RangeMap: New range map

29

"""

30

31

@classmethod

32

def from_iterable(cls, iterable):

33

"""Create RangeMap from iterable of (start, stop, value) tuples.

34

35

Args:

36

iterable: Iterable of (start, stop, value) tuples

37

38

Returns:

39

RangeMap: New range map

40

"""

41

```

42

43

Usage examples:

44

```python

45

from collections_extended import RangeMap

46

from datetime import date

47

48

# Empty range map

49

rm = RangeMap()

50

51

# With default value for unmapped ranges

52

rm_default = RangeMap(default_value='unknown')

53

54

# From mapping of start points

55

starts = {0: 'low', 10: 'medium', 20: 'high'}

56

rm_starts = RangeMap.from_mapping(starts)

57

58

# From tuples of (start, stop, value)

59

ranges = [(0, 5, 'first'), (5, 10, 'second'), (10, 15, 'third')]

60

rm_ranges = RangeMap.from_iterable(ranges)

61

```

62

63

### Range Setting and Access

64

65

Set and retrieve values for specific ranges using slice notation or method calls.

66

67

```python { .api }

68

def set(self, value, start=None, stop=None):

69

"""Set range from start to stop to value.

70

71

Args:

72

value: Value to assign to the range

73

start: Start of range (inclusive, None for unbounded left)

74

stop: End of range (exclusive, None for unbounded right)

75

"""

76

77

def get(self, key, restval=None):

78

"""Get value for a specific key.

79

80

Args:

81

key: Point to look up

82

restval: Value to return if key not mapped

83

84

Returns:

85

Any: Value at key or restval if unmapped

86

"""

87

88

def __getitem__(self, key):

89

"""Get value for key or range slice.

90

91

Args:

92

key: Point to look up or slice for sub-range

93

94

Returns:

95

Any: Value at key or RangeMap for slice

96

97

Raises:

98

KeyError: If key not mapped and no default value

99

"""

100

101

def __setitem__(self, key, value):

102

"""Set range using slice notation.

103

104

Args:

105

key: slice object defining the range

106

value: Value to assign to the range

107

"""

108

```

109

110

Usage examples:

111

```python

112

rm = RangeMap()

113

114

# Set ranges using method calls

115

rm.set('morning', start=6, stop=12)

116

rm.set('afternoon', start=12, stop=18)

117

rm.set('evening', start=18, stop=22)

118

119

# Set ranges using slice notation

120

rm[0:6] = 'night'

121

rm[22:24] = 'late_night'

122

123

# Access specific points

124

print(rm[8]) # 'morning'

125

print(rm[15]) # 'afternoon'

126

print(rm.get(25, 'unmapped')) # 'unmapped'

127

128

# Access sub-ranges

129

sub_range = rm[10:20] # RangeMap with overlapping ranges

130

```

131

132

### Range Queries and Iteration

133

134

Query range information and iterate over mapped intervals.

135

136

```python { .api }

137

def ranges(self, start=None, stop=None):

138

"""Generate MappedRange objects for ranges in the specified interval.

139

140

Args:

141

start: Start of query interval (None for unbounded)

142

stop: End of query interval (None for unbounded)

143

144

Yields:

145

MappedRange: Range objects with start, stop, and value

146

"""

147

148

def get_range(self, start=None, stop=None):

149

"""Return a RangeMap covering the specified range.

150

151

Args:

152

start: Start of range to extract

153

stop: End of range to extract

154

155

Returns:

156

RangeMap: New RangeMap covering the specified range

157

"""

158

159

def __contains__(self, key):

160

"""Check if key is mapped to a value.

161

162

Args:

163

key: Point to check

164

165

Returns:

166

bool: True if key is mapped

167

"""

168

169

def __iter__(self):

170

"""Iterate over range start points that have mappings."""

171

172

def __len__(self):

173

"""Return number of mapped ranges.

174

175

Returns:

176

int: Count of ranges with values

177

"""

178

179

def __bool__(self):

180

"""Return True if any ranges are mapped.

181

182

Returns:

183

bool: True if RangeMap contains mappings

184

"""

185

```

186

187

Usage examples:

188

```python

189

rm = RangeMap()

190

rm[0:10] = 'first'

191

rm[10:20] = 'second'

192

rm[30:40] = 'third'

193

194

# Iterate over all ranges

195

for range_obj in rm.ranges():

196

print(f"[{range_obj.start}:{range_obj.stop}) -> {range_obj.value}")

197

198

# Query specific interval

199

for range_obj in rm.ranges(5, 35):

200

print(f"Overlaps query: [{range_obj.start}:{range_obj.stop}) -> {range_obj.value}")

201

202

# Extract sub-range

203

partial = rm.get_range(5, 25) # Includes parts of 'first' and 'second'

204

205

# Basic queries

206

print(5 in rm) # True

207

print(25 in rm) # False

208

print(len(rm)) # 3

209

print(bool(rm)) # True

210

```

211

212

### Range Modification

213

214

Modify, delete, and clear ranges efficiently.

215

216

```python { .api }

217

def delete(self, start=None, stop=None):

218

"""Delete the specified range.

219

220

Args:

221

start: Start of range to delete (None for unbounded)

222

stop: End of range to delete (None for unbounded)

223

224

Raises:

225

KeyError: If any part of the range is not mapped

226

"""

227

228

def empty(self, start=None, stop=None):

229

"""Empty the specified range (like delete but doesn't raise errors).

230

231

Args:

232

start: Start of range to empty (None for unbounded)

233

stop: End of range to empty (None for unbounded)

234

"""

235

236

def clear(self):

237

"""Remove all mappings from the RangeMap."""

238

239

def __delitem__(self, key):

240

"""Delete range using slice notation.

241

242

Args:

243

key: slice object defining range to delete

244

"""

245

```

246

247

Usage examples:

248

```python

249

rm = RangeMap()

250

rm[0:50] = 'full_range'

251

rm[10:20] = 'middle'

252

rm[30:40] = 'end'

253

254

# Delete specific range

255

del rm[15:25] # Removes part of 'middle' and gap

256

257

# Empty range (no error if unmapped)

258

rm.empty(45, 60) # Removes part of range, no error for unmapped part

259

260

# Delete with error checking

261

try:

262

rm.delete(100, 110) # KeyError - range not mapped

263

except KeyError:

264

print("Range not fully mapped")

265

266

# Clear everything

267

rm.clear()

268

print(len(rm)) # 0

269

```

270

271

### Boundary Properties

272

273

Access information about range boundaries and extents.

274

275

```python { .api }

276

@property

277

def start(self):

278

"""Get the start of the first mapped range.

279

280

Returns:

281

Any: Start point of first range or None if empty/unbounded

282

"""

283

284

@property

285

def end(self):

286

"""Get the end of the last mapped range.

287

288

Returns:

289

Any: End point of last range or None if empty/unbounded

290

"""

291

```

292

293

Usage examples:

294

```python

295

rm = RangeMap()

296

rm[10:20] = 'first'

297

rm[30:40] = 'second'

298

299

print(rm.start) # 10

300

print(rm.end) # 40

301

302

# Unbounded ranges

303

rm[:5] = 'prefix' # Unbounded left

304

rm[50:] = 'suffix' # Unbounded right

305

306

print(rm.start) # None (unbounded left)

307

print(rm.end) # None (unbounded right)

308

```

309

310

### MappedRange Objects

311

312

Represent individual range mappings with start, stop, and value information.

313

314

```python { .api }

315

class MappedRange:

316

def __init__(self, start, stop, value):

317

"""Create a mapped range.

318

319

Args:

320

start: Range start (inclusive)

321

stop: Range end (exclusive)

322

value: Associated value

323

"""

324

325

start: Any # Range start point (inclusive)

326

stop: Any # Range end point (exclusive)

327

value: Any # Associated value

328

329

def __iter__(self):

330

"""Allow unpacking: start, stop, value = mapped_range"""

331

332

def __eq__(self, other):

333

"""Check equality with another MappedRange."""

334

335

def __str__(self):

336

"""String representation: [start, stop) -> value"""

337

338

def __repr__(self):

339

"""Detailed representation for debugging."""

340

```

341

342

Usage examples:

343

```python

344

from collections_extended import MappedRange

345

346

# Create manually

347

mr = MappedRange(0, 10, 'first_range')

348

print(mr) # [0, 10) -> first_range

349

350

# Unpack from ranges() iteration

351

rm = RangeMap()

352

rm[0:10] = 'test'

353

for start, stop, value in rm.ranges():

354

print(f"Range from {start} to {stop}: {value}")

355

356

# Access attributes

357

for range_obj in rm.ranges():

358

print(f"Start: {range_obj.start}")

359

print(f"Stop: {range_obj.stop}")

360

print(f"Value: {range_obj.value}")

361

```

362

363

### View Operations

364

365

Access keys, values, and items through view objects.

366

367

```python { .api }

368

def keys(self):

369

"""Return view of range start keys.

370

371

Returns:

372

RangeMapKeysView: View iterating over range start points

373

"""

374

375

def values(self):

376

"""Return view of range values.

377

378

Returns:

379

RangeMapValuesView: View iterating over unique values

380

"""

381

382

def items(self):

383

"""Return view of (start, value) pairs.

384

385

Returns:

386

RangeMapItemsView: View iterating over start-value pairs

387

"""

388

```

389

390

Usage examples:

391

```python

392

rm = RangeMap()

393

rm[0:10] = 'first'

394

rm[10:20] = 'second'

395

rm[20:30] = 'first' # Same value as first range

396

397

print(list(rm.keys())) # [0, 10, 20]

398

print(list(rm.values())) # ['first', 'second'] - unique values only

399

print(list(rm.items())) # [(0, 'first'), (10, 'second'), (20, 'first')]

400

401

# Views support membership testing

402

print(15 in rm.keys()) # False (15 is not a start point)

403

print('first' in rm.values()) # True

404

print((10, 'second') in rm.items()) # True

405

```

406

407

### Advanced Usage Patterns

408

409

Common patterns for effective RangeMap usage.

410

411

```python

412

from datetime import date, timedelta

413

414

# Version ranges for software releases

415

versions = RangeMap()

416

versions[date(2020, 1, 1):date(2020, 6, 1)] = '1.0'

417

versions[date(2020, 6, 1):date(2021, 1, 1)] = '1.1'

418

versions[date(2021, 1, 1):] = '2.0'

419

420

current_version = versions[date.today()]

421

422

# Price tiers based on quantity

423

pricing = RangeMap(default_value=0.50) # Default unit price

424

pricing[100:500] = 0.45 # Volume discount

425

pricing[500:1000] = 0.40 # Larger volume discount

426

pricing[1000:] = 0.35 # Highest volume discount

427

428

unit_price = pricing[quantity]

429

430

# Time-based scheduling

431

schedule = RangeMap()

432

schedule[6:9] = 'morning_shift'

433

schedule[9:17] = 'day_shift'

434

schedule[17:22] = 'evening_shift'

435

schedule[22:6] = 'night_shift' # Wraps around (if using 24-hour periods)

436

437

current_shift = schedule.get(current_hour, 'off_duty')

438

439

# Overlapping range updates

440

temp_map = RangeMap()

441

temp_map[0:100] = 'baseline'

442

temp_map[20:30] = 'override' # Splits baseline into [0:20) and [30:100)

443

444

# Merging adjacent ranges with same value

445

data = RangeMap()

446

data[0:10] = 'same'

447

data[10:20] = 'same' # Automatically merged into [0:20) = 'same'

448

```