151 lines
4.7 KiB
Python
151 lines
4.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Narzędzie do tworzenia plików .mar
|
|
"""
|
|
|
|
import struct
|
|
import sys
|
|
|
|
|
|
class MultiArrayWriter:
|
|
def __init__(self, dimensions):
|
|
"""
|
|
dimensions: list of ints, np. [3, 4, 2] dla tablicy [3][4][2]
|
|
"""
|
|
self.dimensions = dimensions
|
|
self.total_elements = 1
|
|
for dim in dimensions:
|
|
self.total_elements *= dim
|
|
self.data = {} # sparse: flat_index -> (type, value)
|
|
|
|
def write_int(self, f, value):
|
|
f.write(struct.pack('<i', value))
|
|
|
|
def write_double(self, f, value):
|
|
f.write(struct.pack('<i', int(value * 10000)))
|
|
|
|
def write_bool(self, f, value):
|
|
f.write(struct.pack('<?', value))
|
|
|
|
def write_string(self, f, value):
|
|
data = value.encode('utf-8')
|
|
self.write_int(f, len(data))
|
|
f.write(data)
|
|
|
|
def write_variable(self, f, var_type, value):
|
|
"""type: 1=int, 2=string, 3=bool, 4=double"""
|
|
self.write_int(f, var_type)
|
|
|
|
if var_type == 1:
|
|
self.write_int(f, value)
|
|
elif var_type == 2:
|
|
self.write_string(f, value)
|
|
elif var_type == 3:
|
|
self.write_bool(f, value)
|
|
elif var_type == 4:
|
|
self.write_double(f, value)
|
|
|
|
def indices_to_flat(self, indices):
|
|
"""Konwertuje [x][y][z] na flat index"""
|
|
flat = 0
|
|
multiplier = 1
|
|
|
|
for i in range(len(self.dimensions) - 1, -1, -1):
|
|
flat += indices[i] * multiplier
|
|
multiplier *= self.dimensions[i]
|
|
|
|
return flat
|
|
|
|
def set(self, indices, var_type, value):
|
|
"""
|
|
Ustawia wartość pod wielowymiarowymi indeksami
|
|
|
|
indices: list of ints, np. [1, 2, 0]
|
|
var_type: 1=int, 2=string, 3=bool, 4=double
|
|
value: wartość
|
|
"""
|
|
if len(indices) != len(self.dimensions):
|
|
raise ValueError(f"Wrong number of indices: got {len(indices)}, expected {len(self.dimensions)}")
|
|
|
|
for i, idx in enumerate(indices):
|
|
if idx < 0 or idx >= self.dimensions[i]:
|
|
raise ValueError(f"Index {i} out of bounds: {idx} (max: {self.dimensions[i]-1})")
|
|
|
|
flat_index = self.indices_to_flat(indices)
|
|
self.data[flat_index] = (var_type, value)
|
|
|
|
def set_int(self, indices, value):
|
|
self.set(indices, 1, value)
|
|
|
|
def set_string(self, indices, value):
|
|
self.set(indices, 2, value)
|
|
|
|
def set_bool(self, indices, value):
|
|
self.set(indices, 3, value)
|
|
|
|
def set_double(self, indices, value):
|
|
self.set(indices, 4, value)
|
|
|
|
def save(self, filepath):
|
|
"""Zapisuje do pliku .mar"""
|
|
with open(filepath, 'wb') as f:
|
|
# Liczba wymiarów
|
|
self.write_int(f, len(self.dimensions))
|
|
|
|
# Rozmiary wymiarów
|
|
for dim in self.dimensions:
|
|
self.write_int(f, dim)
|
|
|
|
# Zapisz elementy (posortowane po indeksie)
|
|
for flat_index in sorted(self.data.keys()):
|
|
var_type, value = self.data[flat_index]
|
|
self.write_int(f, flat_index)
|
|
self.write_variable(f, var_type, value)
|
|
|
|
print(f"Saved to {filepath}")
|
|
print(f" Dimensions: {self.dimensions}")
|
|
print(f" Total slots: {self.total_elements}")
|
|
print(f" Filled slots: {len(self.data)}")
|
|
print(f" Fill rate: {100*len(self.data)/self.total_elements:.1f}%")
|
|
|
|
|
|
def example_usage():
|
|
"""Przykład użycia"""
|
|
# Stwórz tablicę 2D [5][3]
|
|
mar = MultiArrayWriter([5, 3])
|
|
|
|
# Wypełnij danymi
|
|
mar.set_string([0, 0], "Reksio")
|
|
mar.set_int([0, 1], 123)
|
|
mar.set_double([1, 2], 3.14159)
|
|
mar.set_bool([2, 0], True)
|
|
mar.set_string([4, 2], "Koniec!")
|
|
|
|
# Zapisz
|
|
mar.save('/tmp/example.mar')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
if len(sys.argv) > 1 and sys.argv[1] == '--example':
|
|
example_usage()
|
|
else:
|
|
print("MultiArray Writer - narzędzie do tworzenia plików .mar")
|
|
print()
|
|
print("Użycie w kodzie:")
|
|
print()
|
|
print(" from mar_writer import MultiArrayWriter")
|
|
print()
|
|
print(" # Stwórz tablicę [3][4][2]")
|
|
print(" mar = MultiArrayWriter([3, 4, 2])")
|
|
print()
|
|
print(" # Ustaw wartości")
|
|
print(" mar.set_string([0, 0, 0], 'Hello')")
|
|
print(" mar.set_int([1, 2, 1], 42)")
|
|
print(" mar.set_double([2, 3, 0], 3.14)")
|
|
print(" mar.set_bool([0, 1, 1], True)")
|
|
print()
|
|
print(" # Zapisz")
|
|
print(" mar.save('output.mar')")
|
|
print()
|
|
print("Uruchom z --example aby stworzyć przykładowy plik")
|