importing arrays from a file

hi everyone,

i have a script that exports an array to a file kinda like this:

[[‘NOF’, 0, 0, 0, [], [], []], [60, 1, 3, 6], [62, 9, 11, 13], [64, 13, 14, 21], [‘NOF’]]

using this bit of script:

def save(self,savefile):
  global startstop
  global fname
  print("saving as:")
  print(savefile)
     try:
       f = open(savefile,'w')
       print ("file open")
     except:
       print("unable to save file.")
     try:
       self.writeln(f,self.startstop)
       print("file saved")
       print self.startstop
       f.close()
       print ("file closed")
     except:
       print("cannot save")

def writeln(self,f,x):
  f.write(str(x))
  f.write("
")

and it works fine, but when i try to import the array using this code:

def load(self,loadfile):
  f = open(str(loadfile),'r')
  self.startstop = f.readline()

but it says that the value is out of range.

any sergestions of a better way of importing and exporting the array?

thanks, levon

Heyho levon!

Although I don’t see the complete error message and the line where the message appears, I would say that you have to convert self.startstop in load() from a string to the vector you need using string.split() and int() or float() (and maybe some other functions, e.g. list()). The reason for this is that readline() returns a string and you need a list.

Oh, and some advices:

  • You don’t need brackets in print statements
  • Why are there global statements in save()?

Addendum (Sorry for the shameless postcount increasing :expressionless: ):

If you only want to access this file from within python you can try the pickle or cpickle module (BUT I dunno if this works inside blender!):


import pickle

.... # your class definitin/methods/members left out, cause I don't know what else you're doing ;-)

    def save(self, filename):
        file = open(filename, 'w')
        pickle.dump(self.startstop, file)
        file.close()

    def load(self, filename):
        file = open(filename, 'r')
        self.startstop = pickle.load(file)
        file.close()

If you need a more complex saving method, you can even look at the shelve module.

HTH

pickle and cPickle works perfectly inside Blender.

Martin

Thanks, i knew i had to do something like that, but im only new to python and self taught so i dont know much of the python modules, so im learning how to use the split() function now.

Someone sergested that i use pickle, but im making it for the blended midi project and at the moment im trying to keep it so you dont need python to run it.

ok, ive worked out a way of importing and export the string using this code:


# import nothing, trust no one
PATH = './test-serial'
DATA = [['NOF',0,0,0,[],[],[],[60,1,2,3],[61,1,2,3],'NOF']]
def Swrite(data,path):
	file = open(path,'w')
	file.write(str(data))
def Sread(path):
	file = open(path,'r')
	lines = file.read()
	output = []
	return recParse(lines)[0]
def parseString(data):
	output = ''
	for i in range(0,len(data)):
		if data[i] == "'":
			return (i +2,output)
		else:
			output = output + data[i]
	raise "Bad error"
			
def parseNum(data):
	output = ''
	for i in range(0,len(data)):
		if data[i] == ",":
			return (i,int(output))
		elif data[i] == ']':
			return (i,int(output))
		else:
			output = output + data[i]
	raise "Bad error"
def recParse(lines):
	output = []
	i = 0
	#for i in range(0,len(lines):
	while i != len(lines):
		if lines[i] == '[':
			l,data = recParse(lines[i+1:]) # if we use 'i', we are in truoble with infinite recursion
			i = i + l -1
			output.append(data)
		elif lines[i] == ']': # finished this list
			return (i+2,output) 
		elif lines[i] == "'": #we have a string
			l,data = parseString(lines[i+1:])
			i = i + l -1
			output.append(data)
		elif lines[i] == ',':
			pass
		elif lines[i] == ' ':
			pass
		#elif i in ['1','2','3','4','5','6','7','8','9',0] : # its a number
		else:
			l,data = parseNum(lines[i:])
			i = i + l -1
			output.append(data)
		i = i + 1
	return output

but when i import it, it says value out of range, when i try to assign the list i import the the one in the script,
any idea why this happens?

Can you please post the complete error message, it is a lot easier to find the error when you know the line where it happens. :wink: (I am sooo lazy)

after fucking around with it, its now saying "AttributeError: ‘list’ object has no attribute ‘val’ " on the line

self.startstop.val = varsread

Is the length of the sublists constant (e.g. the first element [‘NOF’, 0, 0, 0, [], [], []] is always a string, 3 integers and 3 lists) or do you have to handle variable sublists? If it is always constant, you should try string.split() . I recommend you to read the documentation for the string module, it is very helpful. Or as I said before, use pickle.

And pleasepleaseplease post the complete error messages, like:

Traceback (most recent call last):
  File "levon.py", line 71, in ?
    print Sread(sys.argv[1])
  File "levon.py", line 17, in Sread
    return recParse(lines)[0]
  File "levon.py", line 46, in recParse
    l, data = recParse(lines[i+1:]) # if we use 'i', we are in truoble with infinite recursion
  File "levon.py", line 46, in recParse
    l, data = recParse(lines[i+1:]) # if we use 'i', we are in truoble with infinite recursion
  File "levon.py", line 53, in recParse
    l, data = parseString(lines[i+1:])
TypeError: unpack non-sequence

May help…

# import nothing, trust no one
PATH = 'g:/tmp/'
DATA = [['NOF',0,0,0,[],[],[],[60,1,2,3],[61,1,2,3],'NOF']]

def writeln(file,data):
    file.write(str(data)+'
')
    
def readAll(file):
    linesarray=file.readlines()
    return linesarray

def create_AnArrayOfArrays(linesarray):
    new_array=[]
    for l in linesarray:
        exec "new_array.append(%s)" % l[:-1]
    return new_array    
    
file=open(PATH+'test.tst','w')
writeln(file,DATA)
writeln(file,DATA)
writeln(file,DATA)
file.close()

file=open(PATH+'test.tst','r')
LINEARRAYS=readAll(file)
NEW_ARRAY=create_AnArrayOfArrays(LINEARRAYS)
print NEW_ARRAY 
for n in NEW_ARRAY:
   for t in n:
       for c in t:
           print c