Created
March 21, 2013 15:04
-
-
Save david0/5213735 to your computer and use it in GitHub Desktop.
Converts matrices from Texas Instruments Calculators (TI89, TI Voyage 200) to CSV.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# Reads matricies files build by the TI Voyage 200/TI82+ (*.v2m-files) | |
# and outputs csv | |
# | |
# Example: | |
# $ ./timatrix2csv.py main.test.v2p > test.csv | |
from struct import pack, unpack, calcsize | |
from collections import namedtuple | |
from sys import argv, stdout | |
from pprint import pprint | |
from csv import writer | |
def main(): | |
if(len(argv) < 2): | |
print("USAGE: %s [infile] [outfile.csv]" % argv[0]) | |
exit(-1) | |
filename = argv[1] | |
if len(argv) > 2: | |
outfile = open(argv[2]) | |
else: | |
outfile = stdout | |
with open(filename,"rb") as fp: | |
reader = TIMatrixReader(fp) | |
print("Converting %s/%s..." % (reader.folder, reader.name)) | |
csv = writer(stdout, delimiter='\t') | |
csv.writerows(reader.matrix) | |
class InvalidHeaderException(Exception): | |
pass | |
class InvalidMatrixException(Exception): | |
pass | |
class TIMatrixReader(object): | |
def __init__(self, fp): | |
self.fp = fp | |
self.stack = [] | |
self.matrix = None | |
self._readHeader() | |
self._readInstructions() | |
self._buildMatrix() | |
@property | |
def name(self): | |
return self.header.name.decode() | |
@property | |
def folder(self): | |
return self.header.folder.decode() | |
def _readHeader(self): | |
header_fmt = ">8s2s8s40s2s4s8s1s3s4s4sI" | |
Header = namedtuple("Header", "signature sep1 folder description sep2 sep3 name linkType sep4 size sep5 instCount") | |
data = self.fp.read(calcsize(header_fmt)) | |
self.header = Header._make(unpack(header_fmt, data)) | |
if self.header.signature!=b'**TI92P*': | |
print("Wrong header: %s" % self.header.format) | |
raise InvalidHeaderException() | |
def _readInstructions(self): | |
numInst=self.header.instCount | |
while numInst > 0: | |
c=self.fp.read(1)[0] | |
self.stack += [c] | |
numInst -= 1 | |
def _buildMatrix(self): | |
END_TAG = 0xE5 | |
POSINT_TAG = 0x1F | |
NEGINT_TAG = 0x20 | |
LIST_TAG = 0xD9 | |
if self.stack.pop() != LIST_TAG: | |
raise InvalidMatrixException() | |
self.matrix = [] | |
while len(self.stack) > 0: | |
tag = self.stack.pop() | |
if tag == LIST_TAG: | |
self.matrix.append([]) | |
elif tag == END_TAG: | |
pass #FIXME: what to do? | |
elif tag == POSINT_TAG: | |
s = self.stack.pop() | |
if s!=0: | |
s = self.stack.pop() | |
self.matrix[-1].append(s) | |
elif tag == NEGINT_TAG: # TODO: test this! | |
s = self.stack.pop() | |
if s!=0: | |
s = self.stack.pop() | |
self.matrix[-1].append(-1*s) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment