皆様こんにちは。
AMDlabの齋藤です。
世間ではChatGPTが注目されていますね。
私も触ってみていますが、プロンプト関連が悩ましいなと感じています。
Grasshopperでそれと連携している話があるようなので、いつか記事にしたいなと感じています。
さて、今回はGrasshopperやGrasshopperのGhPythonやC# Scriptで例外処理を考えてみようと思います。
例外処理を組むことによって作成者が予想しない入力が起こった時に、
おかしい挙動を防ぐことができます。
今回のデータはこちらに挙げております。
https://github.com/AMDlab/TechBlog-GH_Error_Handling
元のスクリプト
今回は以下プログラムを想定して例外処理を組んでみます。
ベースはList Itemと似た挙動を想定しています。
ここで i のスライダーはリストのインデックスで、範囲は-10<10、Slider TypeはFloating pointです。
GhPythonはLをList Accessに設定しているのみで以下のコードを書いています。
1 |
a = L[int(i)] |
C# Scriptも同じようにLをList Accessに設定しているのみで以下のコードを書いています。
1 2 3 4 |
private void RunScript(List<object> L, object i, ref object A) { A = L[(int) (double) i]; } |
これらから例外処理を実装していきます。
簡単に例外を発生させる(例外処理させる)
まずはGhPythonやC# Scriptに記述して例外処理をします。
例外処理は、Pythonは
raise Exception("エラーです。") C#は
throw new Exception("エラーです。"); のように簡単に実装してしまいます。
本来はより深くエラーの種類を選ばないといけないですが、そのあたりは省略しています。
GhPython
1 2 3 4 5 6 7 8 |
int_i = int(i) if int_i < 0: raise Exception("iが0より小さいです。") if len(L)-1 < int_i: raise Exception("iがLのインデックス上限外です。") a = L[int_i] |
C# Script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
private void RunScript(List<object> L, object i, ref object A) { int intI = (int) (double) i; if(intI < 0) { throw new Exception("iが0より小さいです。"); } if(L.Count - 1 < intI) { throw new Exception("iがLのインデックス上限外です。"); } A = L[intI]; } |
これで数値がリストの外にいった場合、エラーとして出力をしないようにできます。
MessageBoxで目立たせる
次はC# System.WindowsのMessageBoxを利用して表示させます。
GhPythonでも実行可能です。
GhPython
1 2 3 4 5 6 7 8 9 10 11 12 |
from System.Windows.Forms import MessageBox int_i = int(i) if int_i < 0: MessageBox.Show("iが0より小さいです。") raise Exception("iが0より小さいです。") if len(L)-1 < int_i: MessageBox.Show("iがLのインデックス上限外です。") raise Exception("iがLのインデックス上限外です。") a = L[int_i] |
C# Script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
using System.Windows.Forms; //--- usingディレクティブ ---- private void RunScript(List<object> L, object i, ref object A) { int intI = (int) (double) i; if(intI < 0) { MessageBox.Show("iが0より小さいです。"); throw new Exception("iが0より小さいです。"); } if(L.Count - 1 < intI) { MessageBox.Show("iが0より小さいです。"); throw new Exception("iがLのインデックス上限外です。"); } A = L[intI]; } |
この場合はスライダーを動かすごとに警告が出るので少し注意が必要です。
ですが、これを利用すれば以下のように重い処理の警告を出すことができます。
警告を出す
次は実行可能ではあるがユーザーが意図しない挙動となることがわかっている場合に、
その旨を伝える警告をGH_RuntimeMessageで出します。
GH_RuntimeMessageでは、GH_RuntimeMessageLevelで
Error
Warning
Remark
Blank が選ぶことができ、
以下のように表示さることができます。上から順に
Remark
Warning
Error で
Blank は表示されません。
今回は小数点以下がある値が入力されたときに Warning の警告を出すようにします。
GhPython
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
from Grasshopper.Kernel import GH_RuntimeMessageLevel int_i = int(i) if int_i < 0: raise Exception("iが0より小さいです。") if len(L)-1 < int_i: raise Exception("iがLのインデックス上限外です。") if int_i != i: ghenv.Component.AddRuntimeMessage( GH_RuntimeMessageLevel.Warning, "入力iがintでまるめられます。" ) a = L[int_i] |
C# Script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
private void RunScript(List<object> L, object i, ref object A) { int intI = (int) (double) i; if(intI < 0) { throw new Exception("iが0より小さいです。"); } if(L.Count - 1 < intI) { throw new Exception("iがLのインデックス上限外です。"); } if(intI != (double) i) { Component.AddRuntimeMessage( GH_RuntimeMessageLevel.Warning, "入力iがintでまるめられます。" ); } A = L[intI]; } |
以下のように警告を出すことができます。
入力に制限をかける
最後にこうならないために最初から入力に制限をかけてエラーをなくすことを考えます。
本来、今回のスクリプトでは、こちらをはじめに考えるべきなのですが、
上記説明を行うためにわざと制限をかけておりませんでした。
今回は
i のスライダーの範囲は0<4、Slider TypeはIntegersとします。
おわりに
いかがでしたでしょうか。
今回のように簡単な例では上手く伝えられない部分もありましたが、
このあたりまでしっかり実装させてあげると、ユーザー側でなぜ動かないのかの確認作業が減り、
プログラムの使い勝手がよくなります。
皆さんもぜひ挑戦してみてください。
COMMENTS