スクリプトの反復処理

このデモでは、For 関数を反復処理に使用する方法を示しています。これまで、スクリプト エディタとログを使用してスクリプトをテストし、結果を確認してきました。しかし、今度はデバッガを使用して結果を確認したいと思います。スクリプト エディタ ウィンドウを開いたら、まず Names Default to Here と入力します。そして、このブール値を入力します。今はスペースは追加しません。すべてを 1 行に入力し、自動フォーマット機能でクリーンアップさせます。セミコロン、For、開き括弧、a イコール セミコロン、b イコール セミコロン、i イコール カンマと入力して、3 つの変数を初期化します。次に、i がカンマより小さいというテストを入力し、b と i の両方を更新します。 b が更新されます -- b+ が等しくなります。これがインプレース代入関数、つまり add to 関数で、b の現在の値を上書きしてセミコロンで増やします。2 つのものを更新しているからです。そして i++、この ++ はポストインクリメント演算子で、i にその場で加算します。そしてカンマで、この単純なループの本体は Show 関数になります。a、カンマ、b、カンマと表示します -- 次に演算子を使って乗算関数を呼び出します -- つまり a 掛ける b です。次にすべての括弧を閉じてセミコロンを追加し、右クリックして再フォーマットします。ここで注目すべき点が 1 つ -- いや、2 つ -- 1 つは JMP によって余分なセミコロンが追加されたことです。JMP は、最初の引数で関数を結合していることを認識しました。3 番目の引数でも関数を結合していることを認識したので、これらのセミコロンが追加されました。これらは問題ではありません。実際には、これらのセミコロンはスクリプトから削除するでしょう。関数を追加したり、結合したりするのでなければ、これらは不要だからです。もう一つの方法として、各引数がそれぞれ1行になるように並べ替えることもできます。ただし、デバッガを起動したときに、コースのPDFファイルの内容と一致するようにしたいので、セミコロンを除いてJMPが再フォーマットした状態のままにしておきます。デバッガを起動する方法はいくつかあります。「編集」メニューの「スクリプトのデバッグ」オプションがあります。キーボードショートカットはCtrl+Shift+Rです。スクリプトエディタウィンドウの「デバッグ」ツールバーボタンをクリックすることもできます。または、右クリックして「スクリプトのデバッグ」を選択することもできます。最後に紹介する方法なので、この方法を使います。このデバッガはJMPの2番目のインスタンスです。そして、JMPの元のインスタンスは一時的に停止しています。スクリプトに必要なダイアログボックスなど、何らかの操作がある場合、デバッガウィンドウはその操作が行われるまで一時停止されます。操作が完了すると、制御はデバッガに戻ります。デバッガでの処理が終わったら、デバッガを閉じるだけです。右上の「X」ボタンか、ツールバーの「停止」ボタンをクリックするだけで、JMPの元のインスタンスに戻ります。まず、ブレークポイントを設定せずに、このループをそのまま実行してみます。ボタンは2つあります。1つは「実行」、もう1つは「ブレークポイントなしで実行」です。今はブレークポイントを設定していないので、どちらも同じ動作をします。もしブレークポイントを設定していて、それを今すぐ使用したい場合は、左端のこのボタンをクリックします。これをクリックすると、プログラムの実行が再起動しない限り終了することを通知されます。再起動はすぐに行います。デバッガを閉じる以外に選択肢はありません。再起動する前に、スクリプトが表示されている下のパネルの「Locals」タブに移動します。デフォルトの名前空間はHereで、これは行で呼び出したものです。スクリプト実行の最後に、aの値は、bの値は、iの値は、ということがわかります。次に、デバッガーを使用して、反復処理の各ステップでa、b、iの値を確認します。「Restart」ボタンをクリックします。行にブレークポイントを追加します。そのためには、行番号のすぐ右をクリックします。ブレークポイントは必要な数だけ設定できます。この単純なスクリプトでは、実際に必要なのは1つだけです。つまり、行を評価してHere名前空間を設定します。次に、forループ内で初期化引数を評価します。テストを評価します。forループの本体、つまりShow関数を評価します。その後、一時停止して「Locals」タブで値を確認します。画面を元に戻しましょう。もう一度「実行」をクリックすると、更新、テストの実行、本体の実行、一時停止が行われ、値が表示されます。テストが失敗してループが終了するまで、これを繰り返します。何も選択していない状態にしておきましょう。左側の「実行」ボタンを使用します。ここでも、ブレークポイントなしで実行したくありません。それでは、これを実行します。評価後、行で停止しているのがわかります。a、b、iの値はそれぞれ と です。反復処理の次のステップを実行するには、もう一度「実行」ボタンをクリックします。すると、a、b、iの値はそれぞれ と です。もう一度実行できます。a、b、iの最終値に到達します。プログラムの実行が終了したというメッセージが表示されます。何か他の操作を行いたい場合は、再開することもできます。「停止」ボタンをクリックします。または、右上隅のXをクリックして閉じることもできます。「停止」ボタンをクリックします。これで、元のJMPセッションに戻ります。さて、製造中の化合物の硬化時間を測定したとしましょう。製造中に5回サンプリングを行い、各サンプルの硬化時間を測定し、各サンプルの硬化時間の分布を確認したいとします。コースジャーナルの「硬化時間データ」セクションをクリックします。スクリプトを作成する際にお勧めすることの一つは、まず対話形式で試してみて、自分がしようとしていることが実現可能かどうかを確認することです。硬化時間から…までのヒストグラムを作成したいので、まずは簡単な例から始めましょう。「分析」メニューから「分布」を選択します。そして、「硬化時間」をY軸に設定します。ここでも、Y軸の役割はYです。「OK」をクリックします。これを見て、「これは素晴らしい。5つの硬化時間分布すべてにまさに必要な設定だ」と思いました。これが私が使いたいプラットフォームです。このレポートを再作成するスクリプトの小さなテンプレートを作成しました。ホームウィンドウに戻って開きます。配布プラットフォームの起動、Yロール、そして文字列としてCure Timeを指定した列関数を含むこのスクリプトで、レポートが再作成されます。このテンプレートに基づいてループを記述します。まずはCure Timeウィンドウを閉じ、スクリプトエディタに戻って内容をクリアし、同じウィンドウを使えるようにします。スクリプトの先頭には「Names Default to Here」と入力します。先ほどと同様に、JMPの自動フォーマット機能を使ってスクリプトをクリーンアップします。forループは引数cで始まります。cに値を代入します。初期化するのはこの変数だけです。カンマを入力します。cが列数より小さいかどうかをテストします。大きなデータテーブルを扱う場合のベストプラクティスとして、ループの外で列数をカウントし、その結果を変数に格納して、その変数をcと比較する列数とするのが良いでしょう。今回は2番目の列から始めるので5列です。合計5列です。毎回カウントし直すのはあまり心配する必要はありません。しかし、ベストプラクティスとしては、この列数を減らすことです。その後にカンマを入力します。更新引数はcと後置インクリメント演算子、2つのプラス記号、そしてもう一つのカンマです。括弧内に「Distribution」と入力し、yと入力して再び括弧を開き、「column」と入力し、最後に括弧内にカウンターのcを入力します。ここで矢印キーで括弧が全て揃っていることを確認します。実は、ここで閉じ括弧を忘れていて、再フォーマットしようとすると、何かが足りないというメッセージが表示されます。つまり、再フォーマットはデバッグを行うための簡単な方法です。セミコロンを入力します。そして、「スクリプトの再フォーマット」ボタンを使ってスクリプトを実行します。スクリプトをそのまま記述すると、硬化時間の各観測値ごとに別々のウィンドウが表示されます。これは、分布プラットフォームを起動しているからです。スクリプトエディタウィンドウに戻ると分かりますが、反復処理の各ステップで分布プラットフォームを再度起動しているからです。分布についてご存知の方は、「分析」メニューに戻り、「分布」を選択して、5つの硬化時間値すべてをYロールに入力します。分布についてご存知の方は、これらすべてを同じウィンドウに表示できることをご存知でしょう。ジャーナルには、Yロールをすべての列名で構築し、同じウィンドウに5つの分布すべてを含む同じレポートを作成するためのスクリプトがあらかじめ用意されています。このスクリプトを実行する前に、すべてのレポートウィンドウを閉じます。メニューバーの「ウィンドウ」から「すべてのレポートを閉じる」を選択します。そしてジャーナルを見つけます。「Cure Time Distributions」というスクリプトをクリックします。デバッガーでこのスクリプトを確認します。各ステップで何が起こっているかは、スクリプトエディタウィンドウではなく、デバッガー環境で確認します。右クリックして「スクリプトのデバッグ」を選択します。デバッガーを起動する方法は複数あることを思い出してください。先ほどの簡単な例と同様に、行にブレークポイントを追加して、反復処理の各ステップで何が起こるかを確認します。また、c変数とyCol変数にウォッチポイントを追加します。では、「ウォッチ」タブに移動します。緑のプラス記号をクリックしてウォッチを追加します。これは、スクリプト内の特定の変数を確認する方法です。ここでは、変数の数はそれほど多くありません。しかし、多くの変数を含む大きなスクリプトがあり、デバッグ中に監視する必要がある変数が少数である場合は、「ウォッチ」タブを使用すると便利です。緑のプラス記号をクリックしてウォッチを追加します。変数「c」と入力して「OK」をクリックします。次に、変数「yCol」にもウォッチを追加します。「OK」をクリックします。スクリプトを実行する前に、スクリプト全体で何が起こっているかを少し説明します。デバッガーを実行するプロセスで、その様子を見てみましょう。最初の行は、yColという変数を作成しています。 yColには、分布プラットフォームのY分析ロールとそれに続く空の括弧が格納されます。これは、ループ処理でYロールの後の括弧に列名を追加することで式を構築するためです。Exprで引用符で囲んでいるのは、単にyColと書いて、その後に括弧を付けて値yを代入しようとすると、JMPがこれを定義済みの変数として認識しないためエラーが発生するためです。関数としても認識されません。そのため、JMPが評価しようとすることなく、このリテラル値をyColに格納したいのです。これが行の処理です。行から行まではforループで、列から開始し、列がなくなるまで繰り返します。繰り返しますが、実稼働レベルのスクリプトでは、特にデータテーブルが大きい場合は、ループの外側で列数をカウントし、その値を変数に格納する必要があります。forループの本体は、列cを単純に追加するだけです。つまり、最初の列cをyColに格納された式に追加します。 Insert Into は最初の引数を評価しません。そのため、yCol 変数に対して特別な処理は必要ありません。単に変数を参照し、操作を実行します。この場合は、y の後の括弧内に列を追加します。Show 関数は、各ステップで何が起こっているかを確認するための説明用です。この部分は、デバッガを使用していなければログに表示されます。つまり、値を監視し、これは Show 関数を使用するのと同じです。Update を実行します。テストを実行し、c がまだ列数以下であると仮定して、次の列を yCol に挿入します。ループが完了すると、つまり列がなくなると、最後のコード行が作成されます。これについて、詳しく説明します。Insert 関数を使用して、分布式を変更します。分布式は JMP に組み込まれているプラットフォーム起動であるため、Insert Into ではなく Insert を使用します。ユーザーは分布式自体を変更することはできません。分布式を使用する式を変更することはできます。そこで挿入関数を使います。そして、分布をExpr関数で囲むことで、JMPが分布を評価しないようにします。もしこのコード行のこの部分を実行したとしたら(強調しておきますが)、JMPは「Yロールに必要な引数が指定されていません」と警告します。そのため、分布プラットフォームの起動が表示されます。そしてユーザーは列を入力しますが、実際には入力しません。これではスクリプトの目的が達成されませんよね?これが最初の引数です。2番目の引数としてyColを入力すると、JMPはそれを評価しようとします。そして、ループ処理後にどうなるか見てみましょう。しかし、JMPは括弧で囲まれた大文字のYと一連の列名だけしか認識しません。これはJMPにとって扱いにくいものです。変数名としても関数としても認識されないのです。そこでName Exprを使うと、yColに格納されている値を評価することなしに、その値を見ることができます。 yColに格納されている未評価の式は、分布の後に括弧内に格納されます。この処理を実行すると、すべての列のYロールを持つ分布は引用符で囲まれたままになるので、全体をEvalで囲みます。JMPの通常のインスタンスに戻って、もう少し細かく分析することができます。ウォッチポイントがあります。現在、変数は未定義です。これが値として表示されます。最初のブレークポイントまで実行してみましょう。更新前の最初の実行後、cには次の値が格納されます。そして、yColには、空の括弧付きのY列ではなく、「硬化時間」列が格納されます。背景に表示されている小さなテンプレートを思い出してください。デバッガがアクティブなため、テンプレートに移動することはできませんが、これが1列のみの分布を生成します。次の反復処理をもう一度実行します。cはと等しくなり、y分析ロールは2つの硬化時間列を開始します。もう一度実行します。これで3つの列があります。これを続けることができます。バックグラウンドのログを見ると、Show関数によって結果が表示されているのがわかります。ループを終了するまでこれを続けます。そして、5つの硬化時間列すべてが保存されます。これはJMPの通常のセッションのログで確認すると分かりやすいのですが、これらはすべてyColに保存されています。これでプログラムの実行は終了です。デバッガで「停止」をクリックします。これで最後の行が評価されました。5つのヒストグラムを含む硬化時間分布が同じウィンドウに表示されます。では、スクリプトエディタウィンドウに戻ってこの行について簡単に説明しましょう。式を内側から外側へと構築する方法を考えることが重要だと思うからです。では、これを実行していくつかエラーを発生させ、なぜこのように記述したのかを明確にしてみましょう。そのため、事前に記述した行をコメントアウトしておきます。デバッガーインスタンスで説明した内容に戻りますが、「Insert」と入力します。スクリプト作成に慣れていない方は、「Insert」と「Insert Into」をいつ使うべきか、少し試行錯誤する必要があるかもしれません。繰り返しますが、今回のケースでは、特定の分析ロール、または分析ロール内の特定の列を持つプラットフォームを起動する必要があります。しかし、プラットフォームを変更することはできません。変更できるのはユーザーが作成した変数のみです。これらはL値と呼ばれます。では、これを試してみましょう。起動時に「Distribution」と入力し、括弧を開いて括弧を閉じ、カンマを入力して、yColを挿入してみます。繰り返しますが、yColに格納されている値と、分布後の括弧の値を取得するという単純な考え方です。では、この1行を実行するとどうなるか見てみましょう。[エラーチャイム] エラーが発生します。「名前が解決されていません。すべての列のYのアクセスまたは評価でYが見つかりました。」これを無視すると、JMPがこれを評価しようとしただけになります。評価できませんでした。エラーが発生し、完了しませんでした。繰り返しますが、保存された式や引用符で囲まれた式を評価せずに取得する必要がある場合に使用する関数はName Exprです。そこで、開き括弧で囲みます。yColをName Exprで囲みます。これをテストしてみましょう。何が起こるでしょうか。yColを実行すると、先ほどエラーが表示されました。Name Expr yColを実行すると、ログを見ると、サイズを変更しようとしていることがわかります。ログを見ると、JMPはこれに対してエラーを出力しません。引用符で囲まれた式を返すだけです。さて、行を実行しようとすると、ああ、今度は、JMPはyCol変数に問題はありませんでした。しかし、今度は必要な値のない分布を検出しました。ですから、JMPにこのプラットフォームを起動させたくありません。これをキャンセルします。分布をExprで囲むことで、JMPはそれを全く評価しないようにします。繰り返しますが、テストのためにこれをハイライト表示して実行しても問題ありません。これを実行すると、ログを見ると、実行したコード行があります。これが結果です。Yロールを持つ分布と、それに含まれるすべての列です。最後に、行にあるように、この行全体をEval関数で囲みます。これは1つの方法に過ぎませんが、行全体をEval関数で囲みます。これを実行すると、分布レポートがすべて表示された別の分布ウィンドウが表示されます。開発中にいくつかエラーが発生した例を挙げてみました。そうすることで、なぜこのような書き方をするのかを理解していただけると思います。もう1つ付け加えておきたいのは、一般的に推奨されている方法です。最初の硬化時間分布を作成したとき、覚えていると思いますが、「分析」メニューの「分布」で「硬化時間」をYロールに設定し、「OK」をクリックしただけです。JMPが自動生成するスクリプトをそのまま使用し、今回のループを作成する際に使用することをお勧めします。分布でこれをしなかった唯一の理由は、Y分析ロールのみを持つ構文が古い構文だからです。分布の横にある赤い三角形をクリックして「スクリプトをスクリプトウィンドウに保存」を選択すると、新しい構文では各列ごとに連続分布か名義分布かを指定できます。つまり、古い構文よりもループ内のスクリプト記述が少し増えるだけです。古い構文でも問題なく動作します。しかし、この新しい構文を使用することをお勧めします。ループが少し複雑になるだけです。しかし、ほとんどのプラットフォームでは、JMPが自動生成するスクリプトを使用すれば十分でしょう。このスクリプトウィンドウを閉じます。そして、インタラクティブな処理の例をもう一つ見てみましょう。今回は、そのスクリプトをキャプチャします。ただし、ループは既に作成済みです。5つの硬化時間の値すべての管理図を確認したいとします。そこで、インタラクティブな処理を開始するには、「分析」メニューに移動します。「品質とプロセス」の下にある「管理図ビルダー」を選択します。「日」をサブグループの役割に、「硬化時間」をYの役割に割り当てます。すると、管理図ビルダーが自動的に硬化時間の個別の測定値と移動範囲チャートを作成します。これが開始点です。「完了」をクリックしてコントロールパネルを非表示にします。次に、「管理図ビルダー」の横にある赤い三角形をクリックし、「スクリプトをスクリプトウィンドウに保存」をクリックします。これで、このスクリプトエディタウィンドウに、結果を再現する管理図ビルダーが表示されます。ここで、事前に作成したスクリプトと一致させるために、サイズを設定する行を削除します。もちろん、これは必須ではありません。デモ用に簡略化しているだけです。プラットフォームの起動画面には管理図ビルダーが表示されています。そしていくつかオプションがあります。ブール値を使ってコントロールパネルを非表示にしています。機能を表示していません。そして変数ロールがあります。変数ロールにはサブグループがあります。これはすべての硬化時間の値で同じになります。そして、硬化時間(この場合は硬化時間)のYロールがあります。実際に必要なのは3つの要素を構築することです。硬化時間列のY分析ロールを構築し、Yロールにすべての硬化時間列を追加して変数部分を構築します。そして、その変数部分を管理図ビルダーの起動画面に取り込みます。では、ジャーナルに戻って「硬化時間管理図」をクリックしましょう。繰り返しますが、Y分析ロールは3つの要素で構成されています。これはまさに私たちが行ったことと同じです。これらの線は、分布で見たものと全く同じです。変数の命名規則を変えています。次に、変数部分を構築します。挿入関数を使用します。サブグループ「Day」の変数があり、これはすべての硬化時間の値で同じになります。しかし、JMPに「変数」という単語を評価しさせたくありません。エラーが発生します。そこでExprを使用します。そして、分布のスクリプトと同様に、yExprに格納されている列のリストを取得し、それを変数部分に追加します。そして、このスクリプトでは、変数部分を除いた管理図ビルダーの基本テンプレートを作成し、それを変数ccExprに格納します。最後に、変数行を追加します。このコードをバックグラウンドで確認すると、この変数行が管理図ビルダーの起動時に追加されます。この場合、これらは既に定義済みの引用符で囲まれた式なので、両方ともName Exprを使用しました。このInsert Functionをevalで囲むのではなく、結果を独自の変数に格納します。そしてスクリプト内でccを使用して、構築された式を評価します。さあ、デバッガーに取り込んでみましょう。右クリックして「デバッグ」を選択します。「ウォッチ」タブに移動します。他のスクリプトの現在のウォッチ変数を削除したいので、すべてのウォッチを削除するボタンをクリックします。次に、このスクリプト内の4つの変数に4つのウォッチを追加します。緑のプラス記号をクリックします。まず「yExpr」と入力して「OK」をクリックします。もう一度緑のプラス記号をクリックし、「varExpr」を追加します。大文字で入力しても問題ありませんが、スクリプト内のテキストと一貫性を持たせたいので、「OK」をクリックします。 ccExprを追加します。「OK」をクリックします。最後に、ccを追加して「OK」をクリックします。3つの異なる場所で停止させたいので、ブレークポイントを3つ設定します。最初のブレークポイントは行です。これにより、反復処理の各ステップで何が起こっているかを確認できます。次のブレークポイントは行です。ここで一時停止し、varExprに何が格納されているかを確認します。最後に、ccに何が格納されているかを確認するために、行にブレークポイントを設定します。これを閉じたら、それが評価されます。「ステップオーバー」ボタンを使ってデバッガーを実行します。これをクリックします。行が評価され、ループに到達します。下の「ウォッチ」タブを見ると、yExprに現在何が格納されているかを確認できます。もう一度「ステップオーバー」をクリックすると、最初のブレークポイントに移動します。3回目に「ステップオーバー」をクリックすると、yExprに列Cure Timeが含まれていることがわかります。もう一度「ステップオーバー」をクリックしてブレークポイントまで移動します。もう一度クリックします。これで、硬化時間をYロールに挿入しました。forループが完了するまでこれを続けます。これを確認すると、硬化時間の5つの列すべてがYロールに含まれていることがわかります。行はvarExprを定義します。これで、サブグループDayを持つ変数と、それらの列すべてを含むYロールが作成されました。もう一度「ステップオーバー」をクリックすると、ccExprを定義した場所に移動します。「ウォッチ」タブでも確認できますが、これは管理図ビルダーの起動を保存しているだけで、重要な部分が欠けています。行は、すべてをまとめる場所です。もう一度「ステップオーバー」をクリックします。これで、管理図ビルダー、コントロールパネルの表示などにvarExprに保存された値が追加されていることを確認できます。もう一度「ステップオーバー」をクリックします。プログラムの実行が終了します。「停止」をクリックします。通常の状態に戻ります。 JMPのセッションでは、硬化時間などの個々の測定値と移動範囲チャートが表示されています。これらの例では、For関数の使用、Expr関数とName Expr関数の挿入機能の使用、そしてこれらの単純なコンテキストでのデバッガの使用方法を確認しています。ジャーナルに戻り、スクリプトウィンドウへの変更を保存せずに「すべて削除」または「すべて保存」をクリックします。これでこのデモは終了です。