CoffeeScript – 演算

数値演算

四則演算

+ 加算
減算
* 乗算
** べき乗
/ 除算:小数の丸めはなし 11 / 4 → 2.75
// 除算の商 11 // 4 → 2
% 除算の剰余 11 % 4 → 3
%% %と同じ

CoffeeScriptからJavaScrioptへコンパイルした結果は以下のようになる。

11 / 4 11 / 4
11 // 4 Math.floor(11 / 4)
11 % 4 11 % 4
11 %% 4 modulo(11, 4)

インクリメント/デクリメント

インクリメント(++)、デクリメント(–)演算子は、前置・後置で使用可能で、後置は参照後に、前置は参照前に演算が行われる。

変数の値が小数部を持つと、演算誤差が発生する。

代入演算子

数値演算については、”+=”のような代入演算子が各四則演算子について使える。

丸め処理

Mathライブラリのクラスメソッドを使う。

小数点以下の処理
Math.floor() 切り捨て
Math.ceil() 切り上げ
Math.round() 四捨五入

文字列演算

結合

+演算子は二つの文字列を結合する。

片方が文字列でもう片方が数値の場合、数値が文字列に変換されて結合される。

演算 結果
“abc” + “def” “abcdef”
“abc” + 123 “abc123”
123 + “abc” “123abc”

代入演算子

代入演算子の場合、元の変数かオペランドのいずれか一方が文字数なら、文字列として結合される。

数値と文字列の変換

数値→文字列の変換

  • 12.34 + “deg”
  • String(12.34) + “deg”
  • 12.34.toString() + “deg”

文字列→数値の変換

  • Number(“34.56”)
  • parseInt(“34.56”, 10)
  • parseFloat(“34.56”)
  • parseInt(“ffff”, 10)→65535
    • parseInt(“0xffff”, 10)→65535
  • parseInt(“22”, 10)→18
    • parseInt(“0o22”, 10)→0
  • parseInt(“111”, 10)→7
    • parseInt(“0b111”, 10)→0
  • parseInt(“abc”)→NaN

存在演算子

 

CoffeeScript – リテラル

数値リテラル

整数

123 10進数
0b110 2進数
0o11 8進数
0xff 16進数

実数

123.456 固定小数点
1.23456e3 浮動小数点

文字列リテラル

シングルクォート(‘)かダブルクォート(‘)の対で囲む。

シングルクォートで囲った場合はダブルクォートを、ダブルクォートで囲った場合はシングルクォートを直接文字列内に書ける。バックスラッシュによるエスケープでも可能。

 

シングルクォートとダブルクォートの違い

ダブルクォートで囲った場合、文字列リテラル中の#{}によって式が評価された結果を文字列に埋め込めるが、シングルクォートの場合は上記の記号や式がそのまま文字列として返される。

リストと配列

 

Lifegame (CoffeeScript)

概要

CoffeeScriptに慣れるための習作。

ライフゲームの世界をLifeWorldクラスで構築し、パターンのセットや描画を行わせている。表示に関してはcanvasを利用している。

スマートフォン用はこちら

デモンストレーション



    


    



HTML内容

bodyブロックの構成は以下の通り。

  • 初期パターン選択
  • サイズ選択
  • 時間間隔選択
  • 開始/停止ボタン
  • 表示領域

初期パターン選択

規定パターンの中から、ドロップダウンリストで初期パターンを選択。この要素の選択状態が変化した場合の処理は、スクリプト側でjQueryを用いてコールバックを定義している。

サイズと表示間隔の選択

それぞれラジオボタン群で選択させる。これらの要素の選択状態が変化した場合の処理も、スクリプト側でjQueryを用いてコールバックを定義している。

開始/停止ボタン

ボタンが押されるた時の処理はスクリプト側でjQueryを用いてコールバックを定義しており、その時の状態によって停止と起動を繰り返す。

描画領域

HTMLのcanvasを設置。

CoffeeScriptコード

初期パターン

初期パターンを配列にセットしている。たとえば「グライダー」の場合は以下のように定義している。

本体

本体コードは、LifeWorldクラスとグローバル関数の定義からなる。

ブラウザのボタン操作なや状態変化などに対応するコールバックは、jQueryを利用して実装。

初期動作

ブラウザからこのスクリプトが呼び出されたときに一回だけ動作。

LifeWorldの初期化や、コールバックの設定を行う。

グローバル関数

getNewLifeWorld()

LifeWorldの新しい状態を設定する際に呼ばれる関数。

ブラウザの部品から直接は呼ばれないため、windows.の要素とはしていないが、グローバルスコープの関数。

LifeWorldクラス
constructor(canvas)

LifeWorldクラスのコンストラクタ。

canvasを引数にしてインスタンスを生成するが、この段階ではグリッドも生成されていない。他のパラメータについては個別に設定することを意図している。

create(row, col)

行数と列数を指定してインスタンスのグリッドを構築する。グリッドの全要素が0で埋められている。

setDisplayInterval(interval)

動画フレームの時間間隔を設定。

CoffeeScript特有の、引数を直接パラメータに代入する形式。

setPattern(patternString)

選択されているラジオボタンの文字により、あらかじめ定義された初期パターンを登録。

初期パターンがグリッドの中央付近に来るように調整している。

draw()

グリッドの状態に応じてcanvasのコンテキストに描画。格子線も描いている。

nextGeneration()

次のgetNewStatusAt()メソッドを使いながら、次の世代のグリッドの状態を形成。

新しい世代用の一時的なグリッドを生成している。

getNewStatusAt(grid, row, col)

現在の状態から、次の世代のグリッドの状態を算出。

自分のマスの周囲8つのマスの存在状態から、次の世代の誕生/存続/死滅を決定。

周囲の生存数 現状=存在 現状=不在
0 死滅 不在
1~2 存続 不在
3 存続 誕生
4以上 死滅 不在

animate()

setInterval()メソッドに登録するための、ワンフレームの画像を描くメソッド。

startAndStop() / stop()

startAndStop()は、現在動画を実行中かどうかのフラグをチェックし、停止していればsetInterval()を用いて起動、起動中ならclearInterval()停止を行う。

stop()は、状態によらず停止処理。

 

Brython – Timer

Brythonにおけるタイマ処理

Brthonでタイマ処理を実装する場合、time.sleep()メソッドとスレッドクラスの継承を用いても、ブラウザで適切に処理されない(Chromeで実行した場合、処理の冒頭に反応がなく、ある程度の時間後にそれまでの処理が一挙に実行され、その後正常なタイマ処理が続行された)。

Brython固有の機能としてbrowser.timerモジュールにJavaScriptのintervalやtimeoutに相当する以下のメソッド群が用意されている。

  • set_interval()/clear_interval
  • set_timeout()/clear_timeout()
  • request_animation_frame()/cancel_animation_frame

これらはJavaScriptのそれぞれに相当する関数のwrapperであり、JavaScriptの仕様に従っていると考えられる。

JavaScriptのタイマ関係の関数についてはこちらを参照。

interval

基本形

timerパッケージのset_interval()メソッドで一定時間間隔で関数を起動し、clear_interval()メソッドでタイマーの実行を停止する。

引数を渡す場合

ターゲットの関数に引数を渡したい場合、BrythonではJavaScriptのような文字列渡しはできないが、lambda関数式で無名関数の中でターゲットの関数に引数を渡すことができる。

こちらのデモにもtimer.set_interval()を利用している。

 

Brythonの実行時間

概要

Python3、JavaScriptとBrythonの実行時間を比較してみる。

数値演算

Python/Brythonコード


JavaScriptコード

結果

経過時間
Python3 0.152009sec
Brython 3.068000sec
JavaScript 3.000000sec

配列の確保

Python/Brython

JavaScript

結果

経過時間
Python3 0.006001sec
Brython 8.212000sec
JavaScript 2.000000sec

Brython – canvas

Brythonによるcanvasの利用

  1. HTMLで、canvas要素をidを付して記述
  2. browserからdocumentをインポート
  3. documentからcanvasを取得
  4. canvasが取得可能かどうか判定
  5. 2Dのcontextを取得
  6. contextに対してライブラリで描画

canvasライブラリについてはHTML5-canvasを参照。

 

Brython

Brython利用の基本形

  1. Brythonのライブラリを読み込む
  2. brython()を実行させるよう指示する
  3. scriptタグでPythonを指定する
  4. script要素内にPythonのコードを記述する

Brythonのライブラリを読み込む

ライブラリはJavascriptファイル。head要素内でライブラリを指定して読み込ませるが、サーバ上にライブラリを配置しておく方法と、その都度Brythonのサイトから読み込む方法がある。

サーバ上にライブラリを置く場合

サーバ上にライブラリを置かない場合

brython()を実行させる

通常の事例では、body要素のonload属性で指示している。

scriptタグでPythonを指定する

コード例

Brythonのコード例。テクストボックスに名前を入力し、alertで表示。

ボタンのonclick属性でhello()関数を呼び出そうとするとundefinedエラーとなる。Brythonのサイトの事例ではdocオブジェクトのbindメソッドを用いており、これで動作した。

WordPressに移行してからスクリプトの使い方がわからないので、ここではコード例のみ。

console.log

Brythonでconsole.logを使うためには、browser.consoleパッケージを利用する。


 

Python3 – 処理時間の計測

time.time()関数は、呼び出した時点のエポックタイムを秒単位の浮動小数点型で返す。


 

Python3 – スレッド

基本形

threading.Threadクラスで実行する関数と引数を指定し、start()メソッドで開始させる。

同期

幾つかのスレッドの終了を待ってから後続のスレッドを実行させたい場合、join()メソッドで同期をとりたいスレッドの終了を待機する。

スレッドクラス

スレッドクラスを継承したカスタムクラスでの実装方法。

  • thread.Threadクラスを継承する
  • コンストラクタでThreadクラスのコンストラクタを呼び、必要なプロパティをセット
  • run()メソッドをオーバーライドし、処理内容を記述
  • カスタムクラスのインスタンスでstart()を実行

start()メソッドを実行すると、親のThreadクラスのstart()メソッドが呼び出され、そこでrun()メソッドが呼ばれ、カスタムクラスでオーバーライドしたrun()メソッドが実行される。run()メソッドを直接実行すると、シングルスレッドとして実行される。

スレッドの停止

スレッド停止の機能は、thread.Threadクラスを継承したカスタムクラスで実装する。

 

Python3 – 変数のスコープ

ブロックスコープはない

したがって、if文やfor文などの制御構文はスコープを持たない。制御文の外で定義された変数は制御文内で参照でき、制御文内での変更は変数に影響を与える。

関数のスコープ

関数内では変数はローカルスコープを持つ。

  • グローバル変数は関数内から直接には参照できないため、無定義で参照しようとするとエラーとなる
  • 関数内でグローバル変数と同じ名前の変数を定義すると、ローカル変数として扱われる
  • ローカル変数の変更は、同名のグローバル変数に影響を与えない

クラスのスコープ

クラスはローカルのスコープを持つが、クラス変数とインスタンス変数でもスコープが異なる。

global宣言

グローバル変数をglobal宣言することで、関数の中で参照・変更が可能となる。