Brython 3.3.4 程式環境

利用 BrythonAce 編輯器, 建立瀏覽器上的簡單 Python3 程式練習環境.

編寫 Python3 程式邏輯之前必須先了解基本的程式語法, 其中包括:

Python3 變數命名規則與關鍵字

Python 英文變數命名規格

變數必須以英文字母大寫或小寫或底線開頭
變數其餘字元可以是英文大小寫字母, 數字或底線
變數區分英文大小寫
變數不限字元長度
不可使用關鍵字當作變數名稱

使用者可以利用以下程式列出所使用 Python 的版次與關鍵字:

Python3 的程式關鍵字, 使用者命名變數時, 必須避開下列保留字.

Python keywords: ['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']

選擇好的變數名稱:

使用有意義且適當長度的變數名稱, 例如: 使用 length 代表長度, 不要單獨使用 l 或 L, 也不要使用 this_is_the_length
程式前後變數命名方式盡量一致, 例如: 使用 rect_length 或 RectLength
用底線開頭的變數通常具有特殊意義

print() 函式用法

print() 為 Python 程式語言中用來列印數值或字串的函式, 其中有 sep 變數定義分隔符號, sep 內定為 ",", end 變數則用來定義列印結尾的符號, end 內定為跳行符號.

for 迴圈用法與 Python 的縮排規定

重複迴圈用法, 使用者可以透過下列程式編輯區練習 for 迴圈與 print() 函式的用法.

下列的 Brython turtle 網際繪圖程式僅提供參考, 可以用來練習 Python3 程式語法.

函式用法與呼叫

使用者可以利用下列程式, 練習 def 函式定義與呼叫的用法.

以下網際繪圖程式, 僅提供參考.

以下網際動態繪圖程式, 僅提供參考.

基本物件導向與案例

Python 採用類別 (class) 將案例變數 (instance variables) 與案例方法 (instance methods) 包在一起, 並用來定義一種物件 (object).

物件導向具有封裝 (encapsulation) , 繼承 (inheritance) 與多形 ( polymorphism) 等三種特性.

使用者可以利用下列程式練習 Python3 物件的定義與應用.

以下平面機構動態模擬程式, 僅提供參考.

平面機構運動模擬

以下為 Jansen's 八連桿機構的基本 Kinematic 運算, 先採用 Sympy 以符號式推導出機構端點的運動軌跡方程式後, 利用 Python 執行數值分析運算, 列出機構端點的座標.

以下為與上述 Jansen's 八連桿機構對應的座標驗證圖, 機構端點座標 kx= -30.81 ky= -84.02:

平面機構數目合成

itertools module implements a number of iterator building blocks.

itertools.product(*iterables, repeat=1) - Cartesian product of input iterables.

根據 http://www.iftomm2015.tw/IFToMM2015CD/PDF/OS2-048.pdf (or local download)

目前所在頁面, 分別利用 BrythonAce 編輯器, 可直接在網誌中執行 Python3 程式, 基本架構為將 Brython 的標準輸出轉到特定 div 標註, 而 Ace 編輯器則設為與其內的程式碼相同長度, 但至多只會在頁面中顯示 20 行, 且編輯器內的程式碼使用 12 號字元.

ace.py 原始碼, 位於 data/py 目錄中, 將原先只能單一呼叫的函式改為物件, 可以在同一頁面中產生案例時, 透過各標註的 id 字串區分各段程式碼, 是本課程 Python3 物件導向程式的實際應用範例, 謹提供參考.

import sys
import time
import traceback
import javascript

from browser import document as doc, window, alert

if hasattr(window, 'localStorage'):
    from browser.local_storage import storage
else:
    storage = None

class cOutput:

    def __init__(self, target):
        self.target = doc[target]

    def write(self, data):
        self.target.value += str(data)

class Editor():

    def __init__(self, editor_id, console_id, container_id, storage_id):
        self.editor_id = editor_id
        self.console_id = console_id
        self.container_id = container_id
        self.storage_id = storage_id
        self.output = ''

        try:
            self.editor = window.ace.edit(self.editor_id)
            session = self.editor.getSession()
            session.setMode("ace/mode/python")

            self.editor.setOptions({
             'enableLiveAutocompletion': True,
             'enableSnippets': True,
             'highlightActiveLine': False,
             'highlightSelectedWord': True,
             'autoScrollEditorIntoView': True,
             # 'maxLines': session.getLength() 可以根據程式長度設定 editor 列數
             # 設定讓使用者最多可以在畫面中顯示 20 行程式碼
             'maxLines': 20,
             'fontSize': '12pt'
            })
        except:
            from browser import html
            self.editor = html.TEXTAREA(rows=20, cols=70)
            doc[self.editor_id] <= self.editor
            def get_value(): return self.editor.value
            def set_value(x): self.editor.value = x
            self.editor.getValue = get_value
            self.editor.setValue = set_value

    def run(self, *args):
        sys.stdout = cOutput(self.console_id)
        sys.stderr = cOutput(self.console_id)
        doc[self.console_id].value = ''
        src = self.editor.getValue()
        if storage is not None:
           storage[self.storage_id] = src

        t0 = time.perf_counter()
        try:
            #ns = {'__name__':'__main__'}
            # 以 self.editor_id 名稱執行程式
            ns = {'__name__': self.editor_id}
            exec(src, ns)
            state = 1
        except Exception as exc:
            traceback.print_exc(file=sys.stderr)
            state = 0
        self.output = doc[self.console_id].value

        print('<completed in %6.2f ms>' % ((time.perf_counter() - t0) * 1000.0))
        return state

    def show_console(self, ev):
        doc[self.console_id].value = self.output
        doc[self.console_id].cols = 60
        doc[self.console_id].rows = 10

    def clear_console(self, ev):
        doc[self.console_id].value = ""

    def clear_container(self, ev):
        doc[self.container_id].clear()

    # load a Python script
    def load_script(self, evt):
        _name = evt.target.value + '?foo=%s' % time.time()
        self.editor.setValue(open(_name).read())