00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 from __future__ import division
00033 from random import randint
00034 from math import floor
00035 from math import ceil
00036 from array import array
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 class RandomQueue:
00052
00053 def __init__(self):
00054
00055 self.array = []
00056
00057
00058 def empty(self):
00059 return len(self.array) <= 0
00060
00061
00062 def push(self, x):
00063 self.array.append(x)
00064
00065
00066
00067
00068 def pop(self):
00069 n = len(self.array)
00070
00071 if n <= 0:
00072 raise IndexError('Cannot pop from emty container!')
00073 elif n == 1:
00074 return self.array.pop()
00075 else:
00076 i = randint(0, n - 1)
00077 j = n - 1
00078 self.array[i], self.array[j] = self.array[j], self.array[i]
00079
00080 return self.array.pop()
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 def signum(x):
00094 if x > 0:
00095 return 1
00096 elif x < 0:
00097 return -1
00098 else:
00099 return 0
00100
00101
00102 def int_point_2d(p):
00103 x, y = p
00104 return int(x), int(y)
00105
00106
00107 def int_point_3d(p):
00108 x, y, z = p
00109 return int(x), int(y), int(z)
00110
00111
00112
00113
00114 def points_to_grid(points, dimensions):
00115 grid = Grid2D(dimensions, 0)
00116
00117 for point in points:
00118 grid[int_point_2d(point)] = 1
00119
00120 return grid
00121
00122
00123
00124
00125
00126
00127 def points_to_grid_3d(points, dimensions):
00128 grid = Grid3D(dimensions, 0)
00129
00130 for point in points:
00131 grid[int_point_3d(point)] = 1
00132
00133 return grid
00134
00135 def make_grid_1d(width, initial_item=None):
00136 grid = [initial_item] * width
00137
00138 return grid
00139
00140
00141 def make_grid_2d(width, height, initial_item=None):
00142 grid = [None] * width
00143
00144 for i in xrange(width):
00145 grid[i] = [None] * height
00146
00147 for j in xrange(height):
00148 grid[i][j] = initial_item
00149
00150 return grid
00151
00152
00153 def make_grid_3d(width, height, depth, initial_item):
00154 grid = [None] * width
00155
00156 for i in xrange(width):
00157 grid[i] = [None] * height
00158
00159 for j in xrange(height):
00160 grid[i][j] = [None] * depth
00161
00162 for k in xrange(depth):
00163 grid[i][j][k] = initial_item
00164
00165 return grid
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 def srange(s, length):
00182 if s == Ellipsis:
00183 return xrange(length)
00184 else:
00185 b, e, s = s.indices(length)
00186 return xrange(b, e, s)
00187
00188
00189 def is_slice(s):
00190 return type(s) is slice or s == Ellipsis
00191
00192
00193
00194 def slice_len(s, length):
00195 if s == Ellipsis:
00196 return length
00197
00198 b, e, s, = s.indices(length)
00199
00200 tmp = int(ceil((e - b) / s))
00201
00202 if tmp < 0:
00203 return 0
00204 else:
00205 return min(tmp, length)
00206
00207 if s.stop > s.start and s.step > 0:
00208 return (s.stop - s.start) // s.step
00209 elif s.stop < s.start and s.step < 0:
00210 return (s.start - s.stop) // -s.step
00211 else:
00212 return 0
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 def slice_mul(slice1, slice2, length):
00225 if type(slice2) is int:
00226 if type(slice1) is type(Ellipsis):
00227 return slice2
00228 b1, e1, s1 = slice1.indices(length)
00229 s2 = slice2
00230 if s2 < 0:
00231 s2 += length
00232 if s2 < 0:
00233 s2 = 0
00234 return b1 + s2*s1
00235 elif type(slice2) is slice:
00236 if type(slice1) is type(Ellipsis):
00237 return slice2
00238 else:
00239 b1, e1, s1 = slice1.indices(length)
00240 b2, e2, s2 = slice2.indices(length)
00241 b = b1 + b2*s1
00242 s = s1*s2
00243 e = min(b1 + e2*s1, e1)
00244
00245 if e < 0 and s < 0:
00246 return slice(b, None, s)
00247 else:
00248 return slice(b, e, s)
00249
00250
00251
00252 b = slice1.start + slice2.start*slice1.step
00253 s = slice1.step*slice2.step
00254 return slice(b, min(slice1.start + slice2.stop*slice1.step, slice1.stop), s)
00255 elif slice2 == Ellipsis:
00256 return slice1
00257
00258
00259
00260
00261
00262
00263
00264 def complete_slice(s, length):
00265 return s
00266
00267
00268
00269
00270
00271
00272
00273
00274 class PrincipleContainer:
00275 pass
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 class AuxiliaryContainer:
00288 pass
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 class Container:
00302
00303
00304
00305
00306 def __init__(self, dims):
00307 self.dims = dims
00308
00309 count = 1
00310
00311 for dim in dims:
00312 count *= dim
00313
00314 self.count = count
00315
00316
00317
00318 def __eq__(self, other):
00319 if other == None:
00320 return False
00321 if self.dims != other.dims:
00322 return False
00323
00324 for cell1, cell2 in zip(self.cell_iter(), other.cell_iter()):
00325 if cell1 != cell2:
00326 return False
00327 return True
00328
00329
00330 def __ne__(self, other):
00331 return not (self == other)
00332
00333
00334
00335
00336
00337 def __len__(self):
00338 return self.dims[0]
00339
00340
00341
00342
00343
00344 def min_max(self):
00345 cell_iter = self.cell_iter()
00346 min = max = cell_iter.next()
00347
00348 for cell in cell_iter:
00349 if cell > max:
00350 max = cell
00351 elif cell < min:
00352 min = cell
00353 return min, max
00354
00355 def copy_from(self, other):
00356 for index in self.index_iter():
00357 self[index] = other[index]
00358
00359
00360
00361
00362
00363
00364
00365
00366 def clone(self):
00367 new_grid = self.__clonetype__(self.dims)
00368 new_grid.copy_from(self)
00369
00370 return new_grid
00371
00372
00373 class Container1D (Container):
00374 def __init__(self, length):
00375 Container.__init__(self, (length,))
00376 self.length = length
00377 self.__clonetype__ = Grid1D
00378
00379 def __str__(self):
00380
00381 glst = []
00382
00383 for i in xrange(self.length):
00384 glst.append(self[i])
00385
00386 return glst.__repr__()
00387
00388 def __iter__(self):
00389 for i in xrange(self.length):
00390 yield self[i]
00391 raise StopIteration
00392
00393
00394
00395
00396 def cell_iter(self):
00397 return self.__iter__()
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408 def window_iter(self, x1, x0):
00409 for i in xrange(max(0, x0), min(x1, self.length)):
00410 yield self[i]
00411 raise StopIteration
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424 def wrapped_window_iter(self, x1, x0):
00425 for i in xrange(x0, x1):
00426 yield self[i % self.length]
00427 raise StopIteration
00428
00429
00430
00431
00432
00433 def square_iter(self, x, n):
00434 return self.window_iter(x - n, x + n + 1)
00435
00436 def wrapped_square_iter(self, x, n):
00437 return self.wrapped_window_iter(x - n, x + n + 1)
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459 def index_iter(self):
00460 for i in xrange(self.length):
00461 yield i
00462 raise StopIteration
00463
00464
00465 class Container2D (Container):
00466 def __init__(self, width, height):
00467 Container.__init__(self, (width, height))
00468 self.width = width
00469 self.height = height
00470 self.__clonetype__ = Grid2D
00471
00472 def __str__(self):
00473
00474 glst = []
00475
00476 for i in xrange(self.width):
00477 gcol = []
00478
00479 for j in xrange(self.height):
00480 gcol.append(self[i, j])
00481
00482 glst.append(gcol)
00483
00484 return glst.__repr__()
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496 def __iter__(self):
00497 for i in xrange(self.width):
00498 yield self[i, ...]
00499 raise StopIteration
00500
00501
00502
00503
00504
00505
00506
00507
00508 def cell_iter(self):
00509 for i in xrange(self.width):
00510 for j in xrange(self.height):
00511 yield self[i, j]
00512 raise StopIteration
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523 def window_index_iter(self, p0, p1):
00524 x0, y0 = p0
00525 x1, y1 = p1
00526 for i in xrange(max(0, x0), min(x1, self.width)):
00527 for j in xrange(max(0, y0), min(y1, self.height)):
00528 yield (i, j)
00529 raise StopIteration
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542 def wrapped_window_index_iter(self, p0, p1):
00543 x0, y0 = p0
00544 x1, y1 = p1
00545 for i in xrange(x0, x1):
00546 for j in xrange(y0, y1):
00547 yield (i % self.width, j % self.height)
00548 raise StopIteration
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558 def window_iter(self, p0, p1):
00559 x0, y0 = p0
00560 x1, y1 = p1
00561 for i in xrange(max(0, x0), min(x1, self.width)):
00562 for j in xrange(max(0, y0), min(y1, self.height)):
00563 yield self[i, j]
00564 raise StopIteration
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578 def wrapped_window_iter(self, p0, p1):
00579 x0, y0 = p0
00580 x1, y1 = p1
00581 for i in xrange(x0, x1):
00582 for j in xrange(y0, y1):
00583 yield self[i % self.width, j % self.height]
00584 raise StopIteration
00585
00586
00587
00588
00589
00590 def square_index_iter(self, p, n):
00591 x, y = p
00592 return self.window_index_iter((x - n, y - n), (x + n + 1, y + n +1))
00593
00594
00595
00596
00597
00598
00599
00600
00601 def wrapped_square_index_iter(self, p, n):
00602 x, y = p
00603 return self.wrapped_window_index_iter((x - n, y - n), (x + n + 1, y + n +1))
00604
00605
00606
00607
00608
00609
00610 def square_iter(self, p, n):
00611 x, y = p
00612 return self.window_iter((x - n, y - n), (x + n + 1, y + n +1))
00613
00614
00615
00616
00617
00618
00619
00620
00621 def wrapped_square_iter(self, p, n):
00622 x, y = p
00623 return self.wrapped_window_iter((x - n, y - n), (x + n + 1, y + n +1))
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645 def index_iter(self):
00646 for i in xrange(self.width):
00647 for j in xrange(self.height):
00648 yield i, j
00649 raise StopIteration
00650
00651
00652 class Container3D (Container):
00653 def __init__(self, width, height, depth):
00654 Container.__init__(self, (width, height, depth))
00655 self.width = width
00656 self.height = height
00657 self.depth = depth
00658
00659 self.__clonetype__ = Grid3D
00660
00661 def __str__(self):
00662
00663 glst = []
00664
00665 for i in xrange(self.width):
00666 gcol = []
00667 for j in xrange(self.height):
00668 gslice = []
00669
00670 for k in xrange(self.depth):
00671 gslice.append(self[i, j, k])
00672
00673 gcol.append(gslice)
00674 glst.append(gcol)
00675
00676 return glst.__repr__()
00677
00678 def __iter__(self):
00679 for i in xrange(self.width):
00680 yield self[i, ..., ...]
00681 raise StopIteration
00682
00683
00684 def cell_iter(self):
00685 for i in xrange(self.width):
00686 for j in xrange(self.height):
00687 for k in xrange(self.depth):
00688 yield self[i, j, k]
00689 raise StopIteration
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711 def index_iter(self):
00712 for i in xrange(self.width):
00713 for j in xrange(self.height):
00714 for k in xrange (self.depth):
00715 yield i, j, k
00716 raise StopIteration
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728 def window_iter(self, p0, p1):
00729 x0, y0, z0 = p0
00730 x1, y1, z1 = p1
00731
00732 for i in xrange(max(0, x0), min(x1, self.width)):
00733 for j in xrange(max(0, y0), min(y1, self.height)):
00734 for k in xrange(max(0, z0), min(z1, self.depth)):
00735 yield self[i, j, k]
00736 raise StopIteration
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749 def wrapped_window_iter(self, p0, p1):
00750 x0, y0, z0 = p0
00751 x1, y1, z1 = p1
00752
00753 for i in xrange(x0, x1):
00754 for j in xrange(y0, y1):
00755 for k in xrange(z0, z1):
00756 yield self[i % self.width, j % self.height, k % self.depth]
00757 raise StopIteration
00758
00759
00760
00761
00762 def square_iter(self, p, n):
00763 x, y, z = p
00764 return self.window_iter(
00765 (x - n, y - n, z - n),
00766 (x + n + 1, y + n +1, z + n +1))
00767
00768
00769
00770
00771 def wrapped_square_iter(self, p, n):
00772 x, y, z = p
00773 return self.wrapped_window_iter(
00774 (x - n, y - n, z - n),
00775 (x + n + 1, y + n +1, z + n +1))
00776
00777 class GridWindow1D (Container1D, AuxiliaryContainer):
00778 def __init__(self, grid, col_slice):
00779 self.grid = grid
00780 self.x = complete_slice(col_slice, grid.width)
00781 Container1D.__init__(self, slice_len(self.x), grid.width)
00782
00783 def __getitem__(self, x):
00784 new_x = slice_mul(self.x, x, self.grid.width)
00785
00786 return self.grid[new_x]
00787
00788 def __setitem__(self, x, item):
00789 new_x = slice_mul(self.x, x, self.grid.width)
00790
00791 if type(x) is int:
00792 self.grid[new_x] = item
00793 else:
00794 for i, item_i in zip(srange(new_x, self.grid.width), item):
00795 self.grid[i] = item_i
00796
00797
00798 class Grid1D (Container1D, PrincipleContainer):
00799 def __init__(self, dims, initial_item = None):
00800 (width,) = dims
00801 Container1D.__init__(self, width)
00802 self.grid = make_grid_1d(width, initial_item)
00803 self.width = width
00804
00805
00806
00807
00808
00809
00810
00811 def cell_iter(self):
00812 for i in xrange(self.width):
00813 yield self.grid[i]
00814 raise StopIteration
00815
00816 def __getitem__(self, x):
00817 if isinstance(x, int):
00818 return self.grid[x]
00819 elif is_slice(x):
00820 GridWindow1D(self, x)
00821 raise TypeError
00822
00823 def __setitem__(self, x, item):
00824 if type(x) is int:
00825 self.grid[x] = item
00826 elif is_slice(x):
00827 g = GridWindow1D(self, x)
00828 g[...] = item
00829 else:
00830 raise TypeError
00831
00832 class GridRow2D (Container1D, AuxiliaryContainer):
00833 def __init__(self, grid, col_slice, row):
00834 self.grid = grid
00835 self.x = complete_slice(col_slice, grid.width)
00836 self.y = row
00837
00838 Container1D.__init__(self, slice_len(self.x, grid.width))
00839
00840 def __getitem__(self, x):
00841 new_x = slice_mul(self.x, x, self.grid.width)
00842
00843 return self.grid[new_x, self.y]
00844
00845 def __setitem__(self, x, item):
00846 new_x = slice_mul(self.x, x, self.grid.width)
00847
00848 if type(x) is int:
00849 self.grid[new_x] = item
00850 else:
00851 for i, item_i in zip(srange(new_x, self.grid.width), item):
00852 self.grid[i, self.y] = item_i
00853
00854 class GridCol2D (Container1D, AuxiliaryContainer):
00855 def __init__(self, grid, col, row_slice):
00856 self.grid = grid
00857 self.x = col
00858 self.y = complete_slice(row_slice, grid.height)
00859
00860 Container1D.__init__(self, slice_len(self.y, grid.height))
00861
00862 def __getitem__(self, y):
00863 new_y = slice_mul(self.y, y, self.grid.height)
00864
00865 return self.grid[self.x, new_y]
00866
00867 def __setitem__(self, y, item):
00868 new_y = slice_mul(self.y, y, self.grid.height)
00869
00870 if type(y) is int:
00871 self.grid[self.x, new_y] = item
00872 else:
00873 for i, item_i in zip(srange(new_y, self.grid.height), item):
00874 self.grid[self.x, i] = item_i
00875
00876 class GridWindow2D (Container2D):
00877 def __init__(self, grid, x, y):
00878 self.grid = grid
00879 self.x = complete_slice(x, grid.width)
00880 self.y = complete_slice(y, grid.height)
00881
00882 Container2D.__init__(self, slice_len(self.x, grid.width), slice_len(self.y, grid.height))
00883
00884 def __getitem__(self, p):
00885 if isinstance(p, int):
00886 return self[p, ...]
00887 x, y = p
00888
00889 new_x = slice_mul(self.x, x, self.grid.width)
00890 new_y = slice_mul(self.y, y, self.grid.height)
00891 return self.grid[new_x, new_y]
00892
00893 def __setitem__(self, p, item):
00894 if isinstance(p, int):
00895 self[p, ...] = item
00896 x, y = p
00897 new_x = slice_mul(self.x, x, self.grid.width)
00898 new_y = slice_mul(self.y, y, self.grid.height)
00899
00900 if type(x) is int or type(y) is int:
00901
00902 self.grid[new_x, new_y] = item
00903 else:
00904 for i, item_i in zip(srange(new_x, self.grid.width), item):
00905 for j, item_j in zip(srange(new_y, self.grid.height), item_i):
00906 self.grid[i, j] = item_j
00907
00908 def __repr__(self):
00909
00910 glst = []
00911
00912 for i in xrange(slice_len(self.x, self.grid.width)):
00913 gcol = []
00914 for j in xrange(slice_len(self.y, self.grid.height)):
00915 gcol.append(self[i, j])
00916 glst.append(gcol)
00917
00918 return glst.__repr__()
00919
00920
00921 class Grid2D (Container2D, PrincipleContainer):
00922
00923 def __init__(self, dims, initial_item = None):
00924 (width, height) = dims
00925 Container2D.__init__(self, width, height)
00926 self.grid = make_grid_2d(width, height, initial_item)
00927
00928
00929
00930
00931
00932
00933
00934 def cell_iter(self):
00935 for i in xrange(self.width):
00936 for j in xrange(self.height):
00937 yield self.grid[i][j]
00938 raise StopIteration
00939
00940 def __getitem__(self, p):
00941 if isinstance(p, int):
00942 return self[p, ...]
00943 x, y = p
00944 if isinstance(x, int):
00945 if isinstance(y, int):
00946 return self.grid[x][y]
00947 elif is_slice(y):
00948 return GridCol2D(self, x, y)
00949 elif is_slice(x):
00950 if isinstance(y, int):
00951 return GridRow2D(self, x, y)
00952 elif is_slice(y):
00953 return GridWindow2D(self, x, y)
00954
00955 raise TypeError
00956
00957 def __setitem__(self, p, item):
00958 x, y = p
00959 if type(x) is int:
00960 if type(y) is int:
00961 self.grid[x][y] = item
00962 elif is_slice(y):
00963 g = GridCol2D(self, x, y)
00964 g[...] = item
00965 elif is_slice(x):
00966 if type(y) is int:
00967 g = GridRow2D(self, x, y)
00968 g[...] = item
00969 elif is_slice(y):
00970 g = GridWindow2D(self, x, y)
00971 g[..., ...] = item
00972 else:
00973 raise TypeError
00974
00975 class GridBar3D (Container1D, AuxiliaryContainer):
00976 def __init__(self, grid, x, y, z):
00977 self.grid = grid
00978 self.x = x
00979 self.y = y
00980 self.z = complete_slice(z, grid.depth)
00981
00982 Container1D.__init__(self, slice_len(self.z, grid.depth))
00983
00984 def __getitem__(self, z):
00985 new_z = slice_mul(self.z, z, self.grid.depth)
00986 return self.grid[self.x, self.y, new_z]
00987
00988 def __setitem__(self, z, item):
00989 new_z = slice_mul(self.z, z, self.grid.depth)
00990
00991 if type(z) is int:
00992 self.grid[new_z] = item
00993 else:
00994 for i, item_i in zip(srange(new_z, self.grid.depth), item):
00995 self.grid[self.x, self.y, i] = item_i
00996
00997 class GridCol3D (Container1D, AuxiliaryContainer):
00998 def __init__(self, grid, x, y, z):
00999 self.grid = grid
01000 self.x = x
01001 self.y = complete_slice(y, grid.height)
01002 self.z = z
01003
01004 Container1D.__init__(self, slice_len(self.y, grid.height))
01005
01006 def __getitem__(self, y):
01007 new_y = slice_mul(self.y, y, self.grid.height)
01008 return self.grid[self.x, new_y, self.z]
01009 def __setitem__(self, y, item):
01010 new_y = slice_mul(self.y, y, self.grid.height)
01011
01012 if type(y) is int:
01013 self.grid[new_y] = item
01014 else:
01015 for i, item_i in zip(srange(new_y, self.grid.height), item):
01016 self.grid[self.x, i, self.z] = item_i
01017
01018 class GridRow3D (Container1D, AuxiliaryContainer):
01019 def __init__(self, grid, x, y, z):
01020 self.grid = grid
01021 self.x = complete_slice(x, grid.width)
01022 self.y = y
01023 self.z = z
01024
01025 Container1D.__init__(self, slice_len(self.x, grid.width))
01026 def __getitem__(self, x):
01027 new_x = slice_mul(self.x, x, self.grid.width)
01028 return self.grid[new_x, self.y, self.z]
01029 def __setitem__(self, x, item):
01030 new_x = slice_mul(self.x, x, self.grid.width)
01031
01032 if type(x) is int:
01033 self.grid[new_x] = item
01034 else:
01035 for i, item_i in zip(srange(new_x, self.grid.width), item):
01036 self.grid[i, self.y, self.y] = item_i
01037
01038 class GridSliceXY (Container2D, AuxiliaryContainer):
01039 def __init__(self, grid, x, y, z):
01040 self.grid = grid
01041 self.x = complete_slice(x, grid.width)
01042 self.y = complete_slice(y, grid.height)
01043 self.z = z
01044 Container2D.__init__(self, slice_len(self.x, grid.width), slice_len(self.y, grid.height))
01045 def __getitem__(self, p):
01046 if isinstance(p, int):
01047 return self[p, ...]
01048 x, y = p
01049 new_x = slice_mul(self.x, x, self.grid.width)
01050 new_y = slice_mul(self.y, y, self.grid.height)
01051 return self.grid[new_x, new_y, self.z]
01052
01053 def __setitem__(self, p, item):
01054 if isinstance(p, int):
01055 self[p, ...] = item
01056 x, y = p
01057 new_x = slice_mul(self.x, x, self.grid.width)
01058 new_y = slice_mul(self.y, y, self.grid.height)
01059
01060 if type(x) is int or type(y) is int:
01061
01062 self.grid[new_x, new_y, self.z] = item
01063 else:
01064 for i, item_i in zip(srange(new_x, self.grid.width), item):
01065 for j, item_j in zip(srange(new_y, self.grid.height), item_i):
01066 self.grid[i, j, self.z] = item_j
01067
01068 class GridSliceXZ (Container2D, AuxiliaryContainer):
01069 def __init__(self, grid, x, y, z):
01070 self.grid = grid
01071 self.x = complete_slice(x, grid.width)
01072 self.y = y
01073 self.z = complete_slice(z, grid.depth)
01074
01075 Container2D.__init__(self, slice_len(self.x, grid.width), slice_len(self.z, grid.depth))
01076 def __getitem__(self, p):
01077 if isinstance(p, int):
01078 return self[p, ...]
01079 x, z = p
01080 new_x = slice_mul(self.x, x, self.grid.width)
01081 new_z = slice_mul(self.z, z, self.grid.depth)
01082 return self.grid[new_x, self.y, new_z]
01083
01084 def __setitem__(self, p, item):
01085 if isinstance(p, int):
01086 return self[p, ...]
01087 x, z = p
01088 new_x = slice_mul(self.x, x, self.grid.width)
01089 new_z = slice_mul(self.z, z, self.grid.depth)
01090
01091 if type(x) is int or type(z) is int:
01092
01093 self.grid[new_x, self.y, new_z] = item
01094 else:
01095 for i, item_i in zip(srange(new_x, self.grid.width), item):
01096 for j, item_j in zip(srange(new_z, self.grid.depth), item_i):
01097 self.grid[i, self.y, j] = item_j
01098
01099 class GridSliceYZ (Container2D, AuxiliaryContainer):
01100 def __init__(self, grid, x, y, z):
01101 self.grid = grid
01102 self.x = x
01103 self.y = complete_slice(y, grid.height)
01104 self.z = complete_slice(z, grid.depth)
01105
01106 Container2D.__init__(self, slice_len(self.y, grid.height), slice_len(self.z, grid.depth))
01107 def __getitem__(self, p):
01108 if isinstance(p, int):
01109 return self[p, ...]
01110 y, z = p
01111 new_y = slice_mul(self.y, y, self.grid.height)
01112 new_z = slice_mul(self.z, z, self.grid.depth)
01113 return self.grid[self.x, new_y, new_z]
01114
01115 def __setitem__(self, p, item):
01116 if isinstance(p, int):
01117 self[p, ...] = item
01118 y, z = p
01119 new_y = slice_mul(self.y, y, self.grid.height)
01120 new_z = slice_mul(self.z, z, self.grid.depth)
01121
01122 if type(y) is int or type(z) is int:
01123
01124 self.grid[self.x, new_y, new_z] = item
01125 else:
01126 for i, item_i in zip(srange(new_y), item):
01127 for j, item_j in zip(srange(new_z), item_i):
01128 self.grid[self.x, i, j] = item_j
01129
01130 class GridWindow3D (Container3D, AuxiliaryContainer):
01131 def __init__(self, grid, x, y, z):
01132 self.grid = grid
01133 self.x = complete_slice(x, grid.width)
01134 self.y = complete_slice(y, grid.height)
01135 self.z = complete_slice(z, grid.height)
01136
01137 Container3D.__init__(self, slice_len(self.x, grid.width), slice_len(self.y, grid.height), slice_len(self.z, grid.depth))
01138 def __getitem__(self, p):
01139 if isinstance(p, int):
01140 return self[p, ..., ...]
01141 x, y, z = p
01142 new_x = slice_mul(self.x, x, self.grid.width)
01143 new_y = slice_mul(self.y, y, self.grid.height)
01144 new_z = slice_mul(self.z, z, self.grid.depth)
01145
01146 return self.grid[new_x, new_y, new_z]
01147
01148 def __setitem__(self, p, item):
01149 if isinstance(p, int):
01150 self[p, ..., ...] = item
01151 x, y, z = p
01152 new_x = slice_mul(self.x, x, self.grid.width)
01153 new_y = slice_mul(self.y, y, self.grid.height)
01154 new_z = slice_mul(self.z, z, self.grid.depth)
01155
01156 if type(x) is int or type(y) is int or type(z) is int:
01157
01158 self.grid[new_x, new_y, self.z] = item
01159 else:
01160 for i, item_i in zip(srange(new_x, self.grid.width), item):
01161 for j, item_j in zip(srange(new_y, self.grid.height), item_i):
01162 for k, item_k in zip(srange(new_z, self.grid.depth), item_j):
01163 self.grid[i, j, k] = item_k
01164
01165
01166 class Grid3D (Container3D, PrincipleContainer):
01167 def __init__(self, dims, initial_item = None):
01168 (width, height, depth) = dims
01169 Container3D.__init__(self, width, height, depth)
01170 self.grid = make_grid_3d(width, height, depth, initial_item)
01171
01172 def __getitem__(self, p):
01173 if isinstance(p, int):
01174 return self[p, ..., ...]
01175 x, y, z = p
01176 if type(x) is int:
01177 if type(y) is int:
01178 if type(z) is int:
01179 return self.grid[x][y][z]
01180 elif is_slice(z):
01181 return GridBar3D(self, x, y, z)
01182 elif is_slice(y):
01183 if type(z) is int:
01184 return GridCol3D(self, x, y, z)
01185 elif is_slice(z):
01186 return GridSliceYZ(self, x, y, z)
01187 elif is_slice(x):
01188 if type(y) is int:
01189 if type(z) is int:
01190 return GridRow3D(self, x, y, z)
01191 elif is_slice(z):
01192 return GridSliceXZ(self, x, y, z)
01193 elif is_slice(y):
01194 if type(z) is int:
01195 return GridSliceXY(self, x, y, z)
01196 elif is_slice(z):
01197 return GridWindow3D(self, x, y, z)
01198
01199 raise TypeError
01200
01201 def __setitem__(self, p, item):
01202 (x, y, z) = p
01203 if type(x) is int:
01204 if type(y) is int:
01205 if type(z) is int:
01206 self.grid[x][y][z] = item
01207 elif is_slice(z):
01208 g = GridBar3D(self, x, y, z)
01209 g[...] = item
01210 elif is_slice(y):
01211 if type(z) is int:
01212 g = GridCol3D(self, x, y, z)
01213 g[...] = item
01214 elif is_slice(z):
01215 g = GridSliceYZ(self, x, y, z)
01216 g[..., ...] = item
01217 elif is_slice(x):
01218 if type(y) is int:
01219 if type(z) is int:
01220 g = GridRow3D(self, x, y, z)
01221 g[...] = item
01222 elif is_slice(z):
01223 g = GridSliceXZ(self, x, y, z)
01224 g[..., ...] = item
01225 elif is_slice(y):
01226 if type(z) is int:
01227 g = GridSliceXY(self, x, y, z)
01228 g[..., ...] = item
01229 elif is_slice(z):
01230 g = GridWindow3D(self, x, y, z)
01231 g[..., ..., ...] = item
01232 else:
01233 raise TypeError
01234
01235 class ListGrid3D (Grid3D):
01236 def __init__(self, dims):
01237 (width, height, depth) = dims
01238 Grid3D.__init__(self, (width, height, depth))
01239
01240 for index in self.index_iter():
01241 self[index] = []
01242
01243
01244
01245
01246 def additem(self, p, b):
01247 (x, y, z) = p
01248 self[x, y, z].append(b)
01249
01250 class ListGrid2D (Grid2D):
01251 def __init__(self, dims):
01252 (width, height) = dims
01253 Grid2D.__init__(self, (width, height))
01254
01255 for index in self.index_iter():
01256 self[index] = []
01257
01258
01259
01260
01261 def additem(self, p, b):
01262 (x, y) = p
01263 self[x, y].append(b)
01264