亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

在Gnumeric下使用Python腳本操作表格的教程

系統 1789 0

關于Gnumeric

Gnumeric是linux平臺下的一款功能強大且易于使用的電子表格軟件,與其他常用電子表格軟件如Excel等在風格上非常一致。Gnumeric當前的穩定版是1.2.13,對中文的支持已經比較成熟。據官方信息,Gnumeric除實現了MS Excel所有的函數外,還實現了60多個Excel中不存在的函數和基本的金融方面函數,并已經具備了高級統計分析、可擴展的隨機數產生器、線性或非線性求解的計算能力。更令人驚喜的是,現在Gnumeric已經集成了Python強大的腳本編程能力,Python用戶可以為Gnumeric實現更為復雜的計算功能。

何謂Python

Python是一種解釋性的,面向對象的,具有動態語義的程序設計語言。Python代碼具有優秀的可讀性,具有模塊和包的概念,支持各種主流平臺,并具有很好的跨平臺能力。Python已廣泛用于文本處理、互聯網編程、數據庫編程、系統管理等領域 。同時Python又是一種成功的嵌入語言,包裝C/C++的代碼非常方便,越來越多的重量級應用程序開始支持Python腳本編程,OpenOffice, GIMP, Blender等。

插件初探

任何一個C函數調用或訪問一個Python對象都必須遵循這樣一個框架:

1. C函數把調用參數轉換成Python語言數據類型

2. 利用轉換后的參數調用Python函數

3. 返回值轉換成C語言類型,并返回給C函數

類似的,從Python函數調用C函數也遵循相似的步驟:

1. Python函數把參數轉換成C語言類型

2. 用轉換后的參數調用C函數

3. 返回值轉換成Python語言類型后返回給Python函數

因此Python函數和C函數相互調用的關鍵是數據的相互轉換問題,這些轉換需要相當好的C和Python解釋語言開發功底,好在Gnumeric的Python插件已經自動為我們做了數據類型的轉換,我們只需關注算法的實現就可以了。

Gnumeric和Python的交互也遵循類似的過程,首先Gnumeric自動轉換參數類型,繼而調用Python函數,最后再把返回值轉換成合適的類型返回給Gnumeric。下面是Gnumeric和Python的常見數據類型對應表:

在Gnumeric下使用Python腳本操作表格的教程_第1張圖片

對于單元格(Cell),Gnumeric把單元格中的數據直接轉換相應的數據類型,傳遞被調用Python函數,如整數(Integer)、浮點數(Float)、字符串(String);然而對于單元格區域(Range),Gnumeric采取迂回的策略,只是傳遞一個單元格區域的引用(RangeRef)給被調用Python函數,而Python這時就需要通過Gnumeric接口才能訪問和操作單元格區域中的數據。因此,Gnumeric為Python提供了Gnumeric模塊,,包括Gnumeric的全部函數和工作薄工作表對象,這里簡略地列出了Gnumeric模塊中的函數和對象(具體細節請讀者參考Gnumeric的py-gnumeric.c源文件位于plugins/python-loader目錄)。

在Gnumeric下使用Python腳本操作表格的教程_第2張圖片

范例分析

通過上面的介紹,我們初步了解了跨語言調用的框架,在此基礎上再來分析一下Gnumeric軟件包自帶的Python插件范例(通常位于/usr/lib/gnumeric/ /plugins/py-func/)。該范例由plugin.xml、py_func.py兩個文件構成,plugin.xml是XML形式的配置文件,供Gnumeric來讀取python函數的相關信息;py_func.py包含Python函數的定義和函數原型字典。

首先分析的是py_func.py文件。該文件定義了三個函數:func_printf,func_capwords,func_bitand,功能分別是格式化輸出,單詞首字母大寫,按位求和。我們來比較一下這三個函數:

在Gnumeric下使用Python腳本操作表格的教程_第3張圖片

以func_bitand函數為例,函數接受兩個整數,返回值也為整數,C與Python的類型轉換是Gnumeric自動完成的,func_bitand只注重算法的實現,具體計算是通過調用Gnumeric的按位求和函數(bitand)完成的;值得一提的是''@''開頭的文檔字符串是提供給Gnumeric的文檔接口,分別提供函數的功能、接口、實例以及引用方面的信息,格式也是固定的,每個域(包括換行符)用單引號括起來并后接"\"。
代碼 1 func_bitand函數定義

            
from Gnumeric import *
def func_bitand(num1, num2):
    '@FUNCTION=PY_BITAND\n'\
    '@SYNTAX=PY_BITAND (num)\n'\
    '@DESCRIPTION=The BITAND function returns bitwise'\
    'and-ing of its arguments.'\
    '\n'\
    '@EXAMPLES=\n'\
    'PY_BITAND(6, 2) equals 2)'\
    '\n'\
    '@SEEALSO=BITAND'
    
    
    gnm_bitand=functions['bitand'] # Gnumeric的按位求和函數
    return gnm_bitand(num1, num2)


          

py_func.py文件尾處還有一個起特殊作用的字典,向Gnumeric提供Python函數原型信息,姑且稱之為函數原型字典。函數原型字典的命名是非常嚴格的,必須以"_functions"為后綴,"_"前面前面的名字必須與plugin.xml文件保持一致,這樣Gnumeric才能發現插件中的各種函數信息,否則Gnumeric就會出現許多函數信息方面的錯誤,導致插件函數無法使用。函數原型用字典中"key:value"對來表示(代碼2), 如func_bitand,key就是在Gnumeric被映射的函數名py_bitand,value是由參數類型、參數名稱、函數名稱組成的元組。
代碼 2 test_functions函數原型字典

            
test_functions = {
    'py_printf': func_printf,
    'py_capwords': ('s', 'sentence', func_capwords),
    
    
    'py_bitand':  ('ff', 'num1, num2', func_bitand)
}


          

在函數原型字典中,參數類型是用特殊的字符來表示的,例如func_bitand的兩個浮點數參數表示為"ff"。常見參數類型的字符串表示總結如下:

在Gnumeric下使用Python腳本操作表格的教程_第4張圖片

另外一個結構簡單的XML文件plugins.xml (1) ,是開發者向Gnumeric提供的配置信息。information標簽中的name和description標簽提供了該插件的名字和描述信息,而且這些信息的國際化也很簡單,只需要在有語言標記的相應標簽中填寫國際化信息即可。loader標簽中attribute標簽的value屬性、service標簽中id屬性、function標簽中的name屬性是最重要的,分別對應于Python腳本文件名、腳本中的函數原型字典名(不包括后綴)、函數原型函數的key。對于本例,屬性值為py_func,test,py_printf,py_capwords,py_bitand,則對應于插件分別為py_func.py和test_functions,py_printf,py_capwords,py_bitand。這些對應關系一定要一致,否則Gnumeric就會向你抱怨了。
代碼 3 py-func.py的plugin.xml配置文件

            
              
                
                  Python functions
                
                
                  Sample Python plugin providing
               some (useless) functions.
        
                
                
              
              
                
              
              
                
                  
                    Python
                  
                  
                    
                Python
            
                  
                  
                    
                    
                    
                  
                
              
            
          

牛刀小試

根據上面的分析,我們看到用Python編寫Gnumeric函數,需要三個步驟:

1. 創建Python函數源文件,如py_func.py。

2. 根據創建的函數構建函數原型字典,如test_functions。

3. 創建plugin.xml配置文件,配置文件名、函數分類、名字、原型字典等相關信息。

為了演示具體的Gnumeric中Python函數創建的過程,筆者編寫了一個根據自動標記成績等級的小函數,由plugin.xml和exam.py兩個文件構成。

首先創建腳本文件exam.py,整個文件只有mark和cstr兩個函數:mark函數的參數和返回值都是字符串,功能是根據其大小返回成績的等級;cstr用來把字符串轉換成utf-8編碼,使Gnumeric能顯示中文 (2) 。mark函數中的注釋是提供給Gnumeric的函數信息,讀者開發時只需要按著模板簡單的修改就可以了。
代碼 4 exam.py文件

            
# -*- coding: GB2312 -*-
def mark(score):
  '@FUNCTION=MARK_SCORE\n'\
  '@SYNTAX=mark_score(score)\n'\
  '@DESCRIPTION= determine the level for a score\n'\
  '@EXAMPLES= To determine a score in A1: \n'\
  '  mark_score(a1)\n'\
  '@SEEALSO='
  level='N/A'
  if score < 0:
    level = cstr('非法分數')
  elif score < 60:
    level = cstr('未及格')
  elif score < 80:
    level = cstr('及格')
  elif score < 90:
    level = cstr('良')
  elif score <= 100:
    level = cstr('優秀')
  else:
    level = cstr('非法分數')
  return level
def cstr(str):
  """ translate a chinese string into utf-8 string for GTK+ 
  """
  return unicode(str,'gbk').encode('utf8')
exam_functions = {
  'mark_score' : ('f','score',mark)
}


          

下一步就是就是注冊函數,exam.py文件尾處的exam_functions函數原型字典向Gnumeric揭示了mark函數的原型信息,字典的鍵'mark_score'是mark在Gnumeric的名字映射,f表示參數類型為整數,score為參數名。plugin.xml (3) 是根據模板簡單的改寫的,主要注意的就是上面提到的幾個屬性,必須和插件對應,否則插件是無效的;另外一些屬性,如category也加入了中文信息,以方便使用。
代碼 5 exam.py的plugin.xml配置文件

            
              
                
                  Exam functions
                
                
                   Determine rank for exam score 
                
                
              
              
                
              
              
                
                  
                    
    
    Exam
                  
                  
                    Exam
                  
                  
                    
                  
                
              
            
          

OK!現在啟動Gnumeric (4) ,按圖示在A列輸入一列成績,然后在B1單元格內輸入公式:'=mark_score(A1)', 然后利用鼠標拖動復制公式的功能,把公式復制到對應的B列,就會發現所有標志在B列中已經自動生成了。
插圖1 成績分類

在Gnumeric下使用Python腳本操作表格的教程_第5張圖片

更進一步

如果只是對單元格數據簡單計算的話,那么Python在Gnumeric中充其量是好玩的玩具罷了,但Python插件的功能遠不只這些,Python可以控制讀寫單元格區域(Range)的數據,訪問Gnumeric的全部函數,控制工作表的創建等,把這些功能有機地組合起來就能完成復雜的任務了。本節對全班成績做進一步的處理,利用RPy (5) 的summary函數對所有的分數進行簡單的統計,計算最值、均值、中位數和兩個四分位數,并把所得計算結果打印到新的工作表中。

要想統計全班成績,首要的任務就是從Gnumeric獲取數據。對于大批量的數據,Gnumeric是用單元格區域(Range)來表示的,然而在調用過程中傳遞給Python的是單元格區域引用(RangeRef),所以需要對單元格區域引用(RangeRef)做相應的轉換以便提取批量數據。不幸的是,Gnumeric的API正處于發展階段,沒有直接的轉換方法。為此,筆者利用了Gnumeric自身的函數構建了一個PyGnmRange類。PyGnmRange對象以單元格區域引用(RangeRef)為初始化參數,為該單元格區域中的構建所有單元格的索引,即"_table"屬性,同時提供幾個方法來方便地訪問,這樣我們就可以配合Gnumeric模塊中的Sheet對象操縱單元格數據了。
代碼 6 類PyGnmRange的定義

            
    class PyGnmRange:
  def __init__(self, gnm_range_ref):
    get_cols = Gnumeric.functions['column']
    get_rows = Gnumeric.functions['row']
    get_col_num = Gnumeric.functions['columns']
    get_row_num = Gnumeric.functions['rows']
    cols = get_cols(gnm_range_ref)
    rows = get_rows(gnm_range_ref)
    # column first table
    self._table = []
    self._col_num = get_col_num(gnm_range_ref)
    self._row_num = get_row_num(gnm_range_ref)
    for i in range(self._col_num):
      for j in range(self._row_num):
        self._table.append((cols[i][j]-1, rows[i][j]-1))
  def col_num(self):
    return self._col_num
  def row_num(self):
    return self._row_num
  def get_col(self,col):
    start = (col-1) * self._row_num
    end = col * self._row_num
    return self._table[start:end]
  def get_row(self,row):
    indexes = [(i*self._row_num)+(row-1) for i in range(self._col_num)]
    return [self._table[i] for i in indexes]
  def __iter__(self):
    return iter(self._table)


          

另外PyGnmRange類定義需要注意兩點:

1. 單元格下標采取了列優先的表示方法,從零開始計數,例如B3表示為(1,2),這樣同時也是為了與Gnumeric規范保持一致,便于操縱單元格數據。

2. 類初始化函數使用了四個Gnumeric的函數,分別為column、columns、row、rows,其功能如下:

在Gnumeric下使用Python腳本操作表格的教程_第6張圖片

有了前面的準備,我們就可以具體實現summary函數了。summary函數通過gnm_scores參數獲得當前的單元格區域引用,并利用該參數創建PyGnmRange對象,計算所有單元格的下標;又通過Gnumeric模塊的workbooks和sheets函數,取得工作表1的對象;從而結合工作表對象和單元格下標來操作單元格數據。而真正的計算R語言完成的,RPy模塊則是聯接Python和R語言的橋梁 (6) 。最后,summary函數取得R語言計算的結果并通過Gnumeric模塊將其打印到一個新建的工作表里。
代碼 7 exam.py 中summary函數定義

???

            
              
                
                  Exam functions
                
                
                  Sample Python plugin providing some (useless) functions.
                
                
              
              
                
              
              
                
                  
                    Exam
                  
                  
                    Exam
                  
                  
                    
                    
                  
                
              
            
          

函數編寫完之后就是函數注冊了,函數原型字典只有一行,唯一需要注意的是,單元格區域引用數據類型需要用"r"來表示。plugin.xml文件也只需要加入下面一行:
代碼 8 summay函數的plugin.xml配置文件

            
              
                
                  Exam functions
                
                
                  Sample Python plugin providing some (useless) functions.
                
                
              
              
                
              
              
                
                  
                    Exam
                  
                  
                    Exam
                  
                  
                    
                    
                  
                
              
            
          

下面的兩張是插件函數的運行效果圖,輸入數據是隨機生成的80個100以內的浮點數,函數插在B1單元格內,由于該函數的目的是生成簡單的報表而不是返回值,所以運行結束后B1單元格內依然空白,而所有的數據全部打印在新建的工作表4內(圖2和圖3)。
插圖2 全班成績和函數的輸入

在Gnumeric下使用Python腳本操作表格的教程_第7張圖片
插圖3 全班成績統計報告

在Gnumeric下使用Python腳本操作表格的教程_第8張圖片

插件部署

Gnumeric插件部署及其簡單,用戶只需要在自己主目錄下新建.gnumeric目錄,放入插件函數即可,例如exam.py和plugin.xml就是位于 /.gnumeric/ (7) /plugins/exam/,重新啟動Gnumeric插件就生效了 (8) 。

結束語

Gnumeric的Python開發過程需要注意一下幾個問題:

1. Gumeric的Python插件還處于積極地開發過程中,一些代碼很可能在將來的版本中會發生很大的變化;插件提供的Gnumeric模塊接口還不是完整,比如缺乏獲得活動工作表的函數,編寫Python函數時需要仔細地處理。

2. Python函數配置雖然及其簡單,但是調試起來不是很方便,經常會出現Gnumeric不能正確獲取Python信息的情況,這時候的原因是多方面的,例如plugin.xml文件的名字與腳本文件不一致,函數原型字典命名不規范,函數文檔字符串格式錯誤,腳本文件語法錯誤等。

盡管這樣,對于熟悉Python的編程人員來說,這些并不影響編寫Gnumeric函數的趣味,只需小心仔細地處理,這些都不是很難的事。希望本文能起到拋磚引玉的作用,有興趣的讀者可以在此基礎上參考Gnumeric源代碼中的開發者文檔和Python插件的源代碼,會發現許多有價值的信息,編寫更有價值的應用了。


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 日韩成人三级 | 国产高清视频 | 亚洲美女黄视频 | 五月婷婷亚洲 | 亚洲a免费 | 搜毛片 | 欧美性生交xxxxx久久久 | 真人一级毛片免费观看视频 | 日韩精品一区二区三区免费视频 | 国产精品www | 一区二区三区四区国产精品 | 国产免费69成人精品视频 | 久久精品国产精品青草图片 | 欧美手机看片 | 美女被羞羞视频网站在线 | 咪咪爱毛片 | 中文字幕亚洲综合久久 | 天天毛片 | 九九99re在线视频精品免费 | 欧美曰韩免费视频一区 | 一二三区免费视频 | a毛片基地 | 久久99精品久久久久久久不卡 | 国产精品免费观看 | 国产在线观看一区二区三区四区 | 四虎影视永久在线精品免费播放 | 日日爽夜夜操 | 国产成人丝袜精品自啪在线 | 一级a性色生活片毛片 | 91热视频在线 | 欧美一级成人 | 亚洲精品日韩在线一区 | 天堂一区 | 久久爱综合网 | 99精品视频在线免费观看 | 狠狠丁香激情久久综合 | 亚洲一本通 | 国产麻豆精品hdvideoss | dyav午夜片| 久久精品国产久精国产果冻传媒 | 亚洲综合成人网在线观看 |