# my-func.py # from Gnumeric import * import Gnumeric import string import random # Add two numbers together def func_add(num1, num2): '@FUNCTION=PY_ADD\n'\ '@SYNTAX=py_add(num1, num2)\n'\ '@DESCRIPTION=Adds two numbers together.\n'\ 'Look, the description can go onto other lines.\n\n'\ '@EXAMPLES=To add two constants, just type them in: py_add(2,3)\n'\ 'To add two cells, use the cell addresses: py_add(A1,A2)\n\n'\ '@SEEALSO=' return num1 + num2 def func_sum2(gRange): '''@FUNCTION=PY_SUM2\n @SYNTAX=PY_SUM2(range)\n @DESCRIPTION=Adds a range of numbers together, without calling built-in SUM.\n\n @EXAMPLES=To add values in A1 to A5, just type them in:\n py_sum(a1:a5)\n @SEEALSO=''' try: [r_begin, r_end] = range_ref_to_tuples(gRange) wb=Gnumeric.workbooks()[0] # Careful! This is WRONG! It doesn't s=wb.sheets()[0] # use the ACTUAL workbook or sheet. val = 0 for col in range(r_begin[0], r_end[0]): for row in range(r_begin[1], r_end[1]): cell = s[col, row] val = val + cell.get_value() # Note: this doesn't skip blank cells etc. except TypeError: raise GnumericError,GnumericErrorVALUE else: return val def func_permute(gRange): '''@FUNCTION=PY_PERMUTE\n @SYNTAX=PY_PERMUTE(range)\n @DESCRIPTION=Permutes a range of cells\n\n @EXAMPLES=To permute the cells from A1 to A5, type into any cell:\n py_permute(a1:a5)\n @SEEALSO=''' try: [r_begin, r_end] = range_ref_to_tuples(gRange) wb=Gnumeric.workbooks()[0] # Careful! This is WRONG! It doesn't s=wb.sheets()[0] # use the ACTUAL workbook or sheet. print r_begin[0] print r_end[0] print r_begin[1] print r_end[1] val = 0 for col in range(r_begin[0], r_end[0]): for row in range(r_begin[1], r_end[1]): randcol = random.randint(r_begin[0], r_end[0]-1); randrow = random.randint(r_begin[1], r_end[1]-1); cell = s[col, row] val = cell.get_rendered_text() cell2 = s[randcol, randrow] print val cell.set_text(cell2.get_rendered_text()) cell2.set_text(val) # Note: this doesn't skip blank cells etc. except TypeError: raise GnumericError,GnumericErrorVALUE else: return 'Permute!' def range_ref_to_tuples(range_ref): '''I need a function to find the bounds of a RangeRef. This one extracts them from the Gnumeric "column" and "row" commands, and returns them as a pair of tuples. Surely there is a better way? For example, return a list of cells??''' col = Gnumeric.functions['column'] row = Gnumeric.functions['row'] # "column" and "row" take references and return an array of col or row # nums for each cell in the reference. For example, [[1, 1, 1], [2, 2, 2]] # for columns and [[2, 3, 4], [2, 3, 4]] for rows. try: columns = col(range_ref) rows = row(range_ref) begin_col = columns[0][0] - 1 begin_row = rows[0][0] - 1 end_col = columns[-1][-1] end_row = rows[-1][-1] # We subtracted 1 from the begin values because in the API, # indexing begins at 0, while "column" and "row" begin at 1. # We did NOT subtract 1 from the end values, in order to make # them suitable for Python's range(begin, end) paradigm. except TypeError: raise GnumericError,GnumericErrorVALUE except NameError: # right name? raise GnumericError,Gnumeric.GnumericErrorNAME except RefError: # right name? raise GnumericError,Gnumeric.GnumericErrorREF except NumError: # right name? raise GnumericError,Gnumeric.GnumericErrorNUM return [ (begin_col, begin_row), (end_col, end_row) ] # Translate the func_add python function to a gnumeric function and register it example_functions = { 'py_permute': ('r', 'gRange', func_permute) }