or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

base-types.mdboolean-types.mddatetime-types.mddict-types.mdindex.mdinspection-types.mdnumeric-types.mdother-types.mdsequence-types.mdstring-types.md

numeric-types.mddocs/

0

# Numeric Types

1

2

Comprehensive numeric comparison types supporting integers, floats, decimals, and special float values with range checking, approximation, and sign validation. These types enable flexible validation of numeric data with various constraints and special value handling.

3

4

## Capabilities

5

6

### IsNumeric

7

8

Base class for all numeric comparisons providing range checking, approximate matching, and bound validation. Serves as the foundation for all specialized numeric types.

9

10

```python { .api }

11

class IsNumeric(DirtyEquals):

12

"""

13

Base class for numeric comparisons with configurable constraints.

14

15

Supports range checking, approximate matching, and bound validation

16

for numeric values including dates and datetimes.

17

"""

18

19

def __init__(

20

self,

21

*,

22

exactly: Optional[Union[int, float, Decimal]] = None,

23

approx: Optional[Union[int, float, Decimal]] = None,

24

delta: Optional[Union[int, float, Decimal]] = None,

25

gt: Optional[Union[int, float, Decimal]] = None,

26

lt: Optional[Union[int, float, Decimal]] = None,

27

ge: Optional[Union[int, float, Decimal]] = None,

28

le: Optional[Union[int, float, Decimal]] = None

29

):

30

"""

31

Initialize numeric comparison with constraints.

32

33

Args:

34

exactly: Exact value to match

35

approx: Approximate value for comparison

36

delta: Tolerance for approximate comparison

37

gt: Value must be greater than this

38

lt: Value must be less than this

39

ge: Value must be greater than or equal to this

40

le: Value must be less than or equal to this

41

"""

42

43

allowed_types: ClassVar[Tuple[type, ...]] = (int, float, Decimal, date, datetime)

44

45

def prepare(self) -> None:

46

"""Prepare and validate constraint parameters."""

47

48

def bounds_checks(self, other: Union[int, float, Decimal]) -> bool:

49

"""

50

Perform range bound checking.

51

52

Args:

53

other: Numeric value to check

54

55

Returns:

56

bool: True if value satisfies all bound constraints

57

"""

58

59

def approx_equals(

60

self,

61

other: Union[int, float, Decimal],

62

delta: Union[int, float, Decimal]

63

) -> bool:

64

"""

65

Check approximate equality within tolerance.

66

67

Args:

68

other: Value to compare

69

delta: Maximum allowed difference

70

71

Returns:

72

bool: True if values are within delta of each other

73

"""

74

75

def equals(self, other: Any) -> bool:

76

"""

77

Check if value matches numeric constraints.

78

79

Args:

80

other: Value to validate

81

82

Returns:

83

bool: True if value satisfies all conditions

84

"""

85

```

86

87

#### Usage Examples

88

89

```python

90

from dirty_equals import IsNumeric

91

from decimal import Decimal

92

93

# Exact value matching

94

assert 42 == IsNumeric(exactly=42)

95

assert 3.14 == IsNumeric(exactly=3.14)

96

97

# Approximate matching

98

assert 3.14159 == IsNumeric(approx=3.14, delta=0.01)

99

assert 100 == IsNumeric(approx=99, delta=2)

100

101

# Range constraints

102

assert 50 == IsNumeric(gt=0, lt=100)

103

assert 25 == IsNumeric(ge=25, le=75)

104

105

# Combining constraints

106

assert 42 == IsNumeric(gt=0, le=100, approx=40, delta=5)

107

108

# Works with Decimal for high precision

109

big_decimal = Decimal('123.456789')

110

assert big_decimal == IsNumeric(approx=Decimal('123.45'), delta=Decimal('0.01'))

111

112

# Date and datetime support

113

from datetime import date, datetime

114

today = date.today()

115

assert today == IsNumeric(ge=date(2023, 1, 1))

116

117

now = datetime.now()

118

assert now == IsNumeric(gt=datetime(2023, 1, 1))

119

```

120

121

### IsNumber

122

123

Base class specifically for numeric types (int, float, Decimal), excluding date/datetime objects that IsNumeric supports.

124

125

```python { .api }

126

class IsNumber(IsNumeric):

127

"""

128

Base class for pure number types (excludes dates).

129

130

Inherits all functionality from IsNumeric but restricts

131

allowed types to int, float, and Decimal only.

132

"""

133

134

allowed_types: ClassVar[Tuple[type, ...]] = (int, float, Decimal)

135

```

136

137

#### Usage Examples

138

139

```python

140

from dirty_equals import IsNumber

141

142

# Number validation (excludes dates)

143

assert 42 == IsNumber

144

assert 3.14 == IsNumber

145

assert Decimal('123.45') == IsNumber

146

147

# Range constraints for numbers only

148

assert 25 == IsNumber(gt=0, lt=100)

149

assert 50 == IsNumber(approx=48, delta=5)

150

151

# Dates/datetimes won't match

152

from datetime import date

153

# assert date.today() == IsNumber # Would fail - dates not allowed

154

```

155

156

### IsApprox

157

158

Specialized class for approximate number comparison with configurable tolerance.

159

160

```python { .api }

161

class IsApprox(IsNumber):

162

"""

163

Approximate number comparison with tolerance.

164

165

Validates that a number is within a specified delta

166

of the expected approximate value.

167

"""

168

169

def __init__(

170

self,

171

approx: Union[int, float, Decimal],

172

*,

173

delta: Optional[Union[int, float, Decimal]] = None

174

):

175

"""

176

Initialize approximate comparison.

177

178

Args:

179

approx: Expected approximate value

180

delta: Maximum allowed difference (default based on value magnitude)

181

"""

182

```

183

184

#### Usage Examples

185

186

```python

187

from dirty_equals import IsApprox

188

189

# Basic approximate matching

190

assert 3.14159 == IsApprox(3.14, delta=0.01)

191

assert 100 == IsApprox(99, delta=2)

192

193

# Default delta (implementation specific)

194

assert 42.001 == IsApprox(42) # Uses default tolerance

195

196

# Mathematical calculations with floating point precision

197

import math

198

calculated_pi = 22/7 # Approximation of pi

199

assert calculated_pi == IsApprox(math.pi, delta=0.01)

200

201

# API numeric responses

202

api_response = {

203

'cpu_usage': 85.7,

204

'memory_usage': 67.3,

205

'disk_usage': 23.8

206

}

207

208

expected_metrics = {

209

'cpu_usage': IsApprox(85, delta=5),

210

'memory_usage': IsApprox(70, delta=5),

211

'disk_usage': IsApprox(25, delta=5)

212

}

213

214

assert api_response == expected_metrics

215

```

216

217

### Sign-Based Validation Types

218

219

Types for validating the sign (positive/negative/zero) of numeric values.

220

221

```python { .api }

222

class IsPositive(IsNumber):

223

"""Checks value > 0."""

224

225

class IsNegative(IsNumber):

226

"""Checks value < 0."""

227

228

class IsNonNegative(IsNumber):

229

"""Checks value >= 0."""

230

231

class IsNonPositive(IsNumber):

232

"""Checks value <= 0."""

233

```

234

235

#### Usage Examples

236

237

```python

238

from dirty_equals import IsPositive, IsNegative, IsNonNegative, IsNonPositive

239

240

# Positive values (> 0)

241

assert 42 == IsPositive

242

assert 3.14 == IsPositive

243

assert 0.001 == IsPositive

244

245

# Negative values (< 0)

246

assert -42 == IsNegative

247

assert -3.14 == IsNegative

248

assert -0.001 == IsNegative

249

250

# Non-negative values (>= 0)

251

assert 42 == IsNonNegative

252

assert 0 == IsNonNegative # Zero is non-negative

253

254

# Non-positive values (<= 0)

255

assert -42 == IsNonPositive

256

assert 0 == IsNonPositive # Zero is non-positive

257

258

# In data validation

259

user_stats = {

260

'points': 150,

261

'balance': -25.50,

262

'login_count': 0,

263

'penalty_score': -10

264

}

265

266

assert user_stats == {

267

'points': IsPositive,

268

'balance': IsNegative,

269

'login_count': IsNonNegative, # Can be zero

270

'penalty_score': IsNonPositive # Zero or negative

271

}

272

```

273

274

### Integer Types

275

276

Specialized integer validation types with sign constraints.

277

278

```python { .api }

279

class IsInt(IsNumber):

280

"""Integer type checking."""

281

allowed_types: ClassVar[type] = int

282

283

class IsPositiveInt(IsInt):

284

"""Positive integer checking (> 0)."""

285

286

class IsNegativeInt(IsInt):

287

"""Negative integer checking (< 0)."""

288

```

289

290

#### Usage Examples

291

292

```python

293

from dirty_equals import IsInt, IsPositiveInt, IsNegativeInt

294

295

# Basic integer checking

296

assert 42 == IsInt

297

assert 0 == IsInt

298

assert -15 == IsInt

299

300

# Floats won't match

301

# assert 3.14 == IsInt # Would fail

302

303

# Positive integers

304

assert 42 == IsPositiveInt

305

assert 1 == IsPositiveInt

306

# assert 0 == IsPositiveInt # Would fail - zero is not positive

307

# assert -5 == IsPositiveInt # Would fail

308

309

# Negative integers

310

assert -42 == IsNegativeInt

311

assert -1 == IsNegativeInt

312

# assert 0 == IsNegativeInt # Would fail - zero is not negative

313

# assert 5 == IsNegativeInt # Would fail

314

315

# Database ID validation

316

user_record = {

317

'id': 123,

318

'parent_id': 456,

319

'sort_order': -1 # Negative for reverse order

320

}

321

322

assert user_record == {

323

'id': IsPositiveInt, # IDs should be positive

324

'parent_id': IsPositiveInt,

325

'sort_order': IsNegativeInt # Negative sort order

326

}

327

328

# API pagination parameters

329

pagination = {

330

'page': 1,

331

'per_page': 25,

332

'offset': 0,

333

'total_count': 150

334

}

335

336

assert pagination == {

337

'page': IsPositiveInt,

338

'per_page': IsPositiveInt,

339

'offset': IsInt, # Can be zero

340

'total_count': IsInt # Can be zero

341

}

342

```

343

344

### Float Types

345

346

Specialized float validation including special float values (infinity, NaN).

347

348

```python { .api }

349

class IsFloat(IsNumber):

350

"""Float type checking."""

351

allowed_types: ClassVar[type] = float

352

353

class IsPositiveFloat(IsFloat):

354

"""Positive float checking (> 0)."""

355

356

class IsNegativeFloat(IsFloat):

357

"""Negative float checking (< 0)."""

358

359

class IsFloatInf(IsFloat):

360

"""Infinite float checking (positive or negative)."""

361

362

class IsFloatInfPos(IsFloat):

363

"""Positive infinite float checking."""

364

365

class IsFloatInfNeg(IsFloat):

366

"""Negative infinite float checking."""

367

368

class IsFloatNan(IsFloat):

369

"""NaN (Not a Number) float checking."""

370

```

371

372

#### Usage Examples

373

374

```python

375

from dirty_equals import (

376

IsFloat, IsPositiveFloat, IsNegativeFloat,

377

IsFloatInf, IsFloatInfPos, IsFloatInfNeg, IsFloatNan

378

)

379

import math

380

381

# Basic float checking

382

assert 3.14 == IsFloat

383

assert 0.0 == IsFloat

384

assert -2.718 == IsFloat

385

386

# Integers won't match

387

# assert 42 == IsFloat # Would fail

388

389

# Positive floats

390

assert 3.14 == IsPositiveFloat

391

assert 0.001 == IsPositiveFloat

392

# assert 0.0 == IsPositiveFloat # Would fail - zero not positive

393

# assert -1.5 == IsPositiveFloat # Would fail

394

395

# Negative floats

396

assert -3.14 == IsNegativeFloat

397

assert -0.001 == IsNegativeFloat

398

# assert 0.0 == IsNegativeFloat # Would fail - zero not negative

399

# assert 1.5 == IsNegativeFloat # Would fail

400

401

# Special float values

402

assert float('inf') == IsFloatInf

403

assert float('-inf') == IsFloatInf

404

assert float('inf') == IsFloatInfPos

405

assert float('-inf') == IsFloatInfNeg

406

assert float('nan') == IsFloatNan

407

408

# Mathematical calculations with special values

409

calculation_results = {

410

'result1': 1.0 / 0.0, # Positive infinity

411

'result2': -1.0 / 0.0, # Negative infinity

412

'result3': 0.0 / 0.0, # NaN

413

'result4': math.sqrt(2.0) # Normal float

414

}

415

416

assert calculation_results == {

417

'result1': IsFloatInfPos,

418

'result2': IsFloatInfNeg,

419

'result3': IsFloatNan,

420

'result4': IsPositiveFloat

421

}

422

423

# Scientific computation validation

424

scientific_data = {

425

'temperature': 273.15,

426

'pressure': -1.5, # Negative relative pressure

427

'infinity_check': float('inf'),

428

'error_value': float('nan')

429

}

430

431

assert scientific_data == {

432

'temperature': IsPositiveFloat,

433

'pressure': IsNegativeFloat,

434

'infinity_check': IsFloatInf,

435

'error_value': IsFloatNan

436

}

437

438

# Numeric analysis results

439

analysis = {

440

'mean': 45.7,

441

'std_dev': 12.3,

442

'min_value': -infinity_placeholder, # Could be negative infinity

443

'max_value': infinity_placeholder, # Could be positive infinity

444

'invalid_calculations': [float('nan'), float('nan')]

445

}

446

447

# Validate statistical outputs

448

assert analysis == {

449

'mean': IsFloat,

450

'std_dev': IsPositiveFloat, # Standard deviation is always positive

451

'min_value': IsFloatInfNeg | IsFloat, # Could be normal float or -inf

452

'max_value': IsFloatInfPos | IsFloat, # Could be normal float or +inf

453

'invalid_calculations': [IsFloatNan, IsFloatNan]

454

}

455

```

456

457

## Type Definitions

458

459

```python { .api }

460

from typing import Any, ClassVar, Optional, Tuple, Union

461

from decimal import Decimal

462

from datetime import date, datetime

463

464

# All numeric types inherit from IsNumeric/IsNumber which inherit from DirtyEquals

465

# They work with Python's standard numeric types and the decimal module

466

```