Examples

The examples below pass a tuple to the check method. In practice you can pass any instance with a shape property.

Basic Usage

You can use ShapeCheck to verify that array shapes match a pattern:

from ndshapecheck.shape_check import ShapeCheck

sc = ShapeCheck()
sc('1,2,3').check((1, 2, 3))  # ✅ Passes
sc('N,M').check((5, 5))       # ✅ N = 5, M = 5
sc('N,1,M').check((3, 1, 4))  # ❌ Fails
sc('N,1,M').check((5, 1, 5))  # ✅ N = 5, M = 5

Symbols

Symbols (like N, M, A) represent dimensions that can match any value:

sc = ShapeCheck()
sc('A,B,C').check((1920, 1080, 3))  # ✅ A=1920, B=1080, C=3
sc('A').check((1920,))              # ✅ A=1920

Optional Dimensions (?)

Use ? to indicate a dimension may or may not be present:

sc = ShapeCheck()
sc('M?,1,2').check((1, 2))         # ✅ M? is omitted
sc('M?,1,2').check((1, 1, 2))      # ❌ Fails, M? should be omitted.

Multiple Dimensions (* and +)

  • *: Zero or more dimensions

  • +: One or more dimensions

sc = ShapeCheck()
sc('longer_symbol_1+,3').check((1, 3))                   # ✅ 'longer_symbol_1+'=1
sc('longer_symbol_2+,3').check((1, 2, 3, 5, 4, 10, 3, 3))# ✅ 'longer_symbol_2+'=(1,2,3,5,4,10,3,3)

sc('N*').check((1, 2, 3))                  # ✅ N*=(1,2,3)
sc('N*,2').check((1, 2, 3, 2))             # ✅

Consistency of Symbols Across Checks

A ShapeCheck instance remembers the values assigned to symbols between checks.

sc = ShapeCheck()

sc('N,M').check((1, 2))  # ✅ N=1, M=2

sc('N,2?').check((1,))  # ✅ N=1, second dim=(), OK

sc('N,2').check((2, 2))  # ❌ Fails: N = 1, got 2

If you want independent checks with fresh symbols, create a new ShapeCheck() instance.

ShapeCheck.why

If a shape check fails, ShapeCheck records a human-readable explanation in why.

sc = ShapeCheck()

sc('N?,1,2,3').check((1, 2, 3))
print(sc.why)  # ''

sc('N?,3').check((1, 3))
print(sc.why)  # "The shape (1, 3) does not match the rule 'N?=(),3'."

sc('dims,N*').check((3, 56, 54))
sc('dims,N*').check((4, 56, 54))
print(sc.why)  # "The shape (4, 56, 54) does not match the rule 'dims=(3,),N*=(56, 54)'."

Invalid Examples

These examples show when a shape does not match:

sc('1,2').check((1,1))         # ❌ Different second dimension
sc('A,B').check((1,))          # ❌ Missing B
sc('1,A*').check((2,1))        # ❌ Different first dimension.
sc('X?,A+').check((3,))        # ❌ Needs at least one more for A