90_array2d.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. from array2d import array2d
  2. from linalg import vec2i
  3. # test error args for __init__
  4. try:
  5. a = array2d(0, 0)
  6. exit(0)
  7. except ValueError:
  8. pass
  9. # test callable constructor
  10. a = array2d(2, 4, lambda: 0)
  11. assert a.width == a.n_cols == 2
  12. assert a.height == a.n_rows == 4
  13. assert a.numel == 8
  14. # test is_valid
  15. assert a.is_valid(0, 0) and a.is_valid(vec2i(0, 0))
  16. assert a.is_valid(1, 3) and a.is_valid(vec2i(1, 3))
  17. assert not a.is_valid(2, 0) and not a.is_valid(vec2i(2, 0))
  18. assert not a.is_valid(0, 4) and not a.is_valid(vec2i(0, 4))
  19. assert not a.is_valid(-1, 0) and not a.is_valid(vec2i(-1, 0))
  20. assert not a.is_valid(0, -1) and not a.is_valid(vec2i(0, -1))
  21. # test get
  22. assert a.get(0, 0) == 0
  23. assert a.get(1, 3) == 0
  24. assert a.get(2, 0) is None
  25. assert a.get(0, 4, 'S') == 'S'
  26. # test __getitem__
  27. assert a[0, 0] == 0
  28. assert a[1, 3] == 0
  29. try:
  30. a[2, 0]
  31. exit(1)
  32. except IndexError:
  33. pass
  34. # test __setitem__
  35. a[0, 0] = 5
  36. assert a[0, 0] == 5
  37. a[1, 3] = 6
  38. assert a[1, 3] == 6
  39. try:
  40. a[0, -1] = 7
  41. exit(1)
  42. except IndexError:
  43. pass
  44. # test __iter__
  45. a_list = [[5, 0], [0, 0], [0, 0], [0, 6]]
  46. assert a_list == a.tolist()
  47. # test __len__
  48. assert len(a) == 4*2
  49. # test __eq__
  50. x = array2d(2, 4, default=0)
  51. b = array2d(2, 4, default=0)
  52. assert x == b
  53. b[0, 0] = 1
  54. assert x != b
  55. # test __repr__
  56. assert repr(a) == f'array2d(2, 4)'
  57. # test map
  58. c = a.map(lambda x: x + 1)
  59. assert c.tolist() == [[6, 1], [1, 1], [1, 1], [1, 7]]
  60. assert a.tolist() == [[5, 0], [0, 0], [0, 0], [0, 6]]
  61. assert c.width == c.n_cols == 2
  62. assert c.height == c.n_rows == 4
  63. assert c.numel == 8
  64. # test copy
  65. d = c.copy()
  66. assert d == c and d is not c
  67. # test fill_
  68. d.fill_(-3)
  69. assert d == array2d(2, 4, default=-3)
  70. # test apply_
  71. d.apply_(lambda x: x + 3)
  72. assert d == array2d(2, 4, default=0)
  73. # test copy_
  74. a.copy_(d)
  75. assert a == d and a is not d
  76. x = array2d(2, 4, default=0)
  77. x.copy_(d)
  78. assert x == d and x is not d
  79. x.copy_([1, 2, 3, 4, 5, 6, 7, 8])
  80. assert x.tolist() == [[1, 2], [3, 4], [5, 6], [7, 8]]
  81. # test find_one
  82. a = array2d(3, 3, default=0)
  83. a[1, 1] = 1
  84. assert a.find_one(lambda x: x == 1) == vec2i(1, 1)
  85. try:
  86. a.find_one(lambda x: x == 2)
  87. exit(1)
  88. except ValueError:
  89. pass
  90. # test alive_neighbors
  91. a = array2d[int](3, 3, default=0)
  92. a[1, 1] = 1
  93. """ Moore von Neumann
  94. 0 0 0 1 1 1 0 1 0
  95. 0 1 0 1 0 1 1 0 1
  96. 0 0 0 1 1 1 0 1 0
  97. """
  98. moore_result = array2d(3, 3, default=1)
  99. moore_result[1, 1] = 0
  100. von_neumann_result = array2d(3, 3, default=0)
  101. von_neumann_result[0, 1] = von_neumann_result[1, 0] = von_neumann_result[1, 2] = von_neumann_result[2, 1] = 1
  102. _0 = a.count_neighbors(1, 'Moore')
  103. assert _0 == moore_result
  104. _1 = a.count_neighbors(1, 'von Neumann')
  105. assert _1 == von_neumann_result
  106. MOORE_KERNEL = array2d[int](3, 3, default=1)
  107. MOORE_KERNEL[1, 1] = 0
  108. VON_NEUMANN_KERNEL = array2d[int](3, 3, default=0)
  109. VON_NEUMANN_KERNEL[0, 1] = VON_NEUMANN_KERNEL[1, 0] = VON_NEUMANN_KERNEL[1, 2] = VON_NEUMANN_KERNEL[2, 1] = 1
  110. moore_conv_result = a.convolve(MOORE_KERNEL, 0)
  111. assert moore_conv_result == moore_result
  112. von_neumann_conv_result = a.convolve(VON_NEUMANN_KERNEL, 0)
  113. assert von_neumann_conv_result == von_neumann_result
  114. # test slice get
  115. a = array2d(5, 5, default=0)
  116. b = array2d(3, 2, default=1)
  117. assert a[1:4, 1:4] == array2d(3, 3, default=0)
  118. assert a[1:4, 1:3] == array2d(3, 2, default=0)
  119. assert a[1:4, 1:3] != b
  120. a[1:4, 1:3] = b
  121. assert a[1:4, 1:3] == b
  122. """
  123. 0 0 0 0 0
  124. 0 1 1 1 0
  125. 0 1 1 1 0
  126. 0 0 0 0 0
  127. 0 0 0 0 0
  128. """
  129. assert a.count(1) == 3*2
  130. assert a.find_bounding_rect(1) == (1, 1, 3, 2)
  131. assert a.find_bounding_rect(0) == (0, 0, 5, 5)
  132. try:
  133. a.find_bounding_rect(2)
  134. exit(1)
  135. except ValueError:
  136. pass
  137. a = array2d(3, 2, default='?')
  138. # int/float/str/bool/None
  139. for value in [0, 0.0, '0', False, None]:
  140. a[0:2, 0:1] = value
  141. assert a[2, 1] == '?'
  142. assert a[0, 0] == value
  143. a[:, :] = 3
  144. assert a == array2d(3, 2, default=3)
  145. try:
  146. a[:, :] = array2d(1, 1)
  147. exit(1)
  148. except ValueError:
  149. pass
  150. try:
  151. a[:, :] = ...
  152. exit(1)
  153. except TypeError:
  154. pass
  155. a = array2d(3, 4, default=1)
  156. for i, j, x in a:
  157. assert a[i, j] == x
  158. assert len(a) == a.numel
  159. # test _get and _set
  160. a = array2d(3, 4, default=1)
  161. assert a.unsafe_get(0, 0) == 1
  162. a.unsafe_set(0, 0, 2)
  163. assert a.unsafe_get(0, 0) == 2
  164. # test convolve
  165. a = array2d[int](5, 2, default=0)
  166. """
  167. 1 0 2 4 0
  168. 3 1 0 5 1
  169. """
  170. a[0, 0] = 1; a[1, 0] = 0; a[2, 0] = 2; a[3, 0] = 4; a[4, 0] = 0
  171. a[0, 1] = 3; a[1, 1] = 1; a[2, 1] = 0; a[3, 1] = 5; a[4, 1] = 1
  172. assert a.tolist() == [[1, 0, 2, 4, 0], [3, 1, 0, 5, 1]]
  173. kernel = array2d[int](3, 3, default=1)
  174. res = a.convolve(kernel, -1)
  175. """
  176. 0 4 9 9 5
  177. 0 4 9 9 5
  178. """
  179. assert res.tolist() == [[0, 4, 9, 9, 5], [0, 4, 9, 9, 5]]
  180. # stackoverflow bug due to recursive mark-and-sweep
  181. # class Cell:
  182. # neighbors: list['Cell']
  183. # cells: array2d[Cell] = array2d(192, 108, default=Cell)
  184. # OutOfBounds = Cell()
  185. # for x, y, cell in cells:
  186. # cell.neighbors = [
  187. # cells.get(x-1, y-1, OutOfBounds),
  188. # cells.get(x , y-1, OutOfBounds),
  189. # cells.get(x+1, y-1, OutOfBounds),
  190. # cells.get(x-1, y , OutOfBounds),
  191. # cells.get(x+1, y , OutOfBounds),
  192. # cells.get(x , y+1, OutOfBounds),
  193. # cells.get(x+1, y+1, OutOfBounds),
  194. # ]
  195. # import gc
  196. # gc.collect()