class Sheet(object): def __init__(self): self.rows = 3 self.cols = 5 self.matrix = Matrix(3, 5) # fill the sheet with zero numbercells for row in range(self.rows): for col in range(self.cols): self.updateValue(row, col, "0") def updateValue(self, row, col, newValue): if newValue.isdigit(): cellObject = NumberCell(newValue) else: cellObject = FormulaCell(newValue, self) self.matrix.setElementAt(row, col, cellObject) # self.checkAllDependenciesForUpdates() def __str__(self): return self.matrix.__str__()
class Sheet(object): def __init__(self,rows,cols): self.rows = rows self.cols = cols self.matrix = Matrix(rows, cols) # fill the sheet with zero numbercells for row in range(self.rows): for col in range(self.cols): self.modifyValue(row, col, "0") def modifyValue(self, row, col, newValue): if newValue.isdigit(): cellObject = NumberCell(newValue) else: cellObject = FormulaCell(newValue, self) self.matrix.setElementAt(row, col, cellObject) # self.checkAllDependenciesForUpdates() # get values of cells in range def get_range(self, cellRange): result = [] range = self.expand_range(cellRange) for n in range: result.append(self.lookup(n)) return result # get cells name in range def get_range_cells(self,cellRange): return self.expand_range(cellRange) # convert implicit into explicit range def expand_range(self,input): p = re.compile(Constants.REGEX_RANGE) matches = p.finditer(input) result = [] # list of components prev = 0 for match in matches: result.append(input[prev:match.start()]) result = rangeToListConverter(input[match.start():match.end()]) return result # A => 0 def colNameToInt(self, name): # invert oder of letters (lowest count first) name = name[::-1] result = 0 # loop over all letters for i in range(len(name)): # convert the letter to its value, make 1 the first value num = (ord(name[i]) - 65) + 1 # add the number multiplied by its weight result += num * 26 ** i return result - 1 # lookup the value of a given cell. # x = A1, B22, AB33 ... def lookup(self, x): p = re.compile('[A-Z]+') matches = p.match(x) to = matches.end() letters = x[:to] digits = x[to:] row = int(digits) - 1 # for 0 based matrix index col = self.colNameToInt(letters) cell = self.matrix.getElementAt(row, col) return cell.value def lookupCell(self, x): p = re.compile('[A-Z]+') matches = p.match(x) to = matches.end() letters = x[:to] digits = x[to:] row = int(digits) - 1 # for 0 based matrix index col = self.colNameToInt(letters) cell = self.matrix.getElementAt(row, col) return cell ''' Creates some new cells at the bottom, with some basic statistical analysis. Assumptions - Comments: 1. Every set of data is organised column by column. For example, in a sheet with temperatures for some days, every day has a column of temperatures. We also assume some symmetry: Same number of rows for each column 2. The parameter final_row tells us manually where to start the analysis. It indicates the final row used for data, but it can be anything 3. New function in at the top to import data from csv file (csv_to_sheet). Accompanied with ff.csv file in the directory 4. all the following could be done under the same for-loop because it is ALMOST EXACTLY the same code. I let them in separate loops for presentation clarity ### LINES in the analysis sub-sheet ### 1. mean 2. std.deviation 3. median 4. variance 5. max 6. sum 7. count _____________ (from -statistics- library) ''' def statistical_analysis(self, final_row): rows_of_hs = self.rows cols_of_hs = self.cols start_row = final_row + 1 # leave a blank line between the analysis and the Data # 1-MEANS for col in range(0, cols_of_hs): letter_col = int_to_letter(col) s = '=mean(' + letter_col + '1:' + letter_col + str(final_row) + ')' self.modifyValue(start_row, col, s) start_row += 1 # 2-STANDARD DEVIATIONS for col in range(0, cols_of_hs): letter_col = int_to_letter(col) s = '=stdev(' + letter_col + '1:' + letter_col + str(final_row) + ')' self.modifyValue(start_row, col, s) start_row += 1 # 3-MEDIANS for col in range(0, cols_of_hs): letter_col = int_to_letter(col) s = '=median(' + letter_col + '1:' + letter_col + str(final_row) + ')' self.modifyValue(start_row, col, s) start_row += 1 # 4-Variance for col in range(0, cols_of_hs): letter_col = int_to_letter(col) s = '=variance(' + letter_col + '1:' + letter_col + str(final_row) + ')' self.modifyValue(start_row, col, s) start_row += 1 # 5-maximum for col in range(0, cols_of_hs): letter_col = int_to_letter(col) s = '=max(' + letter_col + '1:' + letter_col + str(final_row) + ')' self.modifyValue(start_row, col, s) start_row += 1 # 6-sum for col in range(0, cols_of_hs): letter_col = int_to_letter(col) s = '=sum(' + letter_col + '1:' + letter_col + str(final_row) + ')' self.modifyValue(start_row, col, s) start_row += 1 # 7-count for col in range(0, cols_of_hs): letter_col = int_to_letter(col) s = '=len(' + letter_col + '1:' + letter_col + str(final_row) + ')' self.modifyValue(start_row, col, s) ''' Histograms of frequencies and cumulative frequencies on demand. ''' def histogramPlot(self, the_column, final_row, type='frequency'): col = colNameToInt(the_column) l = [] for row in range(final_row): l.append(self.matrix.getElementAt(row, col).value) if type == 'frequency': plt.hist(l) plt.title('Frequency histogram') plt.ylabel('Frequency') elif type == 'cumulative': bins = np.arange(np.floor(min(l)), np.ceil(max(l))) # for cumulative to 1 plt.hist(l, bins=bins, cumulative=True, density=1) # statistical parameters plt.title('% CumulativeFrequency histogram') plt.ylabel('% Cumulative Frequency') else: raise ValueError( 'Student Generated Error: No type \'' + type + '\' exists. Choose between \'cumulative\' and \'frequency\'.') # plt.legend(loc='right') plt.grid(True) plt.xlabel('Number Of Games') plt.show() def __str__(self): return self.matrix.__str__()
class Sheet(object): def __init__(self, nRows, nCols): self.rows = nRows self.cols = nCols self.matrix = Matrix(nRows, nCols) # fill the sheet with zero numbercells for row in range(self.rows): for col in range(self.cols): self.updateValue(row, col, "0") def __str__(self): return self.matrix.__str__() def updateValue(self, row, col, newValue): if newValue.isdigit(): cellObject = NumberCell(newValue) elif newValue[0] != int: # for string values to be accepted cellObject = alphaCell(newValue) else: cellObject = FormulaCell(newValue, self) self.matrix.setElementAt(row, col, cellObject) def cellUpdate (self, cell, newValue): colNumber = FormulaCell.colNameToInt(self,"".join(re.findall("[A-Z]", cell))) rowNumber =int( "".join(re.findall("[0-9]", cell)))-1 Sheet.updateValue(self, rowNumber, colNumber, newValue) def lookup(self, x): p = re.compile('[A-Z]+') matches = p.match(x) to = matches.end() letters = x[:to] digits = x[to:] row = int(digits) - 1 # for 0 based matrix index col = FormulaCell.colNameToInt(self, letters) cell = self.matrix.getElementAt(row,col) return cell.value # def printTable(self): # field_head = [] # for i in range(self.cols): # field_head.append(FormulaCell.colIntToName(self, i)) # result = PrettyTable(field_head) # # for rows in range(self.rows): # list = [] # for cols in range(self.cols): # list.append(self.matrix.data[rows][cols].value) # result.add_row(list) # print((str(result) + '\n')) ####################### functionalities for spreadsheet ############################### #Resetting all the values of the spreadsheet : def resetvalue(self,value): for row in range(self.rows): for col in range(self.cols): self.updateValue(row, col, value) #Difference between two spreadsheet: def matrixDifference(self,sheet2): for row in range(self.rows): for col in range(self.cols): if self.cols == sheet2.cols and self.rows == sheet2.rows: self.matrix.data[row][col].value -= sheet2.matrix.data[row][col].value else: print ("Matrices are incompatible, therefore cannot be subtracted" ) # Mathematical functions of excel executed on the values of the spreadsheet : #(squareroot of values which are rounded off ) def matrixsqrt(self,sheet1): for row in range(self.rows): for col in range(self.cols): self.matrix.data[row][col].value = math.ceil(math.sqrt (sheet1.matrix.data[row][col].value )) #Transposing one sheet (changing the values from rows to columns): def matrixTranspose(self, sheet1): for rows in range(self.rows): for cols in range(self.cols): self.matrix.data[cols][rows].value = sheet1.matrix.data[rows][cols].value #Looking up for a particular value by entering the row and column number def getCell(self, rows, cols): return self.matrix.getElementAt(rows, cols) #Saving the spreadsheet to check the output in the form of txt file def saveFile(self, filename): with open(filename, 'w') as file: file.write(self.__str__())
class Sheet(object): def __init__(self, rows, cols): self.rows = rows self.cols = cols self.matrix = Matrix(rows, cols) # fill the sheet with zero numbercells for row in range(self.rows): for col in range(self.cols): self.updateValue(row, col, "0") def coordstringToRowCol( self, coordinate_string ): #input is for example AB12, output is then [12, 27] p_letters = re.compile('[A-Z]+') p_numbers = re.compile('[1-9][0-9]*') matches_letters = p_letters.finditer(coordinate_string) matches_numbers = p_numbers.finditer(coordinate_string) letters = [ coordinate_string[match_letters.start():match_letters.end()] for match_letters in matches_letters ] letters_int = [self.colNameToInt(l) for l in letters] numbers = [ int(coordinate_string[match_numbers.start():match_numbers.end()]) for match_numbers in matches_numbers ] return [numbers[0] - 1, letters_int[0]] def updateValue2(self, coordinate_string, newValue): #coordinate_string should be something like A5 result = self.coordstringToRowCol(coordinate_string) self.updateValue(result[0], result[1], newValue) def updateValue(self, row, col, newValue): if newValue.isdigit(): cellObject = NumberCell(newValue, [row, col]) else: cellObject = FormulaCell(newValue, self, [row, col]) self.matrix.setElementAt(row, col, cellObject) # self.checkAllDependenciesForUpdates() # lookup the value of a given cell. # x = A1, B22, AB33 ... def getCellObject( self, row, col ): #get the NumberCell or Formulacell object at the given coordinates return self.matrix.getElementAt(row, col) def colNameToInt(self, name): result = 0 for i in range(len(name)): result += (ord(name[i]) - 65 + 1) * 26**(len(name) - 1 - i) return result - 1 def intToColName(self, x): uppercases = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' # 0 = A, 25 = Z result = [] if x >= 0: rest = x % 26 x = (x // 26) result.insert( 0, uppercases[rest] ) # prepend the uppercase letter to the resulting list while x > 0: rest = x % 26 x = (x // 26) result.insert(0, uppercases[ rest - 1]) # prepend the uppercase letter to the resulting list resultString = ''.join(result) return resultString def lookup(self, x): p = re.compile('[A-Z]+') matches = p.match(x) to = matches.end() letters = x[:to] digits = x[to:] row = int(digits) - 1 # for 0 based matrix index col = self.colNameToInt(letters) cell = self.matrix.getElementAt(row, col) return cell.value def __str__(self): return self.matrix.__str__()
def test_set_entries(self): m = Matrix(2, 3) m.set_entries([0, 1, 2, 3, 4, 5]) n = "|0 1 2|\n|3 4 5|" self.assertEqual(n, m.__str__())
def test_string(self): m = Matrix(2, 2) m.set_board([[1, 2], [3, 4]]) n = "|1 2|\n|3 4|" self.assertEqual(n, m.__str__())