キー押下でプログラムをコントロールしたい - 逆引き Casio Basic

逆引き Casio Basic
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します

追記修正 2017/01/03
[fx-5800P / fx-9860GII / fx-CG20]

プログラムの一旦停止や実行をキー押下でコントロールしたい。



プログラムは、コードの上から下へ順に実行されるものだ、と理解することは基本だ。逆にプログラムを一旦停止するには、一旦停止の機能をコードとして書く必要がある。

最も簡単な方法は、Casio Basic に備わっている Casio 特有の旧来からの命令の1つ  (出力)命令を使うことだ。
命令には、一旦停止の機能も備わっているので、プログラムを一旦停止したいところで使うことができる。但し、一旦停止を解除するには [EXE] を押す必要があり、他のキーは使えない。なお  命令は出力命令なので空白を含めて何か出力させるようにコードを書く必要がある。何も出力せずに一旦停止のみ行うには ""◢ とすれば良い。

命令を含んた旧来の命令の使いこなしは、Casio Basic 入門38 を参照



Basic コマンドを使うと、キーを押した時のプログラムの動作のコントロールを、より自由度高く行える。

汎用性のあるコードとして、
  • 処理を一旦停止させ、何かキーを押している間に処理を先に進める方法
  • 処理を一旦停止させ、何かキーを押すたびに(押している時間に係わらず) 処理を1回だけ実行する方法
  • ◢ 命令と同じ動作を、Basic コマンドで実現する方法
  • ◢ 命令とほぼ同じ機能だが、[EXE] キー以外で一旦停止を楷書する方法
  • 処理を一旦停止させ、何かキーを押している間だけ処理を実行する方法
を紹介する。基本的にキーが押されたことの検出とキーが離されたことの検出、それらの組み合わせで実現する方法だ。具体的には While / WhileEnd ループと Getkey を使って2~4行のコードで実現できる。

⇒ Casio Basic コマンドリファレンス: Whileループ


先ず、以下のプログラムを作り、これを元にそれぞれの課題を実現する方法を付加してゆく。
以下のプログラムは、fx-5800P, fx-9860GII, fx-CG20 のすべてに共通して使える。

ファイル名: C-UP
0→C
While 1
Isz C
Locate 1,1,C
WhileEnd


変数 C0 で初期化し、
Isz CC を1つ増やして Locate 1,1,C で増やした C の値を表示する。
While 1 / WhileEnd による無限ループでこの処理を繰り返す。

プログラム C-UP を実行すると、数字がカウントアップされ、[AC] キーで強制終了する。

==========

何かキーを押している時だけカウントアップを実行し、キーを離したら一旦停止するように、C-UP を改造する。

ファイル名: C-UP1
0→C
While 1
Isz C
Locate 1,1,C
While Getkey=0
WhileEnd

WhileEnd


プログラム C-UP に赤文字の2行を追加した。
 While Getkey=0
 WhileEnd

は、いずれのキーも押されていない時に処理を先に進めない (一旦停止) 機能を実現する。プログラムを一旦停止し、何かキー([AC] キーを除く)を押したら一旦停止を解除する。

さらにキーを押している間カウントアップ処理が継続され、キーを離したら処理が一旦停止する。
なお、カウントアップを1回だけ行うには、キーを押している時間をできるだけ短くする必要がある。言い換えればキーの長押しは、キーを複数回押したのと同じと判定される、つまりキ-リピートを検出する。

ここで、
 While Getkey=0
 WhileEnd

の動作を詳しく見てみる。While Getkey=0 は、While ループの [ループ継続条件]Getkey=0 になっている。
Getkey=0 は、何もキーが押されていないことを意味するから、何もキーが押されていないときこのループが継続する。つまりループがグルグル回っていて、プログラムの処理は先に進まないから、ここでプログラムが一旦停止しているように見える(実際はループ処理が続くのでプログラムは停止していない)。

Getkey は、それが実行された時に押されているキーを判別するコマンドで、押されているキーごとの固有のキーコードを返し、キーが押されていない時は 0 を返す。「返す」というのは、Getkey が その値になっていると思って良い。キーが押されていない場合は 0 になる。
従って、Getkey=0 は、いずれのキーも押されていない条件を示す。

==========

次に、C-UP1 を改造して、キーを押す時間にかかわらず、1回押したらカウントアップを1回だけ行うようにする。

ファイル名: C-UP2
0→C
While 1
Isz C
Locate 1,1,C
While Getkey
WhileEnd

While Getkey=0
WhileEnd

WhileEnd


C-UP1 に青文字の
 While Getkey
 WhileEnd

の2行を追加した。

ここで、
 While Getkey
 WhileEnd
は、何かキーが押されている限りこの2行のループ処理が続き、キーが離された時にこのループを抜ける。つまりキーリピートを抑制する機能を実現する。

Getkey は、このコマンドが実行された時に何かキーが押されていたら 0 以外のキーコードを返す。「返す」とは、Getkey その値であると思って良い。
While Getkey は、While のループ継続条件が Getkey になっていて、何かキーが押されていたら Getkey が 0 以外の値になるから、この時ループは継続され、処理は先へ進まない。キーが離されると、Getkey は 0 になるからループから抜けて、処理は先へ進む。

==========

C-UP2 を改造して、 命令と同じ機能を実現してみる。

つまり、

0→C
While 1
Isz C
Locate 1,1,C◢

WhileEnd

と同じ機能を実現する。


ファイル名: C-UP3
0→C
While 1
Isz C
Locate 1,1,C
While Getkey
WhileEnd

While Getkey≠47
WhileEnd

WhileEnd


C-UP2 の赤文字の部分を変更した。

ここで、、
 While Getkey≠47
 WhileEnd
このループは、キーコード 47 のキー、つまり [EXE] キーが押されない限り、繰り返しを継続して、処理が先に進まない。[EXE] キーが押される時のみ、処理が先へ進む。

命令を使う時は、キーリピートは無いので、
 While Getkey
 WhileEnd
によりキーリピートを抑制している。

この例は、キーコード47の [EXE] キーで処理を1回進めるものだが、他のキーに対応するキーコードを使えば、好きなキーコードで処理を1回進めることができる。汎用の高い方法だ。

==========

プログラム C-UP を改造して、何かキーが押されている時だけ、カウントアップを停止させるようにする。

ファイル名: C-UP4
0→C
While 1
Isz C
Locate 1,1,C
While Getkey
WhileEnd

WhileEnd


このコードで、
 While Getkey
 WhileEnd

は、何かキーが押されている限り、この2行のループが継続することは、上で紹介した。キーが離されている時は、このループは継続しない。

もし、この Getkey が実行されるとき、キーが押されていない場合、[ループ継続条件] である Getkey は 0 なので、ループに1度も入ることなくループを抜ける。







応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ



   



keywords: CasioBasic、プログラミング入門プログラム関数電卓



テーマ : プログラム関数電卓
ジャンル : コンピュータ

キー長押しでメニュー選択させたい - 逆引き Casio Basic

逆引き Casio Basic
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します

修正:2015/10/13
[fx-5800P / fx-9860GII / fx-CG20]

メニュー選択機能で、同じキーの長押しにより2つ目の選択肢を与えたい。



1つのキーを普通に押すだけでなく、同じキーの長押しで別の動作ができれば、1つのキーに2つの異なるメニュー機能を与えられる。これによって、プログラム電卓の限られた広さの画面を有効に使える。

そこで、定石として使える汎用性の高いコードを紹介する。

以下のようなサンプルプログラムを作る。

[1] キーと [2] キーには、普通に押した時と長押しで異なる処理を割り当て、
[3] キーには、普通に押した時のみ処理を割り当て、
[4] キーには、長押しした時のみに処理を割り当てる

このサンプルプログラムは、テンキーでメニューを選択させたい - 逆引き Casio Basic のサンプルプログラムを拡張したものだ。


画面に、

1:ONE      2:TWO
3-THREE  4.FOUR


と表示させる。

数字の後ろに : があれば普通に押す時と長押しの両方に対応し、数字の後ろが . になっていれば長押しのみの対応、数字の後ろが - なら普通に押すことのみに対応する...と意味を持たせてある。

ここでは、汎用性のある fx-5800P 用のコードを示す。fx-9860GII や fx-CG20 に対応するには、後述するように4カ所のキーコードの記述を変更するだけで良い。

サンプルプログラムの動作仕様;
  • [1] を押せば 3行目に HIT [1] と表示
  • [2] を押せば 3行目に HIT [2] と表示
  • [3] を押せば 3行目に HIT [3] と表示
  • [1] の長押しで、3行目に LONG PUSH [1] と表示
  • [2] の長押しで、3行目に LONC PUSH [2] と表示 
  • [4] の長押しで、3行目に LONG PUSH [4] と表示
  • 3行目の表示と同時に、4行目右端にガイド表示 <EXE> を示し、[EXE] で再入力できることを示す
  • [1][4] 以外のキーを押したり、[1][2][4] 以外の長押しでも誤動作しない。

サンプルコード
Locate 1,1,"1:ONE"
Locate 9,1,"2:TWO"
Locate 1,2,"3-THREE"
Locate 9,2,"4.FOUR"

While 1

0→M
Do
Getkey→K
LpWhile K=0
K=35⇒1→M
K=36⇒2→M
K=37⇒3→M

0→C
While Getkey=35
Isz C:C=9⇒Break
WhileEnd
C=9⇒11→M

0→C
While Getkey=36
Isz C:C=9⇒ Break
WhileEnd
C=9⇒12→M

0→C
While Getkey=21
Isz C:C=9⇒Break
WhileEnd
C=9⇒14→M


If M=1
Then Locate 1,3,"HIT [1]"
Else If M=2
Then Locate 1,3,"HIT [2]"
Else If M=3
Then Locate 1,3,"HIT [3]"
Else If M=11
Then Locate 1,3,"LONG PUSH [1]"
Else If M=12
Then Locate 1,3,"LONG PUSH [2]"
Else If M=14
Then Locate 1,3,"LONG PUSH [4]"
IfEnd:IfEnd
IfEnd:IfEnd
IfEnd:IfEnd


If M
Then Locate 12,4,"<EXE>"◢
Locate 1,3,"       " (スペース13個
Locate 12,4,"   " (スペース5個)
IfEnd

WhileEnd



定石として使えるのは、赤文字のブロック紫文字のブロック、そして青文字のブロックだ。


サンプルプログラムをブロック構造で示すと、

 [初期表示]

 While 1

   [メニュー選択]

   [キー長押しによるメニュー選択]

   [選択したメニュー番号に応じた分岐処理]

   [後処理]

 WhileEnd


このように構造化され、初期表示を行ったのち、While 1 / WhileEnd で構成された無限ループ内で、メニュー選択→分岐処理→後処理 が繰り返される。

==========

メニュー選択のためのキー入力は、赤文字の部分が定石として使える。

Do
Getkey→K
LpWhile K=0


は、何もキー入力が無い時はこのループをグルグルまわっていて、何かキーが押された時に押されたキーのキーコードを変数 K に格納してからこのループを抜けて、次の処理へ進む。この部分は、テンキー以外のキー入力にも対応できる。

このループに続く以下の部分、

K=35⇒1→M
K=36⇒2→M
K=37⇒3→M


ここで、押されたキーのキーコードに応じて、メニュー変数 M にメニュー番号を格納する。

実は、赤文字の部分の冒頭にある 0→M が極めて重要だ。今回はテンキー [1][3]、つまりメニュー番号が 1 ~ 3 のみで、それ以外のキーを押しても、誤動作しないようにしたい。そこで、操作上メニュー番号が 0 になることが無いので、最初にメニュー変数 M に 0 を入れておく。そしてメニュー選択により M が 1、2、3 のいずれかになる。つまり、変数 M は、0 ~ 3 のいずれかのア値になって、絶対に他の値にならないことを保証しているわけた。そのため、0→M は誤動作防止のために極め重要になる。

長押しに関して、記述の追加が無いことから、汎用性のあるコードだと分かってもらえるだろう。

==========

次に、紫文字のブロックでは、特定キー長押しの検出とメニュー番号への割り振りを行っている。

0→C
While Getkley=35
Isz C:C=9⇒Break
WhileEnd

C=9⇒11→M

ここで、赤文字の 3511 以外は、同じ記述を3回繰り返している。この場合は、[1] の長押しの検出と、[1] 長押しに対応するメニュー番号を 11 として、メニュー変数 M に 11 を格納している。

While Getkey=35
Isz C:C=9⇒Break
WhileEnd


これは、Getkey が実行される時にキーコード 35 に対応する [1] キーが押されていれば、While ループを回るようにしている。
ループを1回回ると、Isz C でカウンタ変数 C を1つ増やす。カウンタ変数 C は、While ループに入る前に 0→C で 0 に初期化されている。

そして、C=9 になったとき、つまりループを9回まわると、C=9⇒Break によりループから強制的に抜けて、次の処理へ続く。
この次の処理が、C=9⇒11→M になっていて、きちんとループを9回まわって抜けてきた場合のみメニュー変数 M に 11 を格納する。
普通に [1] を押した時のメニュー番号 M が 1 なので、長押しは 10 を足して 11 としているが、ここは他と重複しなければ何でも良い。

ところで、Break コマンドは、それが記述されているループから強制脱出する。
Casio Basic コマンドリファレンス: Break 参照

2カ所ある C=9 の部分が、ループを抜けるまでに回る回数を示していて、長押しと判定されるための時間(=ループ回数)を指定している。この値を大きくすれば、長押しとして判定される時間が長くなり、小さくすればチョット長押しするだけで長押しとして判定される。

fx-5800P だと C=9 くらいが丁度良いと思って 9 にしてるが、9 である必要はない。fx-9860GII で使う場合は、処理速度が速いので 15 くらい丁度良いかも知れない。


キーコード 36 の [2] キーの長押し判定とメニュー番号指定(M=12とする)は、以下のようになる。

0→C
While Getkey=36
Isz C:C=9⇒Break
WhileEnd
C=9⇒12→M


キーコード 21 の [4] キーの長押し判定とメニュー番号指定(M=14とする)は、以下のようになる。

0→C
While Getkey=21
Isz C:C=9⇒Break
WhileEnd
C=9⇒14→M


このように、汎用性の高いコードになっている。

==========

さて、得られらたメニュー番号に応じて、分岐処理を行う青文字の部分は、上のメニュー選択部と対になる重要な骨組みだ。
If / Else / IfEnd を使っている。 詳しくは、Casio Basic コマンドリファレンス: If 文 を参照。

メニュー変数 M が 1, 2, 3, 11, 12, 14 の6通りで分岐処理を行っている。

If M=1
Then Locate 1,3,"HIT [1]"
Else If M=2
Then Locate 1,3,"HIT [2]"
Else If M=3
Then Locate 1,3,"HIT [3]"
Else If M=11
Then Locate 1,3,"LONG PUSH [1]"
Else If M=12
Then Locate 1,3,"LONG PUSH [2]"
Else If M=14
Then Locate 1,3,"LONG PUSH [4]"
IfEnd:IfEnd
IfEnd:IfEnd
IfEnd:IfEnd



この分岐処理を行うブロックで、If 文での分岐にキーコードを使わす、一旦代入したメニュー変数 M を使うには理由がある。
  • 理由1: 上のfx-5800P 用のコードを fx-9860GII へ移植する場合、赤文字部のメニュー選択部の一部を変更するだけで、青文字の分岐処理のブロックを変更する必要が無い。
  • 理由2: テンキー選択を多い場合や、テンキー以外のキー入力に対応して、分岐処理を増えた場合は、メニュー変数で整理する方がプログラムの可読性が増して、分かりやすくバグが入り込みにくい。
  • 理由3: 長押し検出による機能追加にも、対応するメニュー番号を使って拡張できる。

fx-9860GII / fx-CG20 への対応

なお、上のコードを fx-9860GII 用に変更する場合は、赤文字部を以下のように変更するだけば良い。

0→M
Do
Getkey→K
LpWhile K=0
K=72⇒1→M
K=62⇒2→M
K=52⇒3→M


0→C
While Getkey=72
Isz C:C=9⇒Break
WhileEnd
C=9⇒11→M

0→C
While Getkey=62
Isz C:C=9⇒ Break
WhileEnd
C=9⇒12→M

0→C
While Getkey=73
Isz C:C=9⇒Break
WhileEnd
C=9⇒14→M


変更箇所は、赤文字のキーコードのみにな、プログラムの他の部分を変更する必要がない。

==========

話を元に戻して...

青文字のブロックに続く後処理は、

If M
Then Locate 12,4,"<EXE>"◢
Locate 1,3,"    " (スペース7個)
Locate 12,4,"   " (スペース5個)
IfEnd


となっている。

[EXE] で元に戻るための使用方法の表示 <EXE> を行って、 命令で一旦停止。[EXE] で一旦停止を解除したら、全ての表示をスペースで上書き消去している。なお、これら後処理は、有効なメニュー番号が選択された時のみ実行する。
有効なメニュー番号は 0  以外の整数なので、M が 0 でない時のみ実行するために、If M / IfEnd の中に記述している。ここでも、最初に変数 M を 0 で初期化していることが活きてくる。

If [分岐条件] / IfEnd の書式で、[分岐条件] は、それが 0 以外なら If 内の処理(If と IfEnd の間の処理)へ分岐する。0 なら処理を行わず、次へ進む。従って、If M という記述が可能になる。

詳しくは、Casio Basic コマンドリファレンス: If 文 参照。





応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ



   



keywords: CasioBasic、プログラミング入門プログラム関数電卓

リンク集 | ブログ内マップ



テーマ : プログラム関数電卓
ジャンル : コンピュータ

テンキーでメニュー選択させたい - 逆引き Casio Basic

逆引き Casio Basic
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します

修正:2016/10/12
[fx-5800P / fx-9860GII / fx-CG20]

テンキーでメニュー選択するプログラムを作りたい。



画面に、

1:ONE      2:TWO
3:THREE


と表示し、テンキー [1][2] か [3] を押して、それぞれに対応した異なる処理を行うサンプルプログラムを作る。

ここでは、汎用性のある fx-5800P 用のコードを示す。fx-9860GII や fx-CG20 に対応するには、後述するように3カ所のキーコードの記述を変更するだけで良い。

サンプルプログラムの動作仕様;
  • [1] を押せば 3行目に HIT [1] と表示
  • [2] を押せば 3行目に HIT [2] と表示
  • [3] を押せば 3行目に HIT [3] と表示
  • 3行目の表示と同時に、4行目右端にガイド表示 <EXE> を示し、[EXE] で再入力できることを示す
  • [1][3] 以外のキーを押しても誤動作しない
サンプルコード
Locate 1,1,"1:ONE"
Locate 9,1,"2:TWO"
Locate 1,2,"3:THREE"

While 1

0→M
Do
Getkey→K
LpWhile K=0
K=35⇒1→M
K=36⇒2→M
K=37⇒3→M

If M=1
Then Locate 1,3,"HIT [1]"
Else If M=2
Then Locate 1,3,"HIT [2]"
Else If M=3
Then Locate 1,3,"HIT [3]"
IfEnd:IfEnd
IfEnd


If M
Then Locate 12,4,"<EXE>"◢
Locate 1,3,"    " (スペース7個)
Locate 12,4,"   " (スペース5個)
IfEnd

WhileEnd



定石として使えるのは、赤文字のブロック青文字のブロックだ。


サンプルプログラムをブロック構造で示すと、

 [初期表示]

 While 1

   [メニュー選択]

   [選択したメニュー番号に応じた分岐処理]


   [後処理]

 WhileEnd


このように構造化され、初期表示を行ったのち、While 1 / WhileEnd で構成された無限ループ内で、メニュー選択→分岐処理→後処理 が繰り返される。

==========

メニュー選択のためのキー入力は、赤文字の部分が定石として使える。

Do
Getkey→K
LpWhile K=0


は、何もキー入力が無い時はこのループをグルグルまわっていて、何かキーが押された時に押されたキーのキーコードを変数 K に格納してからこのループを抜けて、次の処理へ進む。この部分は、テンキー以外のキー入力にも対応できる。

このループに続く以下の部分、

K=35⇒1→M
K=36⇒2→M
K=37⇒3→M


ここで、押されたキーのキーコードに応じて、メニュー変数 M にメニュー番号を格納する。

実は、赤文字の部分の冒頭にある 0→M が極めて重要だ。今回はテンキー [1][3]、つまりメニュー番号が 1 ~ 3 のみで、それ以外のキーを押しても、誤動作しないようにしたい。そこで、操作上メニュー番号が 0 になることが無いので、最初にメニュー変数 M に 0 を入れておく。そしてメニュー選択により M が 1、2、3 のいずれかになる。つまり、変数 M は、必ず 0 ~ 3 のいずれかの値になって、絶対に他の値にならないことを保証している。そのため、0→M は誤動作防止のために極め重要になる。

==========

次に、得られらたメニュー番号に応じて、分岐処理を行う青文字の部分は、上のメニュー選択部と対になる重要な骨組みだ。
If / Else / IfEnd を使っている。 詳しくは、Casio Basic コマンドリファレンス: If 文 を参照。

メニュー変数 M が 1, 2, 3 の時に分岐処理を行っている。

If M=1
Then Locate 1,3,"HIT [1]"
Else If M=2
Then Locate 1,3,"HIT [2]"
Else If M=3
Then Locate 1,3,"HIT [3]"
IfEnd:IfEnd
IfEnd


この分岐処理を行うブロックで、If 文での分岐にキーコードを使わす、一旦代入したメニュー変数 M を使うには理由がある。
  • 理由1: 上のfx-5800P 用のコードを fx-9860GII へ移植する場合、赤文字部のメニュー選択部の一部を変更するだけで、青文字の分岐処理のブロックを変更する必要が無い。
  • 理由2: テンキー選択を多い場合や、テンキー以外のキー入力に対応して、分岐処理を増えた場合は、メニュー変数で整理する方がプログラムの可読性が増して、分かりやすくバグが入り込みにくい。

fx-9860GII / fx-CG20 への対応


上のコードを fx-9860GII や fx-CG20 向けに変更する場合は、赤文字部を以下のように変更すれば良い。

0→M
Do
Getkey→K
LpWhile K=0
K=72⇒1→M
K=62⇒2→M
K=52⇒3→M


変更箇所は、赤文字のキーコードのみにな、プログラムの他の部分を変更する必要がない。

==========

青文字のブロックに続く後処理は、

If M
Then Locate 12,4,"<EXE>"◢
Locate 1,3,"    " (スペース7個)
Locate 12,4,"   " (スペース5個)
IfEnd


となっている。

[EXE] で元に戻るための外と表示 <EXE> を行って、 命令で一旦停止。[EXE] で一旦停止を解除したら、全ての表示をスペースで上書き消去している。なお、これら後処理は、有効なメニュー番号が選択された時のみ実行する。
有効なメニュー番号は 0  以外の整数なので、M が 0 でない時のみ実行するために、If M / IfEnd の中に記述している。ここでも、最初に変数 M を 0 で初期化していることが活きてくる。

If [分岐条件] / IfEnd の書式で、[分岐条件] は、それが 0 以外なら If 内の処理(If と IfEnd の間の処理)へ分岐する。0 なら処理を行わず、次へ進む。従って、If M という記述が可能になる。

詳しくは、Casio Basic コマンドリファレンス: If 文 参照。





応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ



   



keywords: CasioBasic、プログラミング入門プログラム関数電卓

リンク集 | ブログ内マップ



テーマ : プログラム関数電卓
ジャンル : コンピュータ

◢ 命令を Basic コマンドに置き換えたい

逆引き Casio Basic
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します

2015/10/11
[fx-5800P / fx-9860GII / fx-CG20]

◢ 命令を Basic コマンドに置き換えて、fx-5800P と fx-9860GII 互換のコードを書く。



Casio Basic の Basic コマンドは、fx-5800P と fx-9860GII や fx-CG20 との間でほぼ互換性がある。しかし、意外にも旧来の命令は、詳細動作において互換性が得られない。

fx-9860GII への移植 - 厄介な旧来の命令 参照
※ fx-CG20 でも同じ問題がある.

そこで、例えば (出力)命令の機能を Basic コマンドで置き換えられれば、互換性の問題を回避できる。

置き換える Basic コード:

fx-5800P 用
While Getkey
WhileEnd
While Getley≠47
WhileEnd


fx-9860GII / fx-CG20 用
While Getkey
WhileEnd
While Getkey≠31
WhileEnd


※異なるのはキーコードのみ.

==========

実際に使ってみる;

0→C
While 1
Isz C
Locate 1,1,C◢

WhileEnd

と同じ機能を fx-5800P で実現する。

0→C
While 1
Isz C
Locate 1,1,C
While Getkey
WhileEnd

While Getkey≠47
WhileEnd

WhileEnd


==========

While Getkey≠47
WhileEnd


このループは、キーコード 47 のキー、つまり [EXE] キーが押されない限り、繰り返しを継続して、処理が先に進まない。[EXE] キーが押される時のみ、処理が先へ進む。

命令を使う時は、[EXE] キーを1回押せば、そして [EXE] を長押ししても、Locate 1,1,C を1回だけ実行する(キーリピートはしない)ので、

While Getkey
WhileEnd


により キーリピートを抑制している。

キー押下でプログラムをコントロールしたい - 逆引き Casio Basic



fx-9860GII / fx-CG20 への対応

上記のコードで、キーコード 47 を 31 に書き換えるだけで良い。




応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ



   



keywords: CasioBasic、プログラミング入門プログラム関数電卓

リンク集 | ブログ内マップ



テーマ : プログラム関数電卓
ジャンル : コンピュータ

逆引き Casio Basic - 目次 -

逆引き Casio Basic

新しい記事の公開に合わせて随時追記・修正します
更新: 2015/10/12

逆引き Casio Basic では、やりたいことに対して、その方法をサンプルプログラムと共に紹介してゆく。

新世代 Casio Basic を搭載した fx-5800P と fx-9860GII を前提にするが、新世代 Casio Basic  を搭載した他の Casio 高機能電卓(下記参照)への移植性は高く、移植に伴う修正部分は少ないと思う。

<新世代Casio Basic搭載機>
  - fx-5800P
  - fx-9860G (OS Ver 2 以降)
  - fx-9860GII
  - fx-CG10
  - fx-CG20
  - fx-FD10 Pro




逆引き Casio Basic - 目次

  逆引き Casio Basic について


電卓操作

   (代入)命令の入力方法 [fx-5800P]

   ' (コメント) の入力方法 [fx-9860GII]


入力処理
      
  
キーリピート抑制 [fx-5800P / fx-9860GII / fx-CG20]
    キーリピートを抑制する 

  矢印キーの判別 [fx-5800P / fx-9860GII / fx-CG20]
    4つの矢印キーのうち、どれが押されたかを判別する 

  矢印キーで項目選択(1) [fx-5800P / fx-9860GII / fx-CG20]
    矢印キーを使って項目を選択する(1) 

  矢印キーで項目選択(2) [fx-5800P / fx-9860GII / fx-CG20]
    矢印キーを使って項目を選択する(2) 

  キー押下でプログラムをコントロールしたい [fx-5800P / fx-9860GII / fx-CG20]
    プログラムの一旦停止や実行をキー押下でコントロールしたい

  テンキーでメニュー選択させたい [fx-5800P / fx-9860GII / fx-CG20]
    テンキーでメニュー選択させるプログラムを作りたい

  キー長押しでメニュー選択させたい [fx-5800P / fx-9860GII / fx-CG20]
    メニュー選択機能で、同じキーの長押しにより2つ目の選択肢を与えたい


出力処理

   命令を Basic コマンドに置き換えたい [fx-5800P / fx-9860GII / fx-CG20]  
     命令 を Basic コマンドに置き換えて、fx-5800 と fx-9860GII 互換のコードを書く


計算

  fx-5800P で Mod を使いたい [fx-5800P]
    fx-9860GII (グラフ関数電卓)の 除算の余りが得られる Mod 関数を fx-5800P で実現する

  整数の桁数を求めたい [fx-5800P / fx-9860GII / fx-CG20]
    Locate コマンドを用いて、正しい場所に数値を表示するために 「整数の桁数」 を求める


処理速度

  プログラムを速くしたい [fx-5800P]
    Casio Basic特有の内部処理に基づいて、プログラムを速くする対策を行う






応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ


   


keywords: CasioBasicプログラミング入門プログラム関数電卓

リンク集 | ブログ内マップ

テーマ : プログラム関数電卓
ジャンル : コンピュータ

プログラムを速くしたい - 逆引き Casio Basic

逆引き Casio Basic
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します

2015/06/13
[fx-5800P]

頑張って作ったプログラムが思った以上に遅い。これを速くしたい。



プログラム関数電卓 fx-5800P では、作ったプログラムが思った以上に遅くなることがある。最初に作った時は遅いと感じなくても、機能追加をおこなってプログラム規模が大きくなると、目立ってプログラム実行が遅くなることもよくある。

ここで紹介する対策は、fx-5800P 以外の新世代 Casio Basic 搭載のグラフ関数電卓でも使えるが、グラフ関数電卓はそもそもCPUが速い。主に fx-5800P で役立つと思う。

新世代 Casio Basic については、<目次> を参照。

プログラム高速化には、以下を検討すると良い。

・ コマンドや命令の見直し: 実行速度の速い処理に置き換える

・ Goto 削減:
Goto/Lbl をできるだけ使わないようにする

・ 計算式の活用:
条件分岐やループ処理を計算式に置き換える

・ ロジックの見直し:
プログラム全体の構造やロジックを見直す



コマンドや命令の見直し

fx-5800P の Casio Basic は最低必要限のコマンドしか無いが、それでも1つの処理を実現するためには、複数のやりかたがある。ただ、その選択肢が少ないのが特徴で、選択肢が少ないのでプログラムの改善は楽である。

代表的なコマンドや処理の処理時間の一覧をを示す。これは、特定コマンドの厳密な実行時間ではないので、相対的な比較として見て欲しい。

表 fx-5800P Casio Basic 処理時間の比較
処理内容処理時間 (ミリ秒)
A⇒4.1
通常変数アクセス5.4
If A6.2
If A Else7.2
比較演算(変数)9.7
A≠B⇒10.0
論理演算10.0
比較演算(数値)11.5
If A≠B (変数)12.0
if A≠0 (数値)13.7
テキスト表示 (Locate)20.4
配列変数書き込み22.0
配列変数読み出し22.7
リスト読み出し25.1
リスト書き込み25.3
行列読み出し26.9
行列書き込み28.4

1) 配列変数、リスト、行列の使用は極力減らす
 これらは、際だって実行時間が長い。プログラム上完全に無くすことは不可能だが、同じものを繰り返し使うなら、一旦通常変数に代入しておき、それを使えば効果的だ。ロジックを見直して、これらの使用を減らすことも可能なので、検討の余地はあり、とても効果のある方法と言える。

2) 論理演算、比較演算の使用を減らす
論理演算や比較演算は、条件分岐 (If、⇒) やループ (Do, While) の条件判定で使うことが殆どだろう。論理演算子や比較演算子の使用数を減らすように、プログラムを工夫すると良い。同じ演算を繰り返し使用する場合は、大いに改善の余地がある。

3) Baiscコマンドを Dsz、Isz、⇒ に置き換える
Dsz、Isz、⇒ は、古くからの Casio ユーザーの利便性を考えて、現在の Casio Basic でも使えるように配慮されたものだ。特定の条件を満たす場合は、これらの命令を使う方が顕著な高速化が可能になる。

・ If ... Then ... IfEnd (Else が無い) 構文は、に置き換えると30%速くなる。

・ C+1→C は、C が 0 にならないことが保証されるなら、Isz C に置き換える。

・ C-1→C は、C が 0 にならないことが保証されるなら、Dsz C に置き換える。

4) 条件判定で比較演算を使わない
If A≠0、LpWhile A≠0、While A≠0 は、If A、LpWhile A、While A に置き換えるだけで50%の速度向上が見られる。

条件判定は、内部では 0 か 0 でないか、で処理されている。0 の時は偽、0でない時は真、と判定される。そこで、上のように変数を使い、それが 0 か 0でないかで、条件判定ができる。

これの応用として、
If A≠B、LpWhile A≠B、While A≠B は、それぞれ以下のように判定用変数 C を追加した方が遙かに速くなる。

A-B→C
If C:Then
........
IfEnd


Do
........
A-B→C
........
LpWhile C


A-B→C
While C
........
WhileEnd


5) 数値演算は、できるだけ計算式をシンプルにする。
数値演算や関数の処理時間の一例を表に示す。

処理処理時間 (ミリ秒)
乗算 (AxB)1.6
除算 (A÷B)1.8
累乗 (A)1.9
Int(1.23)1.5

数値演算や関数は、相対的に速いことが分かる。しかし、加算を10回行えば、10ミリ秒以上かかるので、これは明かに無駄である。

例えば、
A + (A+1) + (A+2) + ・・・ + (A+10)
を計算する場合、加算 (+) が20回使われる。

そこで、これをシンプルにして
11A+55
とすれば、乗算1回、加算1回だけになり、10倍の速度向上となる。

なお、上の処理速度比較の測定方法や詳細をまとめた記事を紹介しておく;
 ⇒ fx-5800P: 変数アクセス、比較・論理演算、条件分岐の速度比較


Goto 削減
Casio Basic は、プログラムを上から下へ順に読み込みながら実行する、インタープリタタイプの言語だ。
プログラム中 Goto があると、プログラムの最初から最後まで順にスキャンして、ジャンプ先の Lbl や、ジャンプを伴う Basic コマンドを1つひとつ調べる動作が、内部的に行われている。そのため、ジャンプを伴うコマンドが多くなればなるほど、速度は低下する。

従って、やむを得ない場合を除き、Goto を極力使わないことが、高速化の鍵となり、ジャンプを伴うコマンドが多くなるほど、Goto 削減の効果は大きくなる。


計算式の活用
例えば、
A + (A+1) + (A+2) + ・・・ + (A+10) を、

0→I
Do
A+I→A
I+1→I
LpWhile I≦10

とすることができます。実際は、冒頭の式を ループで処理しようとは思わないだろうが、別の処理なら十分有り得る。
このループの代わりに、
11A+55
とした方が圧倒的に速いことに異論は無いだろう。


ロジックの見直し
まずは、プログラムに無駄がないかどうかを調べる。不要な処理が減ればそれだけ速くなるはずだ。
これ以上は、特に一般論はなく、実際のプログラムに即した検討が必要になる。


プログラム高速化の実例



具体的検討の一例として、下記を挙げておく;
 ⇒ Casio Basic入門32 ~ Casio Basic入門37





応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ







keywords: CasioBasic、プログラミング入門プログラム関数電卓

リンク集 | ブログ内マップ



テーマ : プログラム関数電卓
ジャンル : コンピュータ

整数の桁数を求めたい - 逆引き Casio Basic

逆引き Casio Basic
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します

2015/06/12
[fx-5800P] / [fx-9860GII / fx-CG20]

整数の桁数を求めたい。



整数が代入された変数 A を、画面の右端に表示したい時、A の桁数が分かれば簡単だ。
A の桁数を D とすると、

Locate 17-D,1,A   [fx-5800P の場合]

Locate 22-D,1,A
   [fx-9860GII の場合]


とすれば良い。但し D は 自然数 (1以上の整数)で、16以下(fx-5800P)、21以下(fx-9860GII) が条件になる。



A が自然数 (1以上の整数) の時の桁数

1+Int(log(A))→D   ・・・(1)



A が 0 以上の整数の時の桁数

1→D
A⇒1+Int(log(A))→D


A が 0 の時、log(A) はエラーになるが、この時は桁数 D は 1になる。
そこで、先に D に 1 を代入しておき、A が 0 でない時 (1) の処理を行えば良い。A が 0 で(1)の処理がスキップされる時は、既に D に 1 が代入されているので問題ない。



A が 0 を含めた正・負整数の時の桁数

1→D
A⇒1+Int(log(Abs(A)))→D


ここでは、負号 (-) は桁数に入れていない。

負号 (-) も桁数に入れる場合は、以下のようにすれば良い。

1→D
A>0⇒1+Int(log(Abs(A)))→D
A<0⇒2+Int(log(Abs(A)))→D








応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ



   



keywords: CasioBasic、プログラミング入門プログラム関数電卓

リンク集 | ブログ内マップ



テーマ : プログラム関数電卓
ジャンル : コンピュータ

fx-5800P で Mod を使いたい - 逆引き Casio Basic

逆引き Casio Basic
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します

2015/06/12
[fx-5800P]

fx-5800P で整数の割り算の余りを求める Mod 関数を使いたい。



カシオのグラフ関数電卓 fx-9860GII などに実装されている Mod 関数が、fx-5800P には無い。そこで、fx-5800P のプログラムで Mod 関数と同じ機能を実装する。


fx-9860GII などのグラフ関数電卓の Mod 関数
Mod は剰余を得る関数。fx-9860GII では、1373 で割った余りは、Mod (137,3) で得られる。整数を格納した変数 AN を用いて、Mod (A,N) とすれば、AN で割った余りが求められる。


fx-5800P で Mod 関数と同じ機能を実現する
正の整数 A を 正の整数 N で割った時の商 Q と余り M は、以下の関係になる。

A = QN + M  ・・・(1)

一方、商 Q は以下のように現せる。

Q = Int(A÷N)  ・・・(2)


式(2) の Int( ) は、小数点を以下を切り捨てた結果の整数を求める関数だ。
式(2) を使って、式(1)の Q に代入すると、

A = N・Int(A÷N) + M

従って、式を変形して、余り M は以下の式(3)で現される。

M = A - N・Int(A÷N)   ・・・(3)


fx-5800P では、Mod(A,N) の代わりに以下の記述をすれば良い;

A-NInt(A÷N)





応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ



 



keywords: CasioBasic、プログラミング入門プログラム関数電卓

リンク集 | ブログ内マップ



テーマ : プログラム関数電卓
ジャンル : コンピュータ

逆引き Casio Basic について

逆引き Casio Basic
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します

2015/04/28



これまで、Casio Basic でプログラムを作っていて、繰り返し同じようなロジックを使うようになっています。よく使うロジックを知っているだけで、実際にプログラムを作る時に役立ちます。

そこで、Casio Basic でやりたいことに対して、その方法を紹介するために、逆引き Casio Basic の連載を始めます。

対応機種は、Casio fx-5800P, fx-9860GII, fx-CG20 です。



e-Gadget では、新世代 Casio Basic でのプログラミングについて、3通りの異なる方法で情報提供しています。


Casio Basic でプログラムを作る時、やりたいことを実現するロジックを知りたい
 ⇒ 逆引き Casio Basic - 目次


Casio Basic をじっくりと勉強したい
 ⇒ Casio Basic 入門 - 目次


Casio Basic のコマンドを詳しく知りたい
 ⇒ Casio Basic コマンドリファレンス - 目次









応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ



   



keywords: CasioBasic、プログラミング入門プログラム関数電卓

リンク集 | ブログ内マップ



テーマ : プログラム関数電卓
ジャンル : コンピュータ

矢印キーで項目選択(2) - 逆引き Casio Basic

逆引き Casio Basic
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します

更新 2015/04/29

[fx-5800P / fx-9860GII / fx-CG20]

矢印キーを使って項目を選択する。
矢印キーで項目選択(1) - 逆引き Casio Basic とは異なるロジックを紹介する。


関連記事: fx-5800P:矢印キーの活用


fx-5800P の矢印キー(下図の右上の4つのキー)
Keys-2 

fx-9860GII の矢印キー(下図右下の丸いキー)
TC10-9860GII 

fx-CG20 の矢印キー(下図右下の丸いキー)
fx-CG20_Func_Keys 


矢印キーのキーコード

キーfx-5800Pfx-9860GII / fx-CG20
[▲]8428
[▼]8537
[▶]8627
[◀]8338



項目選択

以下のように矢印キーの [▲] か [▼] を押して、⇒ マークを移動させ、4行目に ⇒マークのある項目番号を表示する。

menu_1 
menu_2 
menu_3 

[▼][▲] キーを押した時、⇒マークを移動させ、項目番号を表示する。

項目番号は1~3で、[▼] を押した時は⇒マークを下へ1つ移動する。項目3から移動するときは、項目1へ移動する。
[▲] を押した時は、逆方向、つまり⇒マークを上へ1つ移動する。項目1から移動する時は、項目3へ移動する。


⇒マークの移動は、
 ・移動する前に、⇒マークをスペースで上書きして消去: Locate コマンド利用
 ・移動先の位置で ⇒マークを表示: Locate コマンド利用

⇒マークの消去および表示位置は、項目番号 M を使って 1桁目、M 行目とすると
 ・消去: Locate 1,M," "
 ・表示: Locate 1,M,"⇒"

但し、⇒マークの消去時(移動前)の M と 表示時(移動後)の M の値は異なることに注意!

ここでは、移動前の M の値から、移動後の M の値を計算で求める。


⇒マークの移動前と移動後を表で示す;

[▼] キー を押したとき
移動前の項目番号 M移動後の項目番号 M求め方
31計算で求める
23
12

[▲] キー を押したとき
移動前の項目番号 M移動後の項目番号 M求め方
13計算で求める
21
32


なお、⇒マークが移動後の項目番号の表示は、 Locate 4,1,M で良い。



⇒マークの移動先の項目番号を計算する方法

⇒マークの移動先を計算で求める場合、[▼] を押した時は移動前の M を3で割った余りに1を加えた結果が移動先の M になる。同様に、[▲] を押した時は、移動前の M に対して M+1 を3で割った余りに1を加えた結果が、移動先の  M になる。

[▼] キー を押した時、計算で ⇒マークの移動先 M を求める方法
移動前の MM を3で割った余り左に1を加える移動先の M
3011
2233
1122

[▲] キー を押した時、計算で ⇒マークの移動先 M を求める方法
移動前の MM+1M+1 を3で割った余り左に1を加える移動先の M
12233
34122
23011

それぞれの計算結果⇒マークの移動先の M が一致していることが分かる。

ところで、整数 A を3で割った余りは、以下のようにして計算できる。

整数 A を3で割った余り = A - 3× Int(A÷3) 

これが、基本になる式だ。項目数が4個あれば、4で割った余りを基本に据えて、計算式を作れば良い。

・ ⇒マークの移動前の M を、そのまま使うか、1を加減いずれかして加工し、
・ それを項目数(今回は3)で割った時の余りを求め
・ これをそのまま使うか、1を加減いずれかして加工して、移動後の M を求める式を作る

項目数で割り算した時の余りの計算を中核とし、細かいところは微調整して、最終的に式を作れば良い。
今回のサンプルプログラムでは、上の表に示した計算方法で良く、式にすると以下のようになる。

 [▼] を押した後の M = M - 3×Int(M÷3) +1 = 1+M-3Int(M÷3)

 [▲] を押した後の M = (M+1) - 3×Int((M+1)÷3) +1 = 2+M-3Int((M+1)÷3)



ところで、fx-9860GII や fx-CG20 の Casio Basic には、余りを求める関数 Mod( ) が備わっていて、整数 A を3で割った余りは、

Mod(A,3)

で求められる。しかし fx-5800P には Mod( ) 関数が無いので、共通して使える上記の計算法を紹介した。


今回の方法は、「全ての整数 A は、それを整数 N で割った余りでグループ分けできる」と言う、理屈に基づいている。
例えば3で割った余りは、0、1、2 のいずれかで、全ての整数は、余り0のグループ、余り1のグループ、余り2のグループのどれかに必ず属する。そして、連続した整数は、これらのグループを順に循環する。

0123456789
余り0余り1余り2余り0余り1余り2余り0余り1余り2余り0



プログラムは以下のようになる。

[▼] [▲] で項目選択 (fx-5800P)
Locate 1,1,"⇒1:"
Locate 2,2,"2:"
Locate 2,3,"3:"
1→M

While 1

Do
Getkey→K
LpWhile K=0

Locate 1,M," "
If K=
85
Then
1+M-3Int(M÷3)→M
Else If K=
84
Then
2+M-3Int((M+1)÷3)→M
IfEnd:IfEnd
Locate 1,M,"⇒"
Locate 1,4,M


WhileEnd



[▼] [▲] で項目選択 (fx-9860GII / fx-CG20)
Locate 1,1,"⇒1:"
Locate 2,2,"2:"
Locate 2,3,"3:"
1→M

While 1

Do
Getkey→K
LpWhile K=0

Locate 1,M," "
If K=
37
Then
1+M-3Int(M÷3)→M
Else If K=
28
Then
2+M-3Int((M+1)÷3)→M
IfEnd:IfEnd
Locate 1,M,"⇒"
Locate 1,4,M


WhileEnd




上のプログラムは、処理がシンプルなので、矢印キーを軽く1回押しても、複数回押したようなキーリピートが発生する。そこで、茶色文字で示した2行(※)を追加してキーリピートを抑制する。

[▼] [▲] で項目選択 (fx-5800P)
Locate 1,1,"⇒1:"
Locate 2,2,"2:"
Locate 2,3,"3:"
1→M

While 1

While Getkey
  (※)
WhileEnd
     (※)
Do
Getkey→K
LpWhile K=0

Locate 1,M," "
If K=
85
Then
1+M-3Int(M÷3)→M
Else If K=
84
Then
2+M-3Int((M+1)÷3)→M
IfEnd:IfEnd
Locate 1,M,"⇒"
Locate 1,4,M


WhileEnd




[▼] [▲] で項目選択 (fx-9860GII / fx-Cg20)
Locate 1,1,"⇒1:"
Locate 2,2,"2:"
Locate 2,3,"3:"
1→M

While 1

While Getkey
  (※)
WhileEnd
     (※)
Do
Getkey→K
LpWhile K=0

Locate 1,M," "
If K=
37
Then
1+M-3Int(M÷3)→M
Else If K=
28
Then
2+M-3Int((M+1)÷3)→M
IfEnd:IfEnd
Locate 1,M,"⇒"
Locate 1,4,M


WhileEnd



この例では、処理がシンプルで高速動作するので、キーリピート抑制をした方が良い。但し fx-5800P は処理速度が遅いので、処理が複雑になれば実行が遅くなり、キーリピートを抑制しない方が良い場合が多い。一方、fx-9860GII は処理速度が速いので、キーリピート抑制はほぼ必要だろう。

 ⇒ キーリピート抑制 - 逆引き Casio Basic




応援クリックをお願いします。励みになるので...


人気ブログランキングへ


FC2ブログランキングへ



   



keywords: CasioBasic、プログラミング入門プログラム関数電卓

リンク集 | ブログ内マップ



テーマ : プログラム関数電卓
ジャンル : コンピュータ

最新記事
最新コメント
カテゴリ
C# (3)
検索フォーム
Visitors
Online Counter
現在の閲覧者数:
プロフィール

やす (Krtyski)

Author:やす (Krtyski)
since Oct 30, 2013


プログラム電卓は、プログラムを使ってナンボ!

実際に触って気づいたこと、自作プログラム、電卓プログラミングについて書いています

おもしろい・役に立つならクリックしてください。励みになります。
にほんブログ村 IT技術ブログ 開発言語へ
にほんブログ村


人気ブログランキングへ


FC2ブログランキングへ


写真: 「4駆で泥んこ遊び@オックスフォード郊外」

リンク
月別アーカイブ
Sitemap

全ての記事を表示する

RSSリンクの表示
最新トラックバック
ブロとも申請フォーム

この人とブロともになる

QRコード
QR