import numpy as np
class sheet_info(object):
CORNER=0
MEASURE=1
CORNER_STRING='c'
MEASURE_STRING='m'
NAME={}
NAME[MEASURE]='measure'
NAME[CORNER]='corner'
HORIZONTAL_TABLE_SHIFT=0
VERTICAL_TABLE_SHIFT=1
HORIZONTAL_PLOT_SHIFT=0
VERTICAL_PLOT_SHIFT=1
HORIZONTAL_DATA_SHIFT=0
VERTICAL_DATA_SHIFT=1
def __init__(self,name=None,e=None):
self.e=e
self.start_col=1
self.start_row=1
self.current_col=1
self.current_row=1
self.sheet_name=name
self.header=[] # List of tuples (col_num,col_name)
self.header_dict={}
self.header_dict[self.CORNER]={}
self.header_dict[self.MEASURE]={}
self.var_dict={}
self.plots=[]
self.plot_info={'maxx':0,'maxy':0}
self.transpose=False
self.header_set=False
self.first_data_row=None
self.last_data_row=None
self.last_corner_col=None
self.first_data_col_name='Pass/Fail'
self.table_shift_type=self.HORIZONTAL_TABLE_SHIFT
self.max_col=0
self.max_row=0
self.header_row=None
self.first_generated_col=None
self.last_generated_col=None
self.data_blocks={}
#************************************************************************
#**************************** Chart section *****************************
#************************************************************************
def add_chart(self,left, width, top, height,shift=None):
if shift==None:
shift=self.HORIZONTAL_PLOT_SHIFT
assert shift in [self.HORIZONTAL_PLOT_SHIFT,self.VERTICAL_PLOT_SHIFT]
if shift==self.HORIZONTAL_PLOT_SHIFT:
left=self.plot_info['maxx']+left
else:
top=self.plot_info['maxy']+top
self.plot_info['maxx']=max(self.plot_info['maxx'],left+width)
self.plot_info['maxy']=max(self.plot_info['maxy'],top+height)
chart_info={'left':left, 'width':width, 'top':top, 'height':height}
self.plots.append(chart_info)
return left, width, top, height
#************************************************************************
#**************************** Data manipulation section *****************
#************************************************************************
def load_data_from_sheet(self,function):
#function(sheet,row1, col1,row2, col2)
assert not hasattr(self,'data')
row1=self.get_first_data_row()
col1=self.get_first_data_col()
row2=self.get_last_data_row()
col2=self.get_last_data_col()
self.data=function(self.sheet_name,row1, col1,row2, col2)#Return numpy array
#print "Data loaded for sheet %s"%(self.sheet_name)
def delete_sheet_data(self):
assert hasattr(self,'data')
del self.data
def add_data_row(self,row_data):
if not hasattr(self,'data'):
self.data=[]
self.data.append(row_data)
def set_data_block(self,data,function):
#data is dictionary where keys is: data,data_type,name
assert 'data' in data
if 'data_type' not in data:
data_type='value'
else:
assert data['data_type'] in ['value','formula','array_formula']
data_type=data['data_type']
data_values=data['data']
numofcols=len(data_values[0])
numofrows=len(data_values)
# if shift_type==None or shift_type==self.HORIZONTAL_DATA_SHIFT:
# self.right_shift_for_data_block()
# else:#Vertical shift we need to move
# self.down_shift_for_data_block()
col1=self.get_current_col()
row1=self.get_current_row()
col2=col1+numofcols-1
row2=row1+numofrows-1
if 'name' in data:
self.add_data_block_info(data['name'],row1, col1,row2, col2)
function(self.sheet_name,row1, col1,row2, col2,data_values,data_type)
self.set_current_location(row=row2,col=col2)
return (row1, col1,row2, col2)
def add_data_block_info(self,name,row1, col1,row2, col2):
assert name not in self.data_blocks
self.data_blocks[name]={'row1':row1, 'col1':col1,'row2':row2, 'col2':col2}
#************** is section **************
def is_sheet_has_passfail_column(self):
return self.first_data_col_name in self.get_column_names()
def is_header_set(self):
return self.header_set
def is_col_name_in_header(self,val,type):
assert isinstance(val, str)
return val in self.header_dict[type]
def is_horizontal_table_shift(self):
return self.table_shift_type==self.HORIZONTAL_TABLE_SHIFT
def is_vertical_table_shift(self):
return self.table_shift_type==self.VERTICAL_TABLE_SHIFT
def is_var_exists(self,var_name):
assert isinstance(var_name, str)
return var_name in self.var_dict
#*********************************************************************
#**************************** Get section ****************************
#*********************************************************************
def get_sheet_data_block_names(self):
return self.data_blocks.keys()
def get_column_range(self,name,type):
assert isinstance(name, str)
col_num=self.get_col_num_by_name(name,type)
first_row=self.get_first_data_row()
last_row=self.get_last_data_row()
return {'col':col_num,'first_row':first_row,'last_row':last_row}
def get_generated_col(self):
return {'first':self.first_generated_col,'last':self.last_generated_col}
def get_passfail_string(self):
return self.first_data_col_name
def get_cell_value(self,sheet,row,col):
assert hasattr(self,'data')
col_index=col-self.get_first_data_col()
row_index=row-self.get_first_data_row()
return self.data[row_index][col_index]
def get_row_values_from_memory(self,sheet,row):
assert hasattr(self,'data')
row_index=row-self.get_first_data_row()
return self.data[row_index]
def get_first_data_col(self):
return min(self.get_data_col_iterator())
def get_last_data_col(self):
return max(self.get_data_col_iterator())
def get_type_from_string(self,val):
assert isinstance(val, str)
if val.lower()==self.CORNER_STRING:
return self.CORNER
elif val.lower()==self.MEASURE_STRING:
return self.MEASURE
else:
return None
def get_col_num_by_name(self,name,type):
assert self.is_header_set()
assert isinstance(name, str)
assert type in [self.MEASURE,self.CORNER]
assert type in self.header_dict
if name not in self.header_dict[type]:
print self.header_dict[type]
self.e.print_error("Column name '%s' not found in '%s' section of header in sheet '%s'"%(name,self.NAME[type],self.sheet_name))
#print self.header_dict
return self.header_dict[type][name]
def get_corner_type(self):
return self.CORNER
def get_corner_string(self):
return self.CORNER_STRING
def get_measure_type(self):
return self.MEASURE
def get_measure_string(self):
return self.MEASURE_STRING
def get_corner_column_names(self):
assert self.is_header_set()
result=[]
for num,name in self.header:
if name in self.header_dict[self.get_corner_type()]:
result.append(name)
return result
def get_measure_column_names(self):
assert self.is_header_set()
result=[]
for num,name in self.header:
if name in self.header_dict[self.get_measure_type()]:
result.append(name)
return result
def get_first_data_row(self):
return self.first_data_row
def get_last_data_row(self):
return self.last_data_row
def get_data_line_iterator(self):
return range(self.first_data_row,self.last_data_row+1)
def get_data_col_iterator(self):
assert self.is_header_set()
return self.data_col_iterator
def get_measures_col_iterator(self):
assert self.is_header_set()
return sorted(self.header_dict[self.get_measure_type()].values())
def get_header(self):
assert self.is_header_set()
return self.header
def get_column_names(self):
assert self.is_header_set()
return [item[1] for item in self.header]
def get_start_col(self):
return self.start_col
def get_start_row(self):
return self.start_row
def get_current_col(self):
return self.current_col
def get_current_row(self):
return self.current_row
def get_transpose_mode(self):
return self.transpose
def get_max_col(self):
return self.max_col
def get_max_row(self):
return self.max_row
def get_first_measure_column(self):
assert self.is_header_set()
return min(self.get_measures_col_iterator())
def get_last_measure_column(self):
assert self.is_header_set()
return max(self.get_measures_col_iterator())
def get_header_row(self):
assert self.is_header_set()
return self.header_row
def get_var_info(self,varname):
assert isinstance(varname, str)
assert varname in self.var_dict
return self.var_dict[varname]
def get_num_of_corner_cols(self):
return len(self.header_dict[self.CORNER])
#************************************************************************
#**************************** Set section *******************************
#************************************************************************
def set_generated_col(self,first,last):
self.first_generated_col=self.start_col+first
self.last_generated_col=self.start_col+last
def set_header_row(self):
self.header_row=self.get_current_row()
def add_var_info(self,var_name,multiplyer):
assert isinstance(var_name, str)
if multiplyer!='':
assert isinstance(multiplyer, (int,float))
assert var_name not in self.var_dict
self.var_dict[var_name]={}
self.var_dict[var_name]['mult']=multiplyer
def set_var_selector_location(self,var_name,row,col):
assert isinstance(var_name, str)
assert var_name in self.var_dict
self.check_row_col(row,col)
self.var_dict[var_name]['row']=row
self.var_dict[var_name]['col']=col
def set_first_data_row(self,num):
assert isinstance(num, int)
assert num >0
assert self.is_header_set()
assert num >= self.start_row
self.first_data_row=num
self.set_max_row(num)
def set_last_data_row(self,num):
assert isinstance(num, int)
assert num >0
assert self.is_header_set()
assert num >= self.start_row
self.last_data_row=num
self.set_max_row(num)
def set_first_data_row_to_current(self):
if not self.transpose:
self.set_first_data_row(self.get_current_row())
else:
self.set_first_data_row(self.get_current_col())
def set_last_data_row_to_current(self,diff):
assert isinstance(diff, int)
if not self.transpose:
self.set_last_data_row(self.get_current_row()+diff)
else:
self.set_last_data_row(self.get_current_col()+diff)
def set_transpose_mode(self):
assert len(self.header)==0
#Mode can't be changed after header added
self.transpose=True
def set_start_col(self,val):
assert val>0
assert isinstance(val, int)
self.start_col=val
def set_start_row(self,val):
assert val>0
assert isinstance(val, int)
self.start_row=val
def set_current_col(self,val):
assert val>0
assert isinstance(val, int)
assert val >= self.start_col
self.current_col=val
self.set_max_col(val)
def set_max_col(self,col):
assert col>0
assert isinstance(col, int)
self.max_col=max(self.max_col,col)
def set_current_row(self,val):
assert val>0
assert isinstance(val, int)
assert val >= self.start_row
self.current_row=val
self.set_max_row(val)
def set_max_row(self,row):
assert row>0
assert isinstance(row, int)
self.max_row=max(self.max_row,row)
def set_current_location(self,row,col):
self.check_row_col(row,col)
self.set_current_row(row)
self.set_current_col(col)
def set_start_location(self,row,col):
self.check_row_col(row,col)
self.set_start_row(row)
self.set_start_col(col)
#************************************************************************
#**************************** Sheet header section **********************
#************************************************************************
def close_header(self,numoflast_corner_col=None):
assert len(self.header)>0
if self.last_corner_col==None and numoflast_corner_col==None:
raise Exception("last_corner_col not defined")
if numoflast_corner_col!=None:
if self.last_corner_col!=None:
print "numoflast_corner_col=%d,last_corner_col=%d"%(numoflast_corner_col,self.last_corner_col)
raise Exception("Can't redefine last_corner_col in sheet %s"%(self.sheet_name))
else:
self.last_corner_col=numoflast_corner_col
data_section=False
for (col_num,col_name) in sorted(self.header):
if col_num>self.last_corner_col:
if col_name in self.header_dict[self.MEASURE]:
return False #Duplication of column name
else:
self.header_dict[self.MEASURE][col_name]=col_num
else:
if col_name in self.header_dict[self.CORNER]:
return False #Duplication of column name
else:
self.header_dict[self.CORNER][col_name]=col_num
self.header_set=True
self.data_col_iterator=[item[0] for item in self.header]
return True
def add_header_col(self,name):
assert isinstance(name, str)
assert not self.is_header_set()
if not self.transpose:
location=self.get_current_col()
else:
location=self.get_current_row()
(row,col)=self.get_current_row(),self.get_current_col()
if self.first_data_col_name.lower()==name.lower():
if not self.transpose:
self.last_corner_col=col-1
else:
self.last_corner_col=row-1
value=tuple([location,name])
self.header.append(value)
return (row,col)
def compare_header(self,header):
assert self.is_header_set()
return header==[item[1] for item in self.header]
#************** Pointer movment **************
def next_cell(self):
if not self.transpose:
self.set_current_col(self.get_current_col()+1)
else:
self.set_current_row(self.get_current_row()+1)
def next_line(self):
if not self.transpose:
self.set_current_row(self.get_current_row()+1)
self.set_current_col(self.get_start_col())
else:
self.set_current_col(self.get_current_col()+1)
self.set_current_row(self.get_start_row())
def next_col(self):
if not self.transpose:
self.set_current_col(self.get_current_col()+1)
self.set_current_row(self.get_start_row())
else:
self.set_current_row(self.get_current_row()+1)
self.set_current_col(self.get_start_col())
def set_next_table(self):
if self.is_horizontal_table_shift():
self.set_start_col(self.get_max_col()+1)
self.set_current_col(self.get_start_col())
self.set_current_row(self.get_start_row())
else:
self.set_start_row(self.get_max_row()+1)
self.set_current_row(self.get_start_row())
self.set_current_col(self.get_start_col())
def right_shift_for_data_block(self):
row=self.get_start_row()
col=self.get_current_col()+1
self.set_current_location(row=row,col=col)
def down_shift_for_data_block(self):
row=self.get_max_row()+1
self.set_start_row(row)
col=self.get_start_col()
self.set_current_location(row=row,col=col)
#***************** Check section #*****************
def check_row_col(self,row,col):
assert row>0
assert col>0
assert isinstance(row, int)
assert isinstance(col, int)