Casio Basic入門2

Casio Basic入門
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します.
最終:2018/11/05


3. fx-5800P CasioBasicの コマンド一覧

fx-5800P Casio Basic の主なコマンド

(1) 入力
 ・入力命令:?
 ・Getkey

(2) 出力
 ・出力命令:
 ・文字列出力: "   "
 ・Cls
 ・Locate

(3) 代入
 ・代入:

(4) ジャンプ
 ・Goto / Lbl 
 ・Dsz / Isz 
 ・ 

(5) 条件分岐
 ・If 文: If ~ Then ~ Else ~ IfEnd 

(6) ループ(繰返し)
 ・Goto / Lbl
 ・Do 文: Do ~ LpWhile 
 ・While 文: While ~ WhileEnd 
 ・For 文: For ~ To (~ Step) ~ Next 

(7) 関係演算
 ・= / / > / / < /

(8) 論理演算
 ・And / Or / Not

(9) 配列変数
 ・Z[ ]

(10) リスト
 ・List

(11) 行列
 ・MAT
 ・det( )
 ・Trn( )
 ・MAT A-1
 など

(12) 実行制御コマンド
 ・Prog
 ・Break
 ・Return
 ・Stop

(13) 各種関数
 ・Int( ) / Frac( )
 ・log( )
 など

(14) 出力設定コマンド
 ・EngOn / EngOff
 ・Norm / Fix / Sci
 など


※ CasioBasic 特有のものは、入力:?出力:代入:ジャンプ命令:Dsz / Isz / ⇒ です。これらの中で、特にジャンプ命令は、非常に利用価値の高いものです。


さて、多くのプログラミング言語と比較すると、fx-5800P のCasioBasic で覚えるべき項目は、とても少ないのです。と言うのも、一般的にパソコンでプログラミングを覚えるには、WindowsなどのOSの動作に関する知識、APIやMFC、様々な機能の多層構造などを知らなくてはなりません。プログラミングの本質を覚える前にギブアップとなりやすいのです。

プログラミングの基本は fx-5800P の CasioBasic に凝縮されていると言えます。

[2016/04/23 追記]
fx-9860GII、fx-CG20 を入手し、これらの Casio Basic についても調べています。機種が異なれば、ハードウェアの違いなどから Csio Basic も少し違ったものになっています。グラフィックスに関しては、fx-9860GII について詳しく調べて Casio Baisc入門 G01~G14 で紹介しています。そして、fx-CG20 までを含めて Casio Basic の互換性について調べました。

Casio Basic - 機種別の互換性

これを見て改めて思うことは、機種間の互換性がかなりのレベルで保たれていて、fx-5800P の Basic Basic が基本になっているということです。Casio Basic 入門には 価格面で入手し易い fx-5800P が適していると言えます。

グラフィックスの描画速度が、fx-CG20 よりも fx-9860GII が速いので、グラフィックスまで含めれば、そして余裕があれば、¥10,000 ~ ¥20,000 程度の fx-9860GII が入門機として良いかも知れません。グラフィックス・プログラミングをしないのであれば、fx-CG20 も入門機として問題ないと思いますが、fx-9860GII と同様に価格が気になります。

[2018/11/05 追記]
fx-9860GII の後継機として、処理速度が同等以上でカラー液晶の fx-CG50 が登場している。fx-9860GII や fx-CG20 で動作する Casio Basicプログラムは、fx-CG50 でも動作する。これからグラフ関数電卓を入手するなら、fx-CG50を勧める。


「CasioBasic入門」では、実際にプログラムを作りながら、これらのコマンド類を解説してゆく予定です。作って面白いプログラムを題材に取り上げたいと考えています。基本は fx-5800P 向けの内容ですが、fx-9860GII や fx-CG50 への移植についても触れています。


Casio Basic 入門と並行して、コマンドリファレンスも作っています。

⇒ CasioBasicコマンドリファレンス: 目次 (随時拡充中)

当初 fx-5800P 向けに書いていますが、fx-9860GII や fx-CG20 / fx-CG50 への適用についても、順次付記してゆく予定です。




4. CasioBasicを使ってみる

実際に手を動かしてプログラムを作ってみることが、プログラミングのスタートです。そして、正しく動作する簡単なプログラムを改良することが、プログラミング習得の最短の道だと思います。

そこで、実際にプログラムを一緒に作りながら、ゆっくりと確実に進めてゆきます。



Chapter 0
プログラム作成・実行の操作ポイント

多くの場合、電源を入れると以下のCOMPモードの画面になります。

Compモード 

fx-5800P は電源を切った時の状態が保存され、次に電源を入れた時に保存された状態で画面表示されます。従って電源を入れた時、上記のCOMPモードでない可能性もあります。

fx-5800P では、左上にある [MODE] キーが操作の起点となります。どのような状態であっても、[MODE] キーを押すと必ず以下に示すモード選択画面になります。

ch1-ModeSelect 

このモード選択画面では、メニュー番号を入力する以外に、この画面からの遷移はできません。

通常の電卓の画面にするには、[1] (1:COMP)、プログラムモードにするには、[5] (5:PROG) とします。

[5] (5:PROG) を選ぶと、以下の Program Menu 画面になります。

TC7-ProgMenu 

この Program Menu 画面から抜けるには、[MODE] キーを押してモード選択を行います。

プログラムの作成、実行、編修は、全てこの Program Menu 画面を起点に操作します。
プログラムの作成、実行、編修中に、[EXIT] キーを何回か押せば、必ず Program Menu に戻ります。


プログラムの作成、実行、編修でポイントとなる画面は、以下の4つです;

1) Program Menu 画面: [EXIT] キーを何回か押せばここに戻る

TC7-ProgMenu 


2) Prog Edit 画面: Program Menu から [3] (3:EDIT) で編修するプログラムを選択

TC7-ProgEdit 


3) Prog List 画面: Program Menu から [2] (2:RUN) で実行するプログラムを選択

TC7-ProgList 


4) プログラム編修画面: プログラムの作成、編修を行う

TC3-5 


先ずは fx-5800P の取り扱い説明書 の88ページ以降の説明を読みながら、実際に操作をしてみてください。また、ハードカバーの裏側に説明のあるステッカーが貼ってありますので、それも少しは参考になります。

1. 最も多用するキー
プログラムの編集画面が表示されている時は、

[FUNCTION] キー

[EXIT] キー

[MODE] キー


を押すと、必要なメニューが出てきます。これら3つのキーから始まる操作で、プログラム作成作業の殆どを行えます。


1.1 [FUNCTION] キー
これを押すと出てくるメニューのうち、最も多用するのが、「3:PROG」メニューと、「1:MATH」です。ここから Casio Basic のコマンドを選んで、編集画面でコマンドを書き込みます。

1.1.1 [1] (1:MATH) メニュー
様々な関数を選択して、プログラム編集画面に書き込めます。さらに、ミリ(m)、マイクロ(μ)、キロ(k)、メガ(M)といった、3桁区切りの接尾記号も、その本来の意味で使えます。例えば1000と書く代わりに1kと書けます。
また、"  " で括られた中には、数字やアルファベット以外にも、表示すべき文字列を書き込めますが、「1:MATH」メニューから文字として書き込むこともできます。

1.1.2 [3] (3:PROG) メニュー
ほぼ全てのコマンドを、このメニューから選んで書き込めます。
また、"  " で括られる中には、数字やアルファベット以外にも、表示すべき文字列を書き込めますが、「3:PROG」メニューから文字として書き込むこともできます。例えば、"<EXE>" などという表示は、「3:PROG」 メニューから、大小関係を判定する <> を選んで文字として使えます。


1.2 「EXIT] キー
1つ前の表示に戻るために使います。分からなくなったら、[EXIT] キーを何度か押せば Program Menu へ戻ります。


1.3 [MODE] キー
Program Manu から抜けて、関数電卓の画面へ戻る時には、[1] (1:COMP) を選びます。
もし、うっかり [MODE] を押してしまうことがありますが、そこで出てくるメニューから [5] (5:PROG) を選べば、プログラム編集画面へ戻れます。この場合でも、作業中の内容はj保存されています。



2. プログラム実行の手順

作成したプログラムを実行するには、2つの方法があります。

Program Menu 画面からのプログラム実行
COMPモードからのプログラム実行: [FILE] キー


2.1 Program Menu 画面からのプログラム実行
Program Menu 画面で、[2] (2:RUN) を選び、ここで表示される Prog List からプログラムを選べば、実行できます。

2.2 COMPモードからのプログラム実行: [FILE]キー
[MODE] [1] (1:COMP) で遷移する、通常の電卓画面(COMP モード)で、プログラムを実行したい時に [FILE] キーを押します。そこで現れるプログラムリストから、プログラムを選んで実行します。


2014/01/21追記: 上記いずれの方法においても、プログラムリストが表示されている時、目的のプログラム名の頭のアルファベットを入力すると(例えば "P")、そのアルファベット("P")で名前が始まるプログラム名にジャンプします。もし "P" で始まるプログラムが無い場合は、アルファベット順で "P" よりも後ろの文字で始まるプログラム名までジャンプします。
プログラムリストが表示されている時はアルファベット入力モードになっているので、例えば "P" で始まるプログラムへジャンプさせるには、[ALPHA] キーを押さずに、いきなり [6] キー(このキーの右上にピンク色で "P" と印刷されています)を押すだけのワン・アクションなので、便利です。


3. アルファベットや数字の入力

[ALPHA] キー と [SHIFT] キーを使って、通常入力モード、ALPHAモード、SHIFTモードを切り替えて入力します。

[ALPHA] を押すと、画面左上に A が表示され、ALPHA入力モードになっていることを示し、キーの右上にピンク色で印刷されているアルファベットや記号を入力できます。但し、キーを1つ入力する前に必ず [ALPHA] を押す必要があります。[ALPHA] をもう一度押すと、画面左上の A  が消え、キーに白で印刷されている数字や関数などを入力できます(通常入力モード)。

[SHIFT] を押すと、画面左上に S  が表示され、SHIFT入力モードになっていることを示し、キーの左上にオレンジ色で印刷されている記号や関数を入力できます。もう一度 [SHIFT] を押すと、画面左上の S  が消え、キーに白で印刷されている数字や関数などを入力できます(通常入力モード)。

[SHIFT] を押してから [ALPHA] を押すと、画面左上に A のみが表示され、ALPHA入力モードであることを示し、ALPHAモードで入力できるアルファベットや記号を、連続して入力できます。いちいちキー一つごとに [ALPHA] を押す必要がありません。


これで、プログラムを作成する準備ができました。


つづく...

Casio Basic (超)入門 /  Casio Basic入門3 / 目次



応援クリックをお願いします。励みになるので...
にほんブログ村 IT技術ブログ 開発言語へ


 


keywords: fx-5800PCasioBasicプログラミング入門プログラム関数電卓

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

関連記事

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

プログラムライブラリ - 圧力換算 (fx-5800P)

プログラムライブラリ
<目次>

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

追記更新 2018/11/03

PConverter (圧力換算プログラム) - fx-5800P

CcLinkerで転送できるプログラムファイルがダウンロード可能に [2018/11/03]


著作権者

やす (Krtyski)
[当ブログ管理人]



対応機種

Casio fx-5800P

Casio fx-9860GII、fx-CG20 / fx-CG50 用は こちら



プログラムの使い方

圧力単位 psi、KPa、bar、atm の間での換算を行う。

例えば、以下の画面表示の時、

1.psi:15
2.KPa:103.3213
3.bar:1.034213
4.atm:1.020689


同じ圧力を4つの異なる単位で表示している。

ここで、10 bar の他の単位での換算値を知るには、[3] キーを押して

1.psi:15
2.KPa:103.3213
3.bar:>>>>>>>>
4.atm:1.020689

bar 単位に 10 を入力すると、以下のように各単位での換算値が表示される。

1.psi:145.0377
2.KPa:1000
3.bar:10
4.atm:9.869232


プログラムを終了するために [EXIT] キーを押すと、BYE! と表示してプログラムが終了する。



プログラムの説明

Casio Basic で圧力換算プログラム を参照



プログラムファイルのダウンロード

CcLinkerで fx-5800P に転送できるプログラムファイル(CCLファイル)のダウンロード

CcLinkerの紹介





ソースファイル

PDFファイル、EXCELファイルのダウンロード

PConverterソース 



応援クリックをお願いします。励みになるので...
にほんブログ村 IT技術ブログ 開発言語へ


 



keywords: CasioBasicプログラム電卓、圧力換算、fx-5800P、fx-9860GII、fx-CG20、fx-CG50

関連記事

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

Casio Basic入門31

Casio Basic入門
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します
最終更新: 2018/11/03

 4. CasioBasicを使ってみる(続き)

Chapter 5

◆ Chapter 5 の目標: サブルーチンを使いこなす

前回: Casio Basic入門30 を見る


[2018/11/03 追記]
 ソースコードの誤記を見直しました
 CcLinker を使ってfx-5800Pに転送して使えるプログラムファイル(CCLファイル)をダウンロードできます。


前回までに、キー長押しによりタイムゾーンの変更・設定機能を呼び出すようにしました。


夏時間の開始と終了の日時は、毎年異なります。そこで2015年の夏時間の開始・終了日時を表示する機能を追加し、さらにチョットした仕上げを行ってプログラムを完成させます。

最終的に完成させるプログラムを一番下に掲載しているので、先にそれを見て分かれば、先へ進むのも良いでしょう。



Chapter5-9
キー長押しによる別機能の呼び出し

27-TZInfo  

このように、ヨーロッパとアメリカ(北米)について、それぞれの夏時間の開始と終了日時を表示する機能を追加します。

なお、この表示は 2014 年のヨーロッパやアメリカの夏時間の期間を示しますが、もう 2015年がやってきます。
そこで、2015年の夏時間の期間を表示するようにします。

2015年の夏時間の期間
・ヨーロッパ: 2015年3月29日 午前2時開始、2015年10月25日 午前3時終了
・アメリカ  : 2015年3月9日 午前2時開始、2015年11月1日 午前2時終了
※ 夏時間終了の時間がヨーロッパとアメリカで1時間違う)

実際問題、現地の人は深夜は寝ているので、アメリカでは 10月25日の朝以降は夏時間ではありません。ヨーロッパでも同様に 11月1日の朝は夏時間ではありません。そこで、本プログラムでは、朝の時点で夏時間かどうかの基準で表示(下記)を行うことにします。

  DLS IN 2015
EUR: 3-20⇒10-24
USA: 2-9 ⇒10-31


2016年には、ここの表示を更新する必要があります。

さて、この表示を呼び出すためにはメイン画面で [3][4] キーを長押しすることにします。そして、その表示は 画面表示ルーチン TZS で行うことにします。



以上が今回の機能追加の内容で、具体的には以下のように進めます。

1.初期化処理
特に変更なし。

2.メニュー番号取得処理
今回は、[3] キー と [4] キーの長押しを検出し、検出されたときに、メニュー変数 M5 を入れる。

3.入力処理
M=5 の時は、単に情報を表示するだけで、キー入力処理は行なわない。

4.時間の計算
M=5 の時は、情報を表示するだけなので、何も計算することはない。

5.時間表示の更新
一旦画面全体を消去し、夏時間の情報を表示したのち、メイン画面を再表示する。再表示は 画面表示サブルーチン TZM を用いる。TZM の変更はない。

6.ループ構造
既にある While 1 ~ WhileEnd ループの中に、上記追加コードを入れる。


メインルーチンの擬似的なプログラムは、以下になります。追加・修正するところが分かると思います。


[初期化処理]

Prog "TZM"  [メイン画面表示]

While 1

  [メニュー番号取得処理]

  
[ [3]  および [4] キー長押しを検出し 両方ともメニュー番号 M=5 とする処理]

  If M=0:Then
    [日本時間入力処理] (時間から「時」と「分」の分離も行う)
  Else If M=1:Then
    [ドイツ時間入力処理] (時間から「時」と「分」の分離も行う)
  Else If M=2:Then
    [LA時間入力処理] (時間から「時と「分」の分離も行う)
  Else If M=3:Then
    キー入力処理は行わない。時間から「時」と「分」の分離のみ行う
  Else If M=4:Then
    キー入力処理は行わない。時間から「時」と「分」の分離のみ行う
  IfEnd:IfEnd
  IfEnd:IfEnd
  IfEnd

  If M=0:Then
    [時間計算]
  Else If M=1:Then
    [時差計算]
  Else If M=2:Then
    [時間計算]
  Else If M=3:Then
    [時間計算]
  Else If M=4:Then
    [時間計算]
  
Else If M=5:Then
    Prog "TZS"  
[夏時間情報の表示]
    Cls
    Prog "TZM"  
[メイン画面表示]

  Else If M=6:Then
    Prog "TZS"  
[ヨーロッパタイムゾーン設定]
    [時間計算]
    Prog "TZM"  
[メイン画面表示]
  
Else If M=7:Then
    Prog "TZS"  
[アメリカタイムゾーン設定]
    [時間計算]
    Prog "TZM"  
[メイン画面表示]

  IfEnd:
IfEnd
  IfEnd:IfEnd
  IfEnd:IfEnd
  IfEnd
:IfEnd

  
Prog "TZD"    [時間の再表示]

WhileEnd


(赤文字は機能追加部分)



1.初期化処理
変更なし。



2.メニュー番号取得処理 - キー長押し処理


[3] キー と [4] キーの長押しを検出して、メニュー変数 M5 を入れます。

長押し検出は、既に説明したものを適用するだけです。

メニュー番号取得処理のソースコード
-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M
K=35⇒1→M
K=36⇒2→M
K=37⇒3→M
K=21⇒4→M

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

0→C
While Getkey=35
Isz C
C=9⇒Break
WhileEnd
C=9⇒6→M
0→C
While Getkey=36
Isz C
C=9⇒Break
WhileEnd
C=9⇒7→M


(赤文字は追加部分)



3.入力処理

入力処理を行わないので、[入力処理ブロック] は何も変更しません。



4.時間計算

時間計算は行いませんが、ここで表示サブルーチン TZS を呼び出し、TZS で夏時間情報を表示させます。TZS 変更については、以下で説明します。

次に、TZS での表示が終わり、メインルーチンに戻ってきたら、一旦画面表示全体を消去 (Cls コマンドを使用)し、メイン画面表示サブルーチン TZM を呼び出して、選んだタイムゾーンに合わて画面を再表示します。TZM の変更は不要です。


メインルーチンに追加するプログラムを示します。今回変更するメインルーチン全体は、一番下に掲載しています。

メインルーチンに追加するプログラム
Else If M=5
Then Prog "TZS"
Cls:Prog "TZM"
IfEnd


タイムゾーン設定サブルーチン TZS を呼び出します。TZS の変更点は、以下で説明します。
  Prog "TZS"

TZS から戻ってきた時、夏時間情報が表示されたままです。そこで、Cls コマンドで画面を消去します。
  Cls
 ⇒ Casio Basic コマンドリファレンス: Cls

最後に、メイン画面の際表示を行うために、メイン画面表示サブルーチン TZM を呼び出します。
  Prog "TZM"


TZS の変更点は、下記のようになります。

サブルーチン:TZS のプログラム (夏時間情報を追加)
Cls
Locate 15,4,"▶t"
Locate 16,4,"E"
Locate 1,4," <Lt-Rt>"   [ これは下へ移動 ]

If M=5:Then
Locate 1,1," DLS IN 2015"
Locate 1,2,"EUR: 3-29⇒10-24"
Locate 1,3,"USA: 3-8 ⇒10-31"◢
Return
Else
If M=6
Then V→Z
Locate 1,1," EUR TIME ZONE"
If S:Then
Locate 1,2,"  WEST  CEST"
Locate 1,3,"  EEST   FEST"
Else
Locate 1,2,"  WET   CET"
Locate 1,3,"  EET    FET"
IfEnd
Else If M=7
Then W→Z
Locate 1,1," USA TIME ZONE"
If T:Then
Locate 1,2," PDT  MDT"
Locate 1,3," CDT  EDT"
Else
Locate 1,2," PST  MST"
Locate 1,2," CST  EST"
IfEnd
IfEnd:IfEnd
IfEnd

Locate 1,4," <Lt-Rt>"    [ これは、上からここへ移動 ]


2+6Z-12Int(Z÷2)→X
2+Int(Z÷2)→Y
Locate X,Y,"⇒"

Do
Getkey→K
If K=86:Then
Locate X,Y," "
If Z=3:Then 0→Z
Else Z+1→Z
IfEnd
2+6Z-12Int(Z÷2)→X
2+Int(Z÷2)→Y
Locate X,Y,"⇒"
Else If K=83
Then
Locate X,Y," "
If Z=0:Then 3→Z
Else Z-1→Z
IfEnd
2+6Z-12Int(Z÷2)→X
2+Int(Z÷2)→Y
Locate X,Y,"⇒"
IfEnd:IfEnd
LoWhile K≠47


(追加部分を赤文字で示す)

・ メニュー番号 M=5 の時の処理として、ヨーロッパとアメリカ(北米)それぞれの夏時間が開始・終了する日時を表示します。
・表示の最後に、◢ 命令を使って、プログラムの実行を一時停止させます。[EXE}キーを押せば一時停止が解除されるので、Returnコマンドで強制的に TZS を終了させ、メインルーチンに戻します。
 ⇒ Casio Basic コマンドリファレンス: ◢ (出力命令)
 ⇒ Casio Basic コマンドリファレンス: Return

なお、M=5 の時、夏時間情報を表示させるので、この時は Locate 1,4," <Tl-Rt>" の表示は邪魔になります。この表示はタイムゾーンを選択させると時に、左矢印と右矢印を使え、と言う操作ガイドなので、M=6M=7 の時のみに必要です。そこで、上に示したように、実行する位置を変更します。





5.時間の再表示

時間の再表示は、サブルーチン TZD で行います。これについては変更の必要がありません。


以上で、プログラムが一応完成しました。




実際に、プログラムを実行していると、いくつか気になる点が出てきたので、最後の仕上げを行います。

ヨーロッパの夏時間か標準時間を切り替えるために、[3] キーを押すとき、1:CEST から 1:CET に表示を切り替わる際に、1:CEST の最後の T の表示がちらつくのが気になったので、以下のように変更しました。

表示サブルーチン TZM の上から2行目;

Locate 1,2,"1:CET"

を、以下のように、スペースを追加しました。

Locate 1,2,"1:CET "


さらに、夏時間と標準時間の切り替えのために [3] キー や [4] キーを押した時、3:ST3:DL の表示の切り替えがもたつく感じがします。 4:ST4:DL の表示の切り替えも同様です。

その原因は、TZM の中で、上記の表示切り替え処理が最後の方にあることにあります。fx-5800P の処理能力が低いためこのようなことになります。そこで、上記の表示の切り替え処理を、メインルーチンの [時間計算]ブロック にある If M=3 および If M=4 の時の処理に、上記の表示切り替えの処理を、敢えて Locate コマンドを追加し、Prog "TZM" を削除します。これで表示切り替えのモタツキが少し解消しました。

[0]キー、[1]キー、[2]キーを押して入力ボックス INPI を呼び出すと >>>>  と表示されますが、ここで何も入力せずに [EXE]キーを押すと 時刻が 0000 になります。この操作は入力キャンセルなので、入力ボックスを呼び出す前の時刻に戻るのが自然です。そこで何も入力しないで戻る特、つまり Z = 0 の時は、時刻変数 J, G, U を更新計算しないようにします。M = 0, 1, 2 の時のそれぞれの処理を、Z が ゼロでない時に実行されるように If Z:ThenIfEnd で挟みます。

このプログラム起動直後は、時刻表示されません。この時、[0][1][2]を押すと >>>> が表示されますが、数字を何も入力せうずに [EXE] を押した時は、Z = 0 となりますが、この時は時刻を示す4桁の数字を表示しないのが自然です。時刻表示サブルーチン TZDJ = -1 の時は Return して何もせず戻るようになっています。そこで、M = 0, 1, 2 の時 時刻変数 J を更新しないように以下のように Z⇒ を追加します。
Z⇒Z→J
Z⇒Z→G
Z⇒Z→U
 

この下に完成したプログラムを示します。今回、追加・修正した部分を赤文字で示しています。

最後に、メインルーチンのプログラム名を TIME ZONE に変更してください。これで一旦完成とします。

今回のプログラムに少し手を入れ、今年の夏時間に対応したものをプログラムライブラリに収録しています。
世界の時差換算 - Time Zone (fx-5800P用)
世界の時差換算 - Time Zone (fx-9860Gシリーズ/fx-CG20/fx-CG50用)







完成したプログラム TIME ZONE は、以下の通り(今回追加した部分を赤文字で示す):

 CcLinkerを使ってfx-5800Pに転送できるCCLファイルのダウンロード
 ※ CcLinker の紹介

メインルーチン:TIME ZONE のプログラム
9→P:17→Q
-1→J:0→G:0→U
0→S:0→T
1→V:0→W
P-V→P:Q-W→Q
Prog "TZM"

While 1

-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M
K=35⇒1→M
K=36⇒2→M
K=37⇒3→M
K=21⇒4→M

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

While Getkey=35
Isz C:C=9⇒Break
WhileEnd:C=9⇒6→M
0→C
While Getkey=36
Isz C:C=9⇒Break
WhileEnd:C=9⇒7→M

If M=0:Then
8→X:1→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z⇒Z→J
Else If M=1
Then
8→X:2→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z⇒Z→G
Else If M=2:
Then
8→X:3→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z⇒Z→U
Else If M=3 Or M=4
Then
Int(J÷100)→A
J-100A→B
IfEnd:IfEnd
IfEnd:IfEnd

If M=0:Then
If Z:Then
A≧24⇒A-24→A
100A+B→J
A-P→C
C<0⇒C+24→C
100C+B→G
A-Q→C
C<0⇒C+24→C
100C+B→U
IfEnd
Else If M=1
Then
If Z:Then
A≧24⇒A-24→A
100A+B→G
A+P→C
C≧24⇒C-24→C
100C+B→J
A+P-Q→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→U
IfEnd
Else If M=2
Then
If Z:Then
A≧24⇒A-24→A
100A+B→U
A+Q→C
C≧24⇒C-24→C
100C+B→J
A+Q-P→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→G
IfEnd
Else If M=3
Then
If S:Then
0→S:P+1→P
Locate 5,2,"T "
Locate 15,2,"ST"

Else
1→S:P-1→P
Locate 5,2,"ST"
Locate 15,2,"DL"

IfEnd
A-P→C
C<0⇒C+24→C
100C+B→G

Else If M=4
Then
If T:Then
0→T:Q+1→Q
Locate 4,3,"S"
Locate 15,3,"ST"

Else
1→T:Q-1→Q
Locate 4,3,"D"
Locate 15,3,"DL"

IfEnd
A-Q→C
C<0⇒C+24→C
100C+B→U

Else If M=5
Then Prog "TZS"
Cls:Prog "TZM"

Else If M=6
Then Prog "TZS"
Z→V:9-S-Z→P
Int(J÷100)→A
J-100A→B
A-P→C
C<0⇒C+24→C
100C+B→G:Cls
Prog "TZM"
Else If M=7
Then Prog "TZS"
Z→W:17-T-Z→Q
Int(J÷100)→A
J-100A→B
A-Q→C
C<0⇒C+24→C
100C+B→U:Cls
Prog "TZM"
IfEnd:IfEnd
IfEnd:IfEnd
IfEnd:IfEnd
IfEnd:IfEnd

Prog "TZD"

WhileEnd




サブルーチン:TZM のプログラム (画面表示)
Locate 1,1,"0:JST"
Locate 1,2,"1:CET "
Locate 1,3,"2:PST"
Locate 13,2,"3:"
Locate 13,3,"4:"
Locate 1,4,"<AC>:QUIT"

If V=0:Then
Locate 3,2,"W"
Else If V=1
Then Locate 3,2,"C"
Else If V=2
Then Locate 3,2,"E"
Else If V=3
Then Locate 3,2,"F"
IfEnd:IfEnd
IfEnd:IfEnd

If W=0:Then
Locate 3,3,"P"
Else If W=1
Then Locate 3,3,"M"
Else If W=2
Then Locate 3,3,"C"
Else If W=3
Then Locate 3,3,"E"
IfEnd:IfEnd
IfEnd:IfEnd

If S:Then
Locate 5,2,"ST"
Locate 15,2,"DL"
Else
Locate 5,2,"T "
Locate 15,2,"ST"
IfEnd

If T:Then
Locate 4,3,"D"
Locate 15,3,"DL"
Else
Locate 4,3,"S"
Locate 15,3,"ST"
IfEnd




サブルーチン:TZS のプログラム (タイムゾーン設定)
Cls
Locate 15,4,"▶t"
Locate 16,4,"E"

If M=5:Then
Locate 1,1,"  DLS IN 2014"
Locate 1,2,"EUR: 3-30⇒10-26"
Locate 1,3,"USA: 3-9 ⇒11-2"◢
Return
Else
If M=6
Then V→Z
Locate 1,1," EUR TIME ZONE"
If S:Then
Locate 1,2,"  WEST  CEST"
Locate 1,3,"  EEST   FEST"
Else
Locate 1,2,"  WET   CET"
Locate 1,3,"  EET    FET"
IfEnd
Else If M=7
Then W→Z
Locate 1,1," USA TIME ZONE"
If T:Then
Locate 1,2," PDT  MDT"
Locate 1,3," CDT  EDT"
Else
Locate 1,2," PST  MST"
Locate 1,3," CST  EST"
IfEnd
IfEnd:IfEnd
IfEnd

Locate 1,4," <Lt-Rt>"
2+6Z-12Int(Z÷2)→X

2+Int(Z÷2)→Y
Locate X,Y,"⇒"

Do
Getkey→K
If K=86:Then
Locate X,Y," "
If Z=3:Then 0→Z
Else Z+1→Z
IfEnd
2+6Z-12Int(Z÷2)→X
2+Int(Z÷2)→Y
Locate X,Y,"⇒"
Else If K=83
Then
Locate X,Y," "
If Z=0:Then 3→Z
Else Z-1→Z
IfEnd
2+6Z-12Int(Z÷2)→X
2+Int(Z÷2)→Y
Locate X,Y,"⇒"
IfEnd:IfEnd
LpWhile K≠47




サブルーチン:TZC のプログラム (時間を「時」と「分」に分離):変更なし
If Z<100:Then
Z→X:0→Y
Else
Int(Z÷100)→X
Z-100X→Y
IfEnd




サブルーチン TZD のプログラム (時間の表示):変更なし
J=-1⇒Return

Locate 8,1,"0000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U




世界の時差換算プログラム TIME ZONE が完成しました。

「入力ボックス」は、以下にあります。
 ⇒ プログラムライブラリ - 入力ボックス

今回 fx-5800P 用に作ったものは、プログラムライブラリ - Time Zone にもまとめています。
このプログラムを fx-9860GII や fx-CG20 に移植したものは、こちら のプログラムライブラリにまとめていて、プログラムファイルをダインロードして電卓に転送してすぐに使えます。


次回からは、入力ボックスの高速化と、正負全小数へ対応するための拡張を試みます。



つづく...

Casio Basic入門32 / 目次



応援クリックをお願いします。励みになるので...
にほんブログ村 IT技術ブログ 開発言語へ


 



keywords: fx-5800PCasioBasic、世界時間換算, プログラミング入門プログラム関数電卓

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



関連記事

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

Casio Basic入門30

Casio Basic入門
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します
最終更新: 2018/11/03

 4. CasioBasicを使ってみる(続き)

Chapter 5

◆ Chapter 5 の目標: サブルーチンを使いこなす

前回: Casio Basic入門29 を見る


[2018/11/03 追記]
 ソースコードの誤記を見直しました
 CcLinker を使ってfx-5800Pに転送して使えるプログラムファイル(CCLファイル)をダウンロードできます。


前回は、ヨーロッパのタイムゾーンを変更・設定する機能を詳細にみてみました。

今回は、アメリカのタイムゾーンを変更・設定する機能を追加してゆきます。

今回完成させるプログラムを一番下に掲載しているので、先にそれを見て分かれば、先へ進むのも良いでしょう。



Chapter5-8
類似処理による機能追加

39-TZ5_main 

このメイン画面では、2:PST は、アメリカの太平洋標準時間を示しています。

アメリカにあるタイムゾーンのうち、下記の4つのタイムゾーンに切り替えられるように機能を追加してゆきます。

タイムゾーン標準時間 夏時間 
太平洋時間PSTPDT
山岳部時間MSTMDT
中部時間CSTCDT
東部時間ESTEDT

US-TZ  
Time-J.net 世界時計 - 世界の時間と時差 - アメリカの時差と現在時刻 から引用


ここで [2] キーを長押しすると、下に示すような 「アメリカのタイムゾーン選択画面」を表示させることにします。

44-TZSelect_NA 

ここでの操作は、ヨーロッパのタイムゾーン設定と全く同様にします。

つまり、左矢印キー [◀] か 右矢印キー [▶] を押すと、⇒ マークが移動し、[EXE] キーを押すと ⇒ マークで示されているタイムゾーンが確定されるようにします。この追加はタイムゾーン設定サブルーチン TZS に追加します。

北米のタイムゾーン変数として、新たに変数 W を使い、夏時間フラグ T と合わせて、以下のように決めます。

タイムゾーン標準時間 (T=0)夏時間 (T=1) 変数 W の値
太平洋時間PSTPDT0
山岳部時間MSTMDT1
中部時間CSTCDT2
東部時間ESTEDT3

サブルーチン TZS でアメリカのタイムゾーンを設定した場合は、変数 W の値を変更します。

TZS が終了してメインルーチンに戻ってきたら、必要な時間計算を行い、最後に時間表示サブルーチン TZD を呼び出して、変数 W の値に従って、時間表示サブルーチン TZD で時間表示を更新します。

以上が今回の機能追加の内容で、具体的には以下のように進めます。

1.初期化処理
新たに、アメリカのタイムゾーン変数 W を追加する。それに合わせて変数を初期化する。
メイン画面表示サブルーチン TZM にもアメリカの異なるタイムゾーン略称を表示するように機能追加する。

2.メニュー番号取得処理
今回は、[2] キーの長押しを検出し、検出されたときに、メニュー変数 M に 7 を入れる。

3.入力処理
M=7 の時は、キー入力処理は行なわない。但し、アメリカのタイムゾーン変更に伴って、メイン画面のタイムゾーン表示を変更するために、メイン画面表示サブルーチン TZM を呼び出す(これに合わせて TZM を修正する)。

4.時間の計算
M=7 の時、タイムゾーン変更に合わせて北米時間を計算する。日本時間とヨーロッパ時間には影響が無いので、これらの計算は行わない。

5.時間表示の更新
時間表示サブルーチン TZD を用いて、日本時間、ヨーロッパ時間、アメリカ時間の表示を更新する。

6.ループ構造
既にある While 1 ~ WhileEnd ループの中に、上記追加コードを入れる。


メインルーチンの擬似的なプログラムは、以下になります。追加・修正するところが分かると思います。


[初期化処理]

Prog "TZM"  [メイン画面表示]

While 1

  [メニュー番号取得処理]

  
[ [1]  および [2] キー長押しを検出し それぞれメニュー番号 M=6, 7 とする処理]

  If M=0:Then
    [日本時間入力処理] (時間から「時」と「分」の分離も行う)
  Else If M=1:Then
    [ドイツ時間入力処理] (時間から「時」と「分」の分離も行う)
  Else If M=2:Then
    [LA時間入力処理] (時間から「時と「分」の分離も行う)
  Else If M=3:Then
    キー入力処理は行わない。時間から「時」と「分」の分離のみ行う
  Else If M=4:Then
    キー入力処理は行わない。時間から「時」と「分」の分離のみ行う
  IfEnd:IfEnd
  IfEnd:IfEnd
  IfEnd

  If M=0:Then
    [時間計算]
  Else If M=1:Then
    [時差計算]
  Else If M=2:Then
    [時間計算]
  Else If M=3:Then
    [時間計算]
  Else If M=4:Then
    [時間計算]
  
Else If M=6:Then
    Prog "TZS"  
[ヨーロッパタイムゾーン設定]
    [時間計算]
    Prog "TZM"  
[メイン画面表示]
  
Else If M=7:Then
    Prog "TZS"  
[アメリカタイムゾーン設定]
    [時間計算]
    Prog "TZM"  
[メイン画面表示]

  IfEnd:
IfEnd
  IfEnd:IfEnd
  IfEnd:IfEnd
  IfEnd

  
Prog "TZD"    [時間の再表示]

WhileEnd


(赤文字は機能追加部分)



1.初期化処理
プログラム起動時に、太平洋時間を表示させたいと言う私の好みから、北米のタイムゾーン変数 W を 0 で初期化しておき、Q と W から Q の初期値を太平洋時間に設定します。
1→W
Q-W→Q

を追加します。

次に、初期表示を受け持っているサブルーチン TZM をアメリカの複数タイムゾーンに対応するように修正します。 TZM 修正内容は以下で説明します。



2.メニュー番号取得処理 - キー長押し処理


[2] キー長押しを検出して、メニュー変数 M7 を入れます。

長押し検出は、既に説明したものを [2] に対応したものを追加するだけです。

メニュー番号取得処理のソースコード
-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M
K=35⇒1→M
K=36⇒2→M
K=37⇒3→M
K=21⇒4→M

0→C
While Getkey=35
Isz C
C=9⇒Break
WhileEnd
C=9⇒6→M
0→C
While Getkey=36
Isz C
C=9⇒Break
WhileEnd
C=9⇒7→M


(赤文字は追加部分)



3.入力処理

入力処理を行わないので、[入力処理ブロック] には何もプログラムを書きません。



4.時間計算

先ず、タイムゾーン設定サブルーチン TZS を呼び出します。TZS はタイムゾーン変数 Z に 0、1、2、3 のいずれかの値を入れてから終了します。今回は、サブルーチン TSZ にアメリカのタイムゾーン選択に関する部分を追加します。TZS 変更については、以下で説明します。

次に、TZS が設定した変数 Z に基づいて、メインルーチンの北米タイムゾーン変数 W を設定し、北米時差変数 Q を算出します。そして、時差 Q から時間を計算します。

最後に、メイン画面表示サブルーチン TZM を呼び出して、選んだタイムゾーンに合わて画面を再表示します。TZM の変更点は、以下で説明しますす。


メインルーチンの [時間計算] ブロック に追加するプログラムを示します。今回変更するメインルーチン全体は、一番下に掲載しています。

メインルーチンに追加するプログラム
Else If M=7
Then Prog "TZS"
Z→W:17-S-Z→Q
Int(J÷100)→A
J-100A→B
A-Q→C
C<0⇒C+24→C
100C+B→U
Cls
Prog "TZM"
IfEnd


タイムゾーン設定サブルーチン TZS を呼び出します。TZS の変更点は、以下で説明します。
  Prog "TZS"

変数 Z は使い捨て変数で、プログラムの動作中にその値が変化しても良いように使っている変数です。一方、変数 W はヨーロッパのタイムゾーン値を格納する予約変数として使っていて、その値は勝手に変更されては困ります。
そこで、TZS の直後で、Z の値を W に入れます。続いて、ヨーロッパ時差の変数 Q を計算します。ここでは夏時間も考慮して、夏時間フラグ T も使います。アメリカの西の端、つまり太平洋時間の時差は、日本からみて17時間です。夏時間では時差が1時間減るので、タイムゾーン値を引き算すれば、選択したタイムゾーンの時差が分かります。
  Z→W:17-T-Z→Q

タイムゾーンを変更しても、日本時間は変わりません。そこで、日本時間を基準に、時差 Q から、選択したタイムゾーンの時間を計算します。現在の日本時間 J から「時」: A と 「分」: B を算出します。この計算は、既に他でも行っているのと同じです。
  Int(J÷100)→A
  J-100A→B


選択したタイムゾーンの時差が Q なので、A - Q が、その地域の「時」になります。但しこの結果が負になる場合があって、まだ前日であることを意味します。そこで、A - Q が 0 未満の時は 24 を加えると正しい時間になります。この計算も、、これまでに行っているのと同じです。
  A-Q→C
  C<0⇒C+24→C


選んだタイムゾーンの「時」: C が分かったので、アメリカ時間 U が計算できます。これも、これまでに行っているのと同じです。
  100C+B→U

プログラムがここまで進んできても、タイムゾーン設定画面が表示されたままです。そこで、Cls コマンドで画面を消去します。
  Cls
 ⇒ Casio Basic コマンドリファレンス: Cls

最後に、メイン画面の際表示を行うために、メイン画面表示サブルーチン TZM を呼び出します。
  Prog "TZM"


TZS を、アメリカの4つのタイムゾーンに合わせて変更します。
太平洋時間(ロサンゼルス)の夏時間への対応は既に済んでいて、以下のような別のタイムゾーンの略称に対しても、夏時間への対応部分はそのまま使えます。

タイムゾーン標準時間 夏時間 変数 W の値
太平洋時間PSTPDT0
山岳部時間MSTMDT1
 中央部時間CSTCDT2
東部時間ESTEDT3

タイムゾーンが変われば、略称の1文字目を変更すれば良く、標準時間と夏時間の両方に対応できることが分かります。
そこで、W の値に応じて、赤く示したアルファベットのみを Locate コマンドで上書きします。

画面表示サブルーチン TZM のプログラム
Locate 1,1,"0:JST"
Locate 1,2,"1:CET"
Locate 1,3,"2:PST"
Locate 13,2,"3:"
Locate 13,3,"4:"
Locate 1,4,"<AC>:QUIT"

If V=0:Then
Locate 3,2,"W"
Else If V=1
Then Locate 3,2,"C"
Else If V=2
Then Locate 3,2,"E"
Else If V=3
Then Locate 3,2,"F"
IfEnd:IfEnd
IfEnd:IfEnd

If W=0:Then
Locate 3,3,"P"
Else If W=1
Then Locate 3,3,"M"
Else If W=2
Then Locate 3,3,"C"
Else If W=3
Then Locate 3,3,"E"
IfEnd:IfEnd
IfEnd:IfEnd


If S:Then
Locate 5,2,"ST"
Locate 15,2,"DL"
Else
Locate 5,2,"T "
Locate 15,2,"ST"
IfEnd

If T:Then
Locate 4,3,"D"
Locate 15,3,"DL"
Else
Locate 4,3,"S"
Locate 15,3,"ST"
IfEnd


(追加部分は赤文字


タイムゾーン設定サブルチン TZS の変更

前回つくった、ヨーロッパのタイムゾーンを変更する TZS のプログラムを示します。ココに、今回追加する部分を赤文字で追加してみます。

Cls
Locate 15,4,"▶t"
Locate 16,4,"E"
Locate 1,4," <Lt-Rt>"

If M=6
Then V→Z
Locate 1,1," EUR TIME ZONE"
If S:Then
Locate 1,2,"  WEST  CEST"
Locate 1,3,"  EEST   FEST"
Else
Locate 1,2,"  WET   CET"
Locate 1,3,"  EET    FET"
IfEnd
Else If M=7
Then W→Z
Locate 1,1," USA TIME ZONE"
If T:Then
Locate 1,2," PDT  MDT"
Locate 1,3," CDT  EDT"
Else
Locate 1,2," PST  MST"
Locate 1,2," CST  EST"
IfEnd
IfEnd:IfEnd

2+6Z-12Int(Z÷2)→X

2+Int(Z÷2)→Y
Locate X,Y,"⇒"

Do
Getkey→K
If K=86:Then
Locate X,Y," "
If Z=3:Then 0→Z
Else Z+1→Z
IfEnd
2+6Z-12Int(Z÷2)→X
2+Int(Z÷2)→Y
Locate X,Y,"⇒"
Else If K=83
Then
Locate X,Y," "
If Z=0:Then 3→Z
Else Z-1→Z
IfEnd
2+6Z-12Int(Z÷2)→X
2+Int(Z÷2)→Y
Locate X,Y,"⇒"
IfEnd:IfEnd
LoWhile K≠47



・ メニュー番号 M=7 の時の処理として、アメリカのタイムゾーンの一覧表示を追加します。
・それ以外の処理は、既に作ったものをそのまま使えます...実際は、そのまま使えるように予め考えていたと言うのが正しいのですが...



5.時間の再表示

時間の再表示は、サブルーチン TZD で行います。これについては変更の必要がありません。

サブルーチン TZD のプログラム: 変更なし
J=-1⇒Return

Locate 8,1,"000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U




今回までに作成したプログラムは、以下の通り(今回追加した部分を赤文字で示す):

 CcLinkerを使ってfx-5800Pに転送できるCCLファイルのダウンロード
 ※ CcLinker の紹介

メインルーチン:TZ のプログラム
9→P:17→Q
-1→J:0→G:0→U
0→S:0→T
1→V:0→W
P-V→P:Q-W→Q
Prog "TZM"

While 1

-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M
K=35⇒1→M
K=36⇒2→M
K=37⇒3→M
K=21⇒4→M

0→C
While Getkey=35
Isz C:C=9⇒Break
WhileEnd:C=9⇒6→M
0→C
While Getkey=36
Isz C:C=9⇒Break
WhileEnd:C=9⇒7→M


If M=0:Then
8→X:1→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→J
Else If M=1
Then
8→X:2→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→G
Else If M=2:
Then
8→X:3→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→U
Else If M=3 Or M=4
Then
Int(J÷100)→A
J-100A→B
IfEnd:IfEnd
IfEnd:IfEnd

If M=0:Then
A≧24⇒A-24→A
100A+B→J
A-P→C
C<0⇒C+24→C
100C+B→G
A-Q→C
C<0⇒C+24→C
100C+B→U
Else If M=1
Then
A≧24⇒A-24→A
100A+B→G
A+P→C
C≧24⇒C-24→C
100C+B→J
A+P-Q→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→U
Else If M=2
Then
A≧24⇒A-24→A
100A+B→U
A+Q→C
C≧24⇒C-24→C
100C+B→J
A+Q-P→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→G
Else If M=3
Then
If S:Then
0→S:P+1→P
Else
1→S:P-1→P
IfEnd
A-P→C
C<0⇒C+24→C
100C+B→G
Prog "TZM"
Else If M=4
Then
If T:Then
0→T:Q+1→Q
Else
1→T:Q-1→Q
IfEnd
A-Q→C
C<0⇒C+24→C
100C+B→U
Prog "TZM"
Else If M=6
Then Prog "TZS"
Z→V:9-S-Z→P
Int(J÷100)→A
J-100A→B
A-P→C
C<0⇒C+24→C
100C+B→G:Cls
Prog "TZM"
Else If M=7
Then Prog "TZS"
Z→W:17-T-Z→Q
Int(J÷100)→A
J-100A→B
A-Q→C
X<0⇒C+24→C
100C+B→U:Cls

Prog "TZM"
IfEnd:IfEnd
IfEnd:IfEnd
IfEnd:IfEnd
IfEnd

Prog "TZD"

WhileEnd




サブルーチン:TZM のプログラム (画面表示)
Locate 1,1,"0:JST"
Locate 1,2,"1:CET"
Locate 1,3,"2:PST"
Locate 13,2,"3:"
Locate 13,3,"4:"
Locate 1,4,"<AC>:QUIT"

If V=0:Then
Locate 3,2,"W"
Else If V=1
Then Locate 3,2,"C"
Else If V=2
Then Locate 3,2,"E"
Else If V=3
Then Locate 3,2,"F"
IfEnd:IfEnd
IfEnd:IfEnd

If W=0:Then
Locate 3,3,"P"
Else If W=1
Then Locate 3,3,"M"
Else If W=2
Then Locate 3,3,"C"
Else If W=3
Then Locate 3,3,"E"
IfEnd:IfEnd
IfEnd:IfEnd


If S:Then
Locate 5,2,"ST"
Locate 15,2,"DL"
Else
Locate 5,2,"T "
Locate 15,2,"ST"
IfEnd

If T:Then
Locate 4,3,"D"
Locate 15,3,"DL"
Else
Locate 4,3,"S"
Locate 15,3,"ST"
IfEnd




サブルーチン:TZS のプログラム (タイムゾーン設定)
Cls
Locate 15,4,"▶t"
Locate 16,4,"E"
Locate 1,4," <Lt-Rt>"

If M=6
Then V→Z
Locate 1,1," EUR TIME ZONE"
If S:Then
Locate 1,2,"  WEST  CEST"
Locate 1,3,"  EEST   FEST"
Else
Locate 1,2,"  WET   CET"
Locate 1,3,"  EET    FET"
IfEnd
Else If M=7
Then W→Z
Locate 1,1," USA TIME ZONE"
If T:Then
Locate 1,2," PDT  MDT"
Locate 1,3," CDT  EDT"
Else
Locate 1,2," PST  MST"
Locate 1,3," CST  EST"
IfEnd
IfEnd:IfEnd

2+6Z-12Int(Z÷2)→X

2+Int(Z÷2)→Y
Locate X,Y,"⇒"

Do
Getkey→K
If K=86:Then
Locate X,Y," "
If Z=3:Then 0→Z
Else Z+1→Z
IfEnd
2+6Z-12Int(Z÷2)→X
2+Int(Z÷2)→Y
Locate X,Y,"⇒"
Else If K=83
Then
Locate X,Y," "
If Z=0:Then 3→Z
Else Z-1→Z
IfEnd
2+6Z-12Int(Z÷2)→X
2+Int(Z÷2)→Y
Locate X,Y,"⇒"
IfEnd:IfEnd
LpWhile K≠47




サブルーチン:TZC のプログラム (時間を「時」と「分」に分離):変更なし
If Z<100:Then
Z→X:0→Y
Else
Int(Z÷100)→X
Z-100X→Y
IfEnd




サブルーチン TZD のプログラム (時間の表示):変更なし
J=-1⇒Return

Locate 8,1,"0000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U




今回は、アメリカのタイムゾーンを変更できるように、機能追加を行いました。
次回は、ヨーロッパやアメリカのタイムゾーンの開始と終了日時を表示する機能を追加します。



つづく...


Casio Basic入門31 / 目次



応援クリックをお願いします。励みになるので...
にほんブログ村 IT技術ブログ 開発言語へ


 


keywords: fx-5800PCasioBasic、世界時間換算, プログラミング入門プログラム関数電卓

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



関連記事

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

Casio Basic入門29

Casio Basic入門
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します
最終更新: 2018/11/03

 4. CasioBasicを使ってみる(続き)

Chapter 5

◆ Chapter 5 の目標: サブルーチンを使いこなす

前回: Casio Basic入門28 を見る


[2018/11/03 追記]
 ソースコードの誤記を見直しました
 CcLinker を使ってfx-5800Pに転送して使えるプログラムファイル(CCLファイル)をダウンロードできます。


前回は、ドイツ時間 (中央ヨーロッパ時間)  に限らず、ヨーロッパ内の4つのタイムゾーンを設定する機能を追加し、新たにタイムゾーン設定サブルーチン TZS のプログラムを提示しました。

今回は、矢印キーで項目を選択させるサブルーチン TZS の作り方を説明します。

今回までに作るプログラムを一番下に掲載しています(前回と同じ)。



Chapter5-7
矢印キーの活用

ヨーロッパのタイムゾーン設定画面を以下のように作ります。

42-TZSelect_EU   

⇒ マークが、現在設定されているタイムゾーンを示しています。

この画面は、S=, V=1 の時、中央ヨーロッパの標準時間を示しています。

サブルーチン TZS が起動する時、夏時間フラグ S の値が 0 か 1 かで表示を変えるようにします。さらに、タイムゾーン変数 V の値に応じて、⇒ マークの位置を買えるようにします。

46-TZSelct_EU_summer2   

この画面は、S=1, V=0 の時、夏時間の西ヨーロッパを示してます。

<Lt-Rt>

は、本来 <左-右> として、左矢印と右矢印を使って選択 ⇒ マークを動かすように説明を入れたかったのですが、fx-5800P は数字とアルファベットしか使えないので、左 = Left = Lt、左 = Right = Rt と勝手に決めて、表示したものです。

右下にある、

▶E

は、確定するには [EXE] キーを押すことを説明しています。

このあたりの表示は、単に私のこだわりですが、私が作るプログラムは操作性を統一し、簡単でも良いから操作説明を表示したいと思っているからです。

これから、TZS を作ってゆく際、動作確認のために、簡単なメインルーチンを使うことにします。

ここでは、仮にファイル名を A としますが、名前は何でもかまいません。

仮メインルーチン: A
0→S
1→V
6→M
Prog "TZS"


S は夏時間フラグで、標準時間の時は 0、夏時間では 1 です。
V はタイムゾーン変数で、0、1、2、3 のいずれかの値になります。
本来のメインルーチン TZ では、メニュー番号 M=6 の時、ヨーロッパのタイムゾーン設定を行います。
北米のタイムゾーンを設定する場合は、M=7 にする予定です。

メインルーチンでは、3つの変数 SVMTZS の動作を決めます。

タイムゾーン V 標準時間: S=0 夏時間: S=1 
西ヨーロッパ時間0WETWEST
中央ヨーロッパ時間1CETCEST
東ヨーロッパ時間2EETEEST
極東ヨーロッパ時間3FETFEST

EU-TZ 
Time-J.net 世界時計 - 世界の時間と時差 - ヨーロッパのタイムゾーンについて から引用



1.初期表示

先ずは、変数の関係無く表示する部分の操作説明の表示を作ります。

Cls
Locate 15,4,"▶t"

Locate 16,4,"E"
Locate 1,4," <Lt-Rt>"


Cls で画面全体の表示をクリアします。

次の2行は、▶E を表示するためのものです。
2行目の ▶t は、プログラム編集画面で、以下の順にキーを押すと入力できます。

[FUNCTION]

[7] - 7:STAT

[3] - 3:DISTR

[4] - 4:▶t

このように、キーボードから入力できる 数字とアルファベット大文字以外の文字を使うことができます。
詳しくは、以下を参照してください。
 ⇒ Casio Basic入門14 - Chapter 2-10
 ⇒ 楽屋裏 - スプラッシュ


次に、メニュー番号 M が 6 の時、ヨーロッパのタイムゾーン選択画面を表示するので、先ずは M による条件分岐を行います。

Else If M=6:Then
[画面表示]
[項目選択]
IfEnd


変数 S と V の値に従って表示を行う [画面表示] の処理は、以下のプログラムになります。

Else If M=6
Then
V→Z
Locate 1,1," EUR TIME ZONE"
If S:Then
Locate 1,2," WEST  CEST"  (WESTの前にスペース2つ)
Locate 1,3,"  EEST   FEST"  (EESTの前にスペース2つ)
Else
Locate 1,2,"  WET    CET"  (WETの前にスペース2つ)
Locate 1,3,"  EET     FET"  (EETの前にスペース2つ)
IfEnd




2.項目選択

矢印キーを押したことを知るためには、キーコードを利用します。


左矢印キー [◀] のキーコードは 83、右矢印キー [▶] のキーコードは 86 です。

これまでもキーコードが出てきましたが、キーコードは取扱説明書に記載されています。
或いは、キーコードを調べるプログラムを使うのも便利です。

キーコードを調べるプログラムはとてもコンパクトなので、入力も楽です。Casio Basic入門3 ~ 8 で、その作り方を紹介しています。
 ⇒ fx-5800P プログラムライブラリ - キーコード取得
 ⇒ Casio Basic入門3


さて、[項目選択] 処理は、以下のような構造で作ります。ここで 変数 Z は、タイムゾーン変数です。

[変数 Z に基づく座標に ⇒マークを表示]
Do
Getkey→K

If K=86:Then
[右矢印キーが押された時の処理]
  1) ⇒マークを消去
  2) 変数 Z の値を更新
  3) 変数 Z に基づく新座標に⇒マークを表示

Else If K=83:Then
[左矢印キーが押された時の処理]
  1) ⇒マークを消去
  2) 変数 Z の値を更新
  3) 変数 Z に基づく新座標に⇒マークを表示

IfEnd:IfEnd
LpWhile K≠47


Do ~ LpWhile ループは、中に Getkey→K が入っていて、 [EXE] キー (キーコード 47) が押されない限り、ループを継続します。つまり、[EXE] キーを押すと、ループから抜け出て、タイムゾーン選択が確定するわけです。


Getkey で得られたキーコード(K) が86の時は、[右矢印キーが押された時の処理] を行います。
キーコード(K)が83の時は、[左矢印キーが押された時の処理] を行います。


矢印キーが押された時の処理
S=0、V=1 の状態で、タイムゾーン設定画面が表示されると、以下のようになります。


 EUR TIME ZONE
  WET  ⇒CET
  EET    FET
 <Lt-Rt>       ▶E


ここで、右矢印 [▶] キーが押されると、⇒ マークが左下の EET へ移動し、その後押されるたびに
EET → FET → WET → CET → EET (戻ってくる) → ・・・ 以降繰り返し・・・

ここで、左矢印 [◀] キーが押されると、⇒ マークが左の WET へ移動し、その後押されるたびに逆回りで、
WET - FET - EET - CET - WET (戻ってくる) - ・・・ 以降繰り返し ・・・

⇒ マークがそれぞれの位置へ移動する時の、タイムゾーン変数 Z の値、⇒ マークの位置(座標)は、以下のようになる。

変数⇒ の座標位置K=86K=83
タイムゾーン Z  X  Y [▶][◀]
WET022
CET182
EET223
FET383
 

Z の値の変化は、以下のプログラムで書けます。

[変数 Z に基づく座標に ⇒マークを表示]
Do
Getkey→K

If K=86:Then
[⇒マークの消去]
If Z=3:Then 0→Z
Else Z+1→Z
IfEnd

[⇒マークを移動先に表示]

Else If K=83:Then
[⇒マークの消去]
If Z=0:Then 3→Z
Else Z-1→Z
IfEnd

[⇒マークの表示位置移動]

IfEnd:IfEnd
LpWhile K≠47



⇒マークの位置は、現在選択されているタイムゾーンに対応します。つまり、タイムゾーン変数 Z の値から ⇒マークの座標を計算する作戦です。Z は、0 → 1 → 2 → 3 → 0 → 1 ・・・ と循環するので、その規則性を利用して計算できる筈です。

変数⇒ の座標位置K=86K=83
タイムゾーン Z  X  Y [▶][◀]
WET022
CET182
EET223
FET383
[▶][◀] キーが押された時、マークが移動する順序を、↓ で示しています。 

要するに、Z の値から、XY の値を計算できれば、とても簡単です。

正解(の1つ)を示します。

X = 2 + 6Z -12Int(Z/2)
Y = 2 + Int(Z/2)


この式は、基本的な考え方を知っていれば、簡単に導くことができます。

説明は後にして、先ずはプログラムを完成させます。⇒マークの消去と表示に関する部分を青文字で示します。

タイムゾーン設定サブルーチン TZS のプログラム 
Cls
Locate 15,4,"▶t"

Locate 16,4,"E"
Locate 1,4," <Lt-Rt>"


If M=6
Then V→Z
Locate 1,1," EUR TIME ZONE"
If S:Then
Locate 1,2,"  WEST  CEST"
Locate 1,3,"  EEST   FEST"
Else
Locate 1,2,"  WET    CET"
Locate 1,3,"  EET     FET"
IfEnd
IfEnd

2+6Z-12Int(Z÷2)→X
2+Int(Z÷2)→Y
Locate X,Y,"⇒"


Do
Getkey→K

If K=86:Then
Locate X,Y," "
If Z=3:Then 0→Z
Else Z+1→Z
IfEnd

2+6Z-12Int(Z÷2)→X
2+Int(Z÷2)→Y
Locate X,Y,"⇒"


Else If K=83:Then
Locate X,Y," "
If Z=0:Then 3→Z
Else Z-1→Z
IfEnd

2+6Z-12Int(Z÷2)→X
2+Int(Z÷2)→Y
Locate X,Y,"⇒"

IfEnd:IfEnd

LpWhile K≠47



式を使って Z から XY を求めなくても、If 文で書くことも出来ます。ただその場合は12個の If 文が必要となり、プログラムの記述量が多くなり入力も大変になります。

ちなみに、計算式の代わりに If 文を多く使ったプログラムは、以下になります。以下の記述方法ですと、計算式が合計6行で済むところ、If 文を使って同じことをするにのに30行の記述が必要になります。


If 文を多用した TZS のプログラム
Cls
Locate 15,4,"▶t"
Locate 16,4,"E"
Locate 1,4," <Lt-Rt>"

If M=6
Then V→Z
Locate 1,1," EUR TIME ZONE"
If S:Then
Locate 1,2,"  WEST  CEST"
Locate 1,3,"  EEST   FEST"
Else
Locate 1,2,"  WET   CET"
Locate 1,3,"  EET    FET"
IfEnd
IfEnd

If Z=0
Then 2→X:2→Y
Else If Z=1
Then 8→X:2→Y
Else If Z=2
Then 2→X:3→Y
Else If Z=3
Then 8→X:3→Y
IfEnd:IfEnd
IfEnd:IfEnd
Locate X,Y,"⇒"


Do
Getkey→K

If K=86:Then
Locate X,Y," "
If Z=3:Then 0→Z
Else Z+1→Z
IfEnd

If Z=0
Then 2→X:2→Y
Else If Z=1
Then 8→X:2→Y
Else If Z=2
Then 2→X:3→Y
Else If Z=3
Then 8→X:3→Y
IfEnd:IfEnd
IfEnd:IfEnd
Locate X,Y,"⇒"


Else If K=83
Then
Locate X,Y," "
If Z=0:Then 3→Z
Else Z-1→Z
IfEnd

If Z=0
Then 2→X:2→Y
Else If Z=1
Then 8→X:2→Y
Else If Z=2
Then 2→X:3→Y
Else If Z=3
Then 8→X:3→Y
IfEnd:IfEnd
IfEnd:IfEnd
Locate X,Y,"⇒"

IfEnd:IfEnd
LoWhile K≠47


私は、個人的に大量の同じ記述を繰り返すのは好きではなく、同じ内容を式で実現できれば、簡潔で構造が分かりやすいプログラムを書けると考えます。プログラムのサイズ(所用バイト数)も、記述量が少ない法がコンパクトになり、fx-5800P の限られたメモリにより多くのプログラムを格納できます。どう考えても、簡潔で構造が分かりやすく、さらにコンパクトなプログラムの方が良いと思うのですが、如何でしょうか?



⇒マークの削除と表示の座標を計算で求める方法

⇒マークを消去したり表示するための座標(X, Y) の計算方法が簡単でなければ、この方法を採用する意味がありません。

以下の表は、Z の値と X や Y の値の関係を示しています。

変数⇒ の座標位置K=86K=83
タイムゾーン Z  X  Y [▶][◀]
WET022
CET182
EET223
FET383
[▶][◀] キーが押された時、マークが移動する順序を、↓ で示しています。 


X を見てみると、Z が 1 づつ増えるに従って、2 と 8 を繰り返しています。
このような繰り返しパターンが見られるとき、剰余系の考え方が使えます。

Z を 2 で割った時の余りは、0 か 1 で、余りの数で Z を2つのグループに分けられます。
Z を 3 で割った時の余りは、0 か 1 か 2 で、余りの数で Z を3つのグループに分けられます。
 ・
 ・

Z を m で割った時の余りは、0, 1, 2, 3,・・・, m-2, m-1 で、余りの数で Z を m個のグループに分けられます。

繰り返しパターンが見られる時は、繰り返しを余りの数で分類できます。

今は、2つの繰り返しなので、余りが 0 か 1 のどちらかに分類できて、0 と 1 が交互に現れるパターンです。

ZrX
002
118
202
318

r は Z を 2 で割った余りだと分かります。

この r を 6 倍して 2 を足せば X になる、つまり、

6r + 2 = X

となります。

従って、r つまり 「Z を 2 で割った余り」を計算できれば、Z から X を求める式がわかります。

Z を m で割った余り r は、

r = Z - m×Int(Z/m)

です。Int( ) は、( )の中の数の整数部を取り出します。
この余りの式を覚えておくと、様々なところで使えて、とても便利です。

以上から、m=2 でよいので、

X = 6r + 2
  = 6(Z - m×Int(Z÷m)) + 2
  = 6(Z - 2×Int(Z÷2)) + 2
  = 2 + 6Z - 12Int(Z÷2)


と、式にできました。一見突拍子もない式に思えるのですが、汎用性のある考え方を知っていれば、簡単に求められました。



次に、Y を見てみると、Z が 1 づつ増える時、Y は階段のようにふえてゆきます。

StepFunc 

このパターンには、階段関数の考え方が役立ちます。

Z が 2 増えるたびに s が 1 づつ増える。
Z が 3 増えるたびにs が 1 づつ増える。
  ・
  ・
Z が m 増えるたびに s が 1 づつ増える。

今回の Z と Y には、このパターンがはっきりとみえます。

ZsY
002
102
213
313

Y = 2 + s 

なので、Z から階段パターンの s が求まると、Y を計算できます。

s = Int(Z÷m)

この式も、階段パターンで使える便利なものです。

上の例では m が 2 なので、

Y = 2 + s
  =
2 + Int(Z÷2)

従って、

X = 2 + 6Z -12Int(Z/2)
Y = 2 + Int(Z/2)


が得られます。

プログラムは、以下になります。

2 + 6Z -12Int(Z÷2)→X
2+ Int(Z÷2)→Y



さて、ここで作った TZS は、冒頭で作った メインルーチン A で、S や V の値を変更して動作確認ができます。
夏時間 S (0, 1) と ヨーロッパのタイムゾーン値 V (0, 1, 2, 3 )を変えて、動作確認をしてみましょう。 



今回までに作成したプログラムは、以下の通り(今回追加した部分を赤文字で示す):

 CcLinkerを使ってfx-5800Pに転送できるCCLファイルのダウンロード
 ※ CcLinker の紹介

メインルーチン:TZ のプログラム

9→P:17→Q
-1→J:0→G:0→U
0→S:0→T
1→V
P-V→P

Prog "TZM"

While 1

-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M
K=35⇒1→M
K=36⇒2→M
K=37⇒3→M
K=21⇒4→M

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


If M=0:Then
8→X:1→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→J
Else If M=1
Then
8→X:2→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→G
Else If M=2:
Then
8→X:3→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→U
Else If M=3 Or M=4
Then
Int(J÷100)→A
J-100A→B
IfEnd:IfEnd
IfEnd:IfEnd

If M=0:Then
A≧24⇒A-24→A
100A+B→J
A-P→C
C<0⇒C+24→C
100C+B→G
A-Q→C
C<0⇒C+24→C
100C+B→U
Else If M=1
Then
A≧24⇒A-24→A
100A+B→G
A+P→C
C≧24⇒C-24→C
100C+B→J
A+P-Q→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→U
Else If M=2
Then
A≧24⇒A-24→A
100A+B→U
A+Q→C
C≧24⇒C-24→C
100C+B→J
A+Q-P→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→G
Else If M=3
Then
If S:Then
0→S:P+1→P
Else
1→S:P-1→P
IfEnd
A-P→C
C<0⇒C+24→C
100C+B→G
Prog "TZM"
Else If M=4
Then
If T:Then
0→T:Q+1→Q
Else
1→T:Q-1→Q
IfEnd
A-Q→C
C<0⇒C+24→C
100C+B→U
Prog "TZM"
Else If M=6
Then Prog "TZS"
Z→V:9-S-Z→P
Int(J÷100)→A
J-100A→B
A-P→C
C<0⇒C+24→C
100C+B→G:Cls
Prog "TZM"

IfEnd:IfEnd
IfEnd:IfEnd
IfEnd:IfEnd

Prog "TZD"

WhileEnd




サブルーチン:TZM のプログラム (画面表示)
Locate 1,1,"0:JST"
Locate 1,2,"1:CET"
Locate 1,3,"2:PST"
Locate 13,2,"3:"
Locate 13,3,"4:"
Locate 1,4,"<AC>:QUIT"

If V=0:Then
Locate 3,2,"W"
Else If V=1
Then Locate 3,2,"C"
Else If V=2
Then Locate 3,2,"E"
Else If V=3
Then Locate 3,2,"F"
IfEnd:IfEnd
IfEnd:IfEnd


If S:Then
Locate 5,2,"ST"
Locate 15,2,"DL"
Else
Locate 5,2,"T "
Locate 15,2,"ST"
IfEnd

If T:Then
Locate 4,3,"D"
Locate 15,3,"DL"
Else
Locate 4,3,"S"
Locate 15,3,"ST"
IfEnd




サブルーチン:TZS のプログラム (タイムゾーン設定)
Cls
Locate 15,4,"▶t"
Locate 16,4,"E"
Locate 1,4," <Lt-Rt>"

If M=6
Then V→Z
Locate 1,1," EUR TIME ZONE"
If S:Then
Locate 1,2,"  WEST  CEST"
Locate 1,3,"  EEST   FEST"
Else
Locate 1,2,"  WET   CET"
Locate 1,3,"  EET    FET"
IfEnd
IfEnd

2+6Z-12Int(Z÷2)→X
2+Int(Z÷2)→Y
Locate X,Y,"⇒"

Do
Getkey→K
If K=86:Then
Locate X,Y," "
If Z=3:Then 0→Z
Else Z+1→Z
IfEnd
2+6Z-12Int(Z÷2)→X
2+Int(Z÷2)→Y
Locate X,Y,"⇒"
Else If K=83
Then
Locate X,Y," "
If Z=0:Then 3→Z
Else Z-1→Z
IfEnd
2+6Z-12Int(Z÷2)→X
2+Int(Z÷2)→Y
Locate X,Y,"⇒"
IfEnd:IfEnd
LpWhile K≠47




サブルーチン:TZC のプログラム (時間を「時」と「分」に分離):変更なし
If Z<100:Then
Z→X:0→Y
Else
Int(Z÷100)→X
Z-100X→Y
IfEnd




サブルーチン TZD のプログラム (時間の表示):変更なし
J=-1⇒Return

Locate 8,1,"0000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U




今回は、ヨーロッパのタイムゾーンを変更できるように、機能追加を行いました。
次回は、北米のタイムゾーンも変更できるようにします。



つづく...


Casio Basic入門30 / 目次



応援クリックをお願いします。励みになるので...
にほんブログ村 IT技術ブログ 開発言語へ


 



keywords: fx-5800PCasioBasic、世界時間換算, プログラミング入門プログラム関数電卓

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



関連記事

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

Casio Basic入門28

Casio Basic入門
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します
最終更新: 2018/11/03

 4. CasioBasicを使ってみる(続き)

Chapter 5

◆ Chapter 5 の目標: サブルーチンを使いこなす

前回: Casio Basic入門27 を見る


[2018/11/03 追記]
 ソースコードの誤記を見直しました
 CcLinker を使ってfx-5800Pに転送して使えるプログラムファイル(CCLファイル)をダウンロードできます。


前回までに、日本、ドイツ、ロサンゼルス(LA) の時間を夏時間を含めて換算できるようになりました。
今回は、ドイツ時間 (中央ヨーロッパ時間)  に限らず、ヨーロッパ内の4つのタイムゾーンを設定する機能を追加します。


今回までで完成させるプログラムを一番下に掲載しているので、先にそれを見てみて分かるなら、先に進むのも良いでしょう。



Chapter5-6
キー長押しによる機能呼び出し

39-TZ5_main 

このメイン画面では、1:CET は、中央ヨーロッパの標準時間を示しています。

ヨーロッパにあるタイムゾーンのうち、下記の4つのタイムゾーンに切り替えられるように機能を追加してゆきます。

タイムゾーン標準時間 夏時間 
西ヨーロッパ時間WETWEST
中央ヨーロッパ時間CETCEST
東ヨーロッパ時間EETEEST
極東ヨーロッパ時間FETFEST

EU-TZ 
Time-J.net 世界時計 - 世界の時間と時差 - ヨーロッパのタイムゾーンについて から引用


ここで [1] キーを長押しすると、下に示すような 「ヨーロッパのタイムゾーン選択画面」を表示させるようにします。

42-TZSelect_EU 

ここで、左矢印キー [◀] か 右矢印キー [▶] を押すと、⇒ マークが移動し、[EXE] キーを押すと ⇒ マークで示されたタイムゾーンが確定されるようにします。この追加機能は、サブルーチンで実現することにします。このサブルーチンを、ファイル名 TZS (タイムゾーン設定サブルーチン) とします。設定 = Setting なので、TZ + S = TZS です。

ヨーロッパのタイムゾーン変数に、新たに V を使い、その値を以下のように決めます。

タイムゾーン標準時間 変数 V の値
西ヨーロッパ時間WET0
中央ヨーロッパ時間CET1
東ヨーロッパ時間EET2
極東ヨーロッパ時間FET3

サブルーチン TZS では、変数 V の値を変更します。

TZS が終了してメインルーチンに戻ってきたら、必要な時間計算を行い、最後に時間表示サブルーチン TZD を呼び出して、変数 V の値に従って時間表示をさせます。そこで、TZD を修正します。

以上が今回の機能追加の内容で、具体的には以下のように進めます。

1.初期化処理
新たに、ヨーロッパのタイムゾーン変数 V を追加する。それに合わせて変数の初期化を見直す。
メイン画面表示サブルーチン TZM にも機能追加する。

2.メニュー番号取得処理
今回は、[1] キーの長押しを検出し、検出されたときに、メニュー変数 M に 6 を入れる(5 を飛ばして 6 としたが、違う処理によることから、6 とした)。

3.入力処理
M=6 の時は、キー入力処理は行なわない。但し、ヨーロッパのタイムゾーン変更に伴って、メイン画面のタイムゾーン表示を変更するために、メイン画面表示サブルーチン TZM を呼び出す(これに合わせて TZM を修正する)。

4.時間の計算
M=6 の時、タイムゾーン変更に合わせてヨーロッパ時間を計算する。日本時間と北米時間には影響が無いので、これらの計算は行わない。

5.時間表示の更新
時間表示サブルーチン TZD を用いて、日本時間、ヨーロッパ時間、アメリカ時間の表示を更新する。

6.ループ構造
既にある While 1 ~ WhileEnd ループの中に、上記追加コードを入れる。


メインルーチンの擬似的なプログラムは、以下になります。今回追加・修正するところが、はっきりと分かります。


[初期化処理]

Prog "TZM"  [メイン画面表示]

While 1

  [メニュー番号取得処理]

  
[ [1] キー長押しを検出し メニュー番号 M = 6 とする処理]

  If M=0:Then
    [日本時間入力処理] (時間から「時」と「分」の分離も行う)
  Else If M=1:Then
    [ドイツ時間入力処理] (時間から「時」と「分」の分離も行う)
  Else If M=2:Then
    [LA時間入力処理] (時間から「時と「分」の分離も行う)
  Else If M=3:Then
    キー入力処理は行わない。時間から「時」と「分」の分離のみ行う
  Else If M=4:Then
    キー入力処理は行わない。時間から「時」と「分」の分離のみ行う
  IfEnd:IfEnd
  IfEnd:IfEnd
  IfEnd

  If M=0:Then
    [時間計算]
  Else If M=1:Then
    [時差計算]
  Else If M=2:Then
    [時間計算]
  Else If M=3:Then
    [時間計算]
  Else If M=4:Then
    [時間計算]
  
Else If M=6:Then
    Prog "TZS"  
[ヨーロッパタイムゾーン設定]
    [時間計算]
    Prog "TZM"  
[メイン画面表示]
  IfEnd:
IfEnd
  IfEnd:IfEnd
  IfEnd:IfEnd

  
Prog "TZD"    [時間の再表示]

WhileEnd


(赤文字は追加・修正部分)



1.初期化処理
ドイツの時差は8時間なので、これまでドイツの時差を示す変数 P を 8 で初期化していました。今後は、変数 P をヨーロッパの各タイムゾーンに合わせた時差として使います。一番西にある西ヨーロッパ標準時間の時差は9時間なので、P を 9 で初期化;
9→P 
と変更します。

プログラム起動時に、ドイツの時間を表示させたいと言う私の好みから、ヨーロッパのタイムゾーン変数 V を 1 で初期化しておき、P と V から P の初期値をドイツのある中央ヨーロッパ時間に設定します。
1→V
P-V→P

を追加します。

もし、プログラム起動時にイギリス時間を表示したい場合は、V を 0
で初期化しておきましょう。

次に、初期表示の変更を行います。初期表示はサブルーチン TZM で受け持っているので、これを複数タイムゾーンに対応するように修正します。 TZM 修正内容は以下で説明します。



2.メニュー番号取得処理 - キー長押し処理


[1] キー長押しを検出して、メニュー変数 M5 を入れます。

先ずは、以下のプログラムを見てください。今回追加した長押しを検出する部分赤文字にしています。

メニュー番号取得処理のソースコード
-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M
K=35⇒1→M
K=36⇒2→M
K=37⇒3→M
K=21⇒4→M

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


先ずは、これまで作った緑色の部分で、現在押されているキーを検出します。

その後に追加された6行のプログラム(赤文字)では、

[1] キーがまだ押されている時はWhile ループに入り、所定の回数(ここでは9回)ループを回った時だけメニュー変数 M に 6 が入り、それ以外は M は 1 のまま、となります。

C=9⇒BreakC=9⇒6→M の両方に出てくる C=9 の部分で、長押し検出のための判定時間を変えられます。私が実際に触ったところでは、C=9 程度が良いと思うので、9 にしていますが、少ない値にして反応を速くすることもできます。反応が早すぎると、[1] キーを短く押したと思っても長押しと判定されるので、操作性が悪くなります。

While ループは、ループ継続の判定をループの最初で行います。一方 Do ループは、ループの最後で継続判定を行います。
今回は、不必要ならループに入らないようにしたいので、While ループを使います。
 ⇒ Casio Basic コマンドリファレンス: While ~ WhileEnd
 ⇒ Casio Basic コマンドリファレンス: Do ~ LpWhile


Break コマンドは、While ループや Do ループから強制的に抜ける時に使います。
 ⇒ Casio Basic コマンドリファレンス: Break


キーの長押し判定のポイントは、

1) 長押し判定部より前に、通常のキー判定があること
長押し判定部に入る前に、メニュー番号 M は既に 1 と決まっている。

2) While ループに入る段階で、[1] キーが押されているかどうかを判定する
普通に [1] キーを押した場合と、他のキーが押されている場合は、このループに入らず、[1] キーの長押しではないと判断する。

3) While ループを出る条件が2つある
所定回数(9回)ループを回った時 (C=9⇒Break) と、[1] キーから指が離れた時 (Getkey が 35 を返さなくなった時) の2つが、ループを出る条件です。

4) While ループを出た後、ループを回った回数が9回かどうかで長押し判定を行う
ループから出たところに、C=9⇒6→M があります。ループを9回回った時のみ、メニュー番号 M に 6 を入れています。


これで、[1] キーが長押しされたことを確実に検出し、長押しの時だけ M = 6 となり、それ以外は M = 1 となります。
さらに、長押しの判定時間も変えられます(上で説明した通り)。

長押し判定部分は、以下のように書くこともできます。

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


プログラムの行数が長くなるので、以降はこのような記述にします。


なお、キー長押しについては、同じ手法を以下でも紹介しています。
 ⇒ Casio Basic 入門22 - 和暦・西暦換算プログラムを作る



3.入力処理

入力処理を行わないので、[入力処理ブロック] には何もプログラムを書きません。



4.時間計算

先ず、タイムゾーン設定サブルーチン TZS を呼び出します。TZS はタイムゾーン変数 Z に 0、1、2、3 のいずれかの値を入れてから終了します。今回は、サブルーチン TSZ を新たに作ります。

次に、TZS が設定した変数 Z に基づいて、メインルーチンのヨーロッパタイムゾーン変数 V を設定し、ヨーロッパ時差変数 P を算出します。そして、時差 P から、選んだタイムゾーンの時間を計算します。

最後に、メイン画面表示サブルーチン TZM を呼び出して、選んだタイムゾーンに合わて画面を再表示します。これに合わせて TZM を変更します。

最初に、メインルーチンの [時間計算] ブロックに追加するプログラムを示します。今回変更するメインルーチン全体は、一番下に掲載しています。

メインルーチンに追加するプログラム
Else If M=6
Then Prog "TZS"
Z→V:9-S-Z→P
Int(J÷100)→A
J-100A→B
A-P→C
C<0⇒C+24→C
100C+B→G
Cls
Prog "TZM"
IfEnd


最初に、タイムゾーン設定サブルーチン TZS を呼び出します。
  Prog "TZS"
TZS のプログラムを一番下に掲載していますので、とりあえず入力して使えるようにしてください。詳しくは次回説明します。TZS では、4つのタイムゾーンから1つ選んで確定すると、変数 Z にタイムゾーン値を入れて終了します。
ヨーロッパのタイムゾーン値 V は 0、1、2、3 のいずれかで、一番西が 0、東にゆくにつれて 1、2、3 となります。

変数 Z は使い捨て変数で、プログラムの動作中にその値が変化しても良いように使っている変数です。一方、変数 V はヨーロッパのタイムゾーン値を格納する予約変数として使っていて、その値は勝手に変更されては困ります。
そこで、TZS の直後で、Z の値を V に入れておきます。続いて、ヨーロッパ時差の変数 P を計算します。ここでは夏時間も考慮して、夏時間フラグ S も利用しています。ヨーロッパの西の端、つまり西ヨーロッパの時差は、日本からみて9時間です。夏時間では時差が1時間減り、タイムゾーン値を引き算すれば、選択したタイムゾーンの時差が分かります。
  Z→V:9-S-Z→P

タイムゾーンを変更しても、日本時間は変わりません。そこで、日本時間を基準に、時差 P から、選択したタイムゾーンの時間を計算します。現在の日本時間 J から「時」: A と 「分」: B を算出します。この計算は、既に他でも行っているのと同じです。
  Int(J÷100)→A
  J-100A→B


選択したタイムゾーンの時差が P なので、A - P が、その地域の「時」になります。但しこの結果が負になる場合があって、まだ前日であることを意味します。そこで、A - P が 0 未満の時は 24 を加えると正しい時間になります。この計算も、、これまでに行っているのと同じです。
  A-P→C
  C<0⇒C+24→C


選んだタイムゾーンの「時」: C が分かったので、ヨーロッパ時間 G が計算できます。これも、これまでに行っているのと同じです。
  100C+B→G

プログラムがここまで進んできても、タイムゾーン設定画面が表示されたままです。そこで、Cls コマンドで画面を消去します。
  Cls
 ⇒ Casio Basic コマンドリファレンス: Cls

最後に、メイン画面の際表示を行うために、メイン画面表示サブルーチン TZM を呼び出します。
  Prog "TZM"


TZS を、ヨーロッパの4つのタイムゾーンに合わせて変更します。
中央ヨーロッパ(ドイツ)の夏時間への対応は既に済んでいて、以下のような別のタイムゾーンの略称に対しても、夏時間への対応部分はそのまま使えます。

タイムゾーン標準時間 夏時間 変数 V の値
西ヨーロッパ時間WETWEST0
中央ヨーロッパ時間CETCEST1
東ヨーロッパ時間EETEEST2
極東ヨーロッパ時間FETFEST3

タイムゾーンが変われば、略称の1文字目を変更すれば良く、標準時間と夏時間の両方に対応できることが分かります。
そこで、V の値に応じて、赤く示したアルファベットのみを Locate コマンドで上書きします。

画面表示サブルーチン TZM のプログラム
Locate 1,1,"0:JST"
Locate 1,2,"1:CET"
Locate 1,3,"2:PST"
Locate 13,2,"3:"
Locate 13,3,"4:"
Locate 1,4,"<AC>:QUIT"

If V=0:Then
Locate 3,2,"W"
Else If V=1
Then Locate 3,2,"C"
Else If V=2
Then Locate 3,2,"E"
Else If V=3
Then Locate 3,2,"F"
IfEnd:IfEnd
IfEnd:IfEnd


If S:Then
Locate 5,2,"ST"
Locate 15,2,"DL"
Else
Locate 5,2,"T "
Locate 15,2,"ST"
IfEnd

If T:Then
Locate 4,3,"D"
Locate 15,3,"DL"
Else
Locate 4,3,"S"
Locate 15,3,"ST"
IfEnd


(追加部分は赤文字



5.時間の再表示

時間の再表示は、サブルーチン TZD で行います。これについては変更の必要がありません。

サブルーチン TZD のプログラム: 変更なし
J=-1⇒Return

Locate 8,1,"000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U




今回までに作成したプログラムは、以下の通り(今回追加した部分を赤文字で示す):

 CcLinkerを使ってfx-5800Pに転送できるCCLファイルのダウンロード
 ※ CcLinker の紹介

メインルーチン:TZ のプログラム
9→P:17→Q
-1→J:0→G:0→U
0→S:0→T
1→V
P-V→P

Prog "TZM"

While 1

-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M
K=35⇒1→M
K=36⇒2→M
K=37⇒3→M
K=21⇒4→M

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


If M=0:Then
8→X:1→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→J
Else If M=1
Then
8→X:2→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→G
Else If M=2
Then
8→X:3→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→U
Else If M=3 Or M=4
Then
Int(J÷100)→A
J-100A→B
IfEnd:IfEnd
IfEnd:IfEnd

If M=0:Then
A≧24⇒A-24→A
100A+B→J
A-P→C
C<0⇒C+24→C
100C+B→G
A-Q→C
C<0⇒C+24→C
100C+B→U
Else If M=1
Then
A≧24⇒A-24→A
100A+B→G
A+P→C
C≧24⇒C-24→C
100C+B→J
A+P-Q→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→U
Else If M=2
Then
A≧24⇒A-24→A
100A+B→U
A+Q→C
C≧24⇒C-24→C
100C+B→J
A+Q-P→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→G
Else If M=3
Then
If S:Then
0→S:P+1→P
Else
1→S:P-1→P
IfEnd
A-P→C
C<0⇒C+24→C
100C+B→G
Prog "TZM"
Else If M=4
Then
If T:Then
0→T:Q+1→Q
Else
1→T:Q-1→Q
IfEnd
A-Q→C
C<0⇒C+24→C
100C+B→U
Prog "TZM"
Else If M=6
Then Prog "TZS"
Z→V:9-S-Z→P
Int(J÷100)→A
J-100A→B
A-P→C
C<0⇒C+24→C
100C+B→G:Cls
Prog "TZM"

IfEnd:IfEnd
IfEnd:IfEnd
IfEnd:IfEnd

Prog "TZD"

WhileEnd




サブルーチン:TZM のプログラム (画面表示)
Locate 1,1,"0:JST"
Locate 1,2,"1:CET"
Locate 1,3,"2:PST"
Locate 13,2,"3:"
Locate 13,3,"4:"
Locate 1,4,"<AC>:QUIT"

If V=0:Then
Locate 3,2,"W"
Else If V=1
Then Locate 3,2,"C"
Else If V=2
Then Locate 3,2,"E"
Else If V=3
Then Locate 3,2,"F"
IfEnd:IfEnd
IfEnd:IfEnd


If S:Then
Locate 5,2,"ST"
Locate 15,2,"DL"
Else
Locate 5,2,"T "
Locate 15,2,"ST"
IfEnd

If T:Then
Locate 4,3,"D"
Locate 15,3,"DL"
Else
Locate 4,3,"S"
Locate 15,3,"ST"
IfEnd




サブルーチン:TZS のプログラム (タイムゾーン設定)
Cls
Locate 15,4,"▶t"
Locate 16,4,"E"
Locate 1,4," <Lt-Rt>"

If M=6
Then V→Z
Locate 1,1," EUR TIME ZONE"
If S:Then
Locate 1,2,"  WEST  CEST"
Locate 1,3,"  EEST   FEST"
Else
Locate 1,2,"  WET   CET"
Locate 1,3,"  EET    FET"
IfEnd
IfEnd

2+6Z-12Int(Z÷2)→X
2+Int(Z÷2)→Y
Locate X,Y,"⇒"

Do
Getkey→K
If K=86:Then
Locate X,Y," "
If Z=3:Then 0→Z
Else Z+1→Z
IfEnd
2+6Z-12Int(Z÷2)→X
2+Int(Z÷2)→Y
Locate X,Y,"⇒"
Else If K=83
Then
Locate X,Y," "
If Z=0:Then 3→Z
Else Z-1→Z
IfEnd
2+6Z-12Int(Z÷2)→X
2+Int(Z÷2)→Y
Locate X,Y,"⇒"
IfEnd:IfEnd
LpWhile K≠47




サブルーチン:TZC のプログラム (時間を「時」と「分」に分離):変更なし
If Z<100:Then
Z→X:0→Y
Else
Int(Z÷100)→X
Z-100X→Y
IfEnd




サブルーチン TZD のプログラム (時間の表示):変更なし
J=-1⇒Return

Locate 8,1,"0000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U




今回は、ヨーロッパのタイムゾーンを変更できるように、機能追加を行いました。
次回は、アメリカのタイムゾーンも変更できるようにします。



つづく...


Casio Basic入門29 / 目次




応援クリックをお願いします。励みになるので...
にほんブログ村 IT技術ブログ 開発言語へ


 


keywords: fx-5800PCasioBasic、世界時間換算, プログラミング入門プログラム関数電卓

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



関連記事

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

Casio Basic入門27

Casio Basic入門
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します
最終更新: 2018/11/03

 4. CasioBasicを使ってみる(続き)

Chapter 5

◆ Chapter 5 の目標: サブルーチンを使いこなす

前回: Casio Basic入門26 を見る


[2018/11/03 追記]
 ソースコードの誤記を見直しました
 CcLinker を使ってfx-5800Pに転送して使えるプログラムファイル(CCLファイル)をダウンロードできます。


前回は、ドイツ時間を夏時間や標準時間に切り替える機能、それに伴って正しい時間を表示する機能を追加しました。
今回は、前回とほど同様の方針で、LA時間を夏時間に切り替える機能を追加してゆきます。


今回完成させるプログラムを一番下に掲載しているので、先にそれを見て、分かれば先に進んでも良いでしょう。



Chapter5-5
少し異なるルーチンを、わかりやすく追加する(2)

ロサンゼルス時間の夏時間切り替え機能をメニュー番号4にします。同時に、現在は夏時間なのか、標準時間なのかを表示するようにします。

今回は、以下のように 2:PST の右に LA時間の夏時間l設定用のメニューを追加します。

39-TZ5_main    


標準時間を ST、夏時間を DL と表示することにしています。
ST は Standard Time (標準時間) の略で、DL は Daylight Saving (アメリカ流の夏時間の表現) からとっています。

上の画面は、起動時の初期表示で、起動時には標準時間となるようにします。そして、[4] キーを押したら夏時間に切り替わり、もう一度押したら標準時間に戻る...といった動作(トグル動作)にします。

プログラム内部で、現在がLAの夏時間かどうかがわかるようにするために、新しい変数 T を夏時間フラグとして用い、

T = 0 時は標準時間で、T = 1 の時は夏時間

と決めます。


今回は、[4] キーを押してLA時間を夏時間に変更し、ロサンゼルス時間を計算し、その結果を画面表示する機能を追加します。

1.初期化処理
先ず、今回追加する新しい変数 T (ヨーロッパの夏時間フラグ)の初期化を行う。
次に、初期表示の変更を行います。初期表示はサブルーチン TZM で受け持っているので、これを修正する。

2.メニュー番号取得処理
ループの中で Getkey コマンドを使って、[4] キーが押された時、メニュー変数 M4 を入れる。
なお、この処理では、何かキーが押されるまでプログラムは先に進まず、入力待ちの状態になる。

3.入力処理
M=4 の時は、キー入力処理は行なわない。但し、LA時間 U が、夏時間か標準時間に変更されるので、U から「時」と「分」を分離する。

4.時間の計算
M=4 の時、変更されたLA時間を計算する。日本時間とドイツ時間には影響が無いので、これらの計算は行わない。

5.時間表示の更新
時間表示サブルーチン TZD を用いるので、これまでのように日本時間、ドイツ時間、LA時間の表示を更新する。

6.ループ構造
既にある While 1 ~ WhileEnd ループの中に、上記追加コードを入れる。


メインルーチンの擬似的なプログラムは、以下になります。今回の機能追加に必要な修正部分がはっきりします。

[初期設定]

Prog "TZM"  [メイン画面表示]

While 1

  [メニュー番号取得処理]

  If M=0:Then
    [日本時間入力処理] (時間から「時」と「分」の分離も行う)
  Else If M=1:Then
    [ドイツ時間入力処理] (時間から「時」と「分」の分離も行う)
  Else If M=2:Then
    [LA時間入力処理] (時間から「時と「分」の分離も行う)
  Else If M=3:Then
    キー入力処理は行わない。時間から「時」と「分」の分離のみ行う
  Else If M=4:Then
    キー入力処理は行わない。時間から「時」と「分」の分離のみ行う
  IfEnd:
IfEnd
  IfEnd:IfEnd
  IfEnd

  If M=0:Then
    [時間計算]
  Else If M=1:Then
    [時差計算]
  Else If M=2:Then
    [時間計算]
  Else If M=3:Then
    [時間計算]
  Else If M=4:Then
    [時間計算]
  IfEnd:
IfEnd
  IfEnd:IfEnd
  IfEnd

  Prog "TZD"  
[時間の再表示]

WhileEnd


(赤文字は追加・修正部分)



1.初期化処理
今回は、ドイツの夏時間フラグ T を追加したので、これを 0 で初期化しておきます。
T = 0 は、標準時間であることを示します。

0→T

を追加します。



2.メニュー番号取得処理


[4] キーを押すと、メニュー変数 M に 4 を設定する。

メニュー番号取得処理のプログラム
-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M
K=35⇒1→M
K=36⇒2→M
K=37⇒3→M
K=21⇒4→M 
[今回追加]


[4] キーのキーコードは 21 です。




3.入力処理

ドイツ時間を、夏時間 - 標準時間 に切り替えるのみで、キー入力処理は行いません。ドイツ時間が切り替わっても、日本時間やロサンゼルス時間には影響が無いので、この時点での日本時間 J を分離して、「時」を 変数 A に、「分」を変数 B に入れておきます。

Int(J÷100)→A
J-100A→B"


この部分は、M = 3 の時のドイツの夏時間設定と同じなので、Else If M=4IdEnd を追加せずに、以下のようにします。

Else If M=3
Then
Int(J÷100)→A
J-100A→B
IfEnd


この部分を以下のように修正します。

Else If M=3 Or M=4
Then
Int(J÷100)→A
J-100A→B
IfEnd


Or M=4 を追加するだけです。



4.時間計算

最初に、今回追加するプログラムを示します。

Else If M=4
Then
If T:Then
0→T:Q+1→Q
Else
1→T:Q-1→Q
IfEnd
A-Q→C
C<0⇒C+24→C
100C+B→U
Prog "TZM"
IfEnd


ドイツの夏時間計算のルーチンで、P を Q に置き換え、G を U に置き換えるだけです。つまり、基本ロジックは全く同じです。

一応、説明をします。

最初の部分は、夏時間フラグの変更と時差の変更を行います。

  If T:Then
  0→T:Q+1→Q
  Else
  1→T:Q-1→Q
  IfEnd


現状が夏時間の時は、T=1 になっています。
  If T:Then
は、T1 の時の分岐処理なので、
夏時間フラグ:0 にし、時差:Q を1時間増やします。

Else 以下は、現状が標準時間の時の処理で、
夏時間フラグ:T1 にし、時差:Q を1時間減らしています。


この後に続く処理では、LA時間を計算し、時間表示サブルーチン TZM を呼び出します。

  A-Q→C
  C<0⇒C+24→C
  100C+B→U
  Prog "TZM"


入力処理のところで、現在の日本時間 J から「時」:A と「分」 B を算出しています。
LA時間は、日本時間の「時」 A と時差 から計算するので、A - Q でLA時間の「時」が得られます。

この計算の結果が負の数になる場合は、LAはまだ前日と言うことになります。この場合は、得られた負の数に 24 を足せば、24時制の「時」になります。

そこで、A - Q を一旦変数 C に入れておき、それが負の数なら 24 を足しておきます。
   A-Q→C
   C<0⇒C+24→C


LA時間:U は、100C + B で計算できます。
   100C+B→U 

最後に、サブルーチン TZM を呼び出す
   Prog "TZM"


さて、画面表示サブルーチン TZM をLAの夏時間に対応するように変更します。

サブルーチン TZM のプログラム
Locate 1,1,"0:JST"
Locate 1,2,"1:CET"
Locate 1,3,"2:PST"
Locate 13,2,"3:"
Locate 13,3,"4:"
Locate 1,4,"<AC>:QUIT"


If S:Then
Locate 5,2,"ST"   
[1:CET を 1:CEST に表示を切り替える]
Locate 15,2,"DL"  
[3:ST を 3:DL に表示を切り替える]
Else
Locate 5,2,"T "   
[1:CEST を 1:CET に表示を切り替える]
Locate 15,2,"ST"  
[3:DL を 3:ST に表示を切り替える]
IfEnd


If T:Then
Locate 4,3,"D"    
[2:PST を 2:PDT に表示を切り替える]
Locate 15,3,"DL"  
[4:ST を 4:DL に表示を切り替える]
Else
Locate 4,3,"S"    
[2:PDT を 1:PST に表示を切り替える]
Locate 15,3,"ST"  
[4:DL を 4:ST に表示を切り替える]
IfEnd


(赤文字は追加分)

アメリカの標準時間と夏時間の略称は、以下のように共に3文字です。

そこで、略称の2文字目を T と D で切り替えると、標準時間と夏時間の略称表示を切り替えられ、上のプログラムをこれを実行しています。

タイムゾーン標準時間 夏時間 
太平洋時間PSTPDT
山岳部時間MSTMDT
中央部時間CSTCDT
東部時間ESTEDT



5.時間の再表示


時間の再表示は、サブルーチン TZD で行います。これについては変更の必要がありません。

サブルーチン TZD のプログラム
J=-1⇒Return

Locate 8,1,"000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U




今回までに作成したプログラムは、以下の通り(今回追加した部分を赤文字で示す):

 CcLinkerを使ってfx-5800Pに転送できるCCLファイルのダウンロード
 ※ CcLinker の紹介

メインルーチン:TZ のプログラム
8→P:17→Q
-1→J:0→G:0→U
0→S:0→T
Prog "TZM"

While 1

-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M
K=35⇒1→M
K=36⇒2→M
K=37⇒3→M
K=21⇒4→M

If M=0:Then
8→X:1→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→J
Else If M=1
Then
8→X:2→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→G
Else If M=2
Then
8→X:3→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→U
Else If M=3 Or M=4
Then
Int(J÷100)→A
J-100A→B
IfEnd:IfEnd
IfEnd:IfEnd

If M=0:Then
A≧24⇒A-24→A
100A+B→J
A-P→C
C<0⇒C+24→C
100C+B→G
A-Q→C
C<0⇒C+24→C
100C+B→U
Else If M=1
Then
A≧24⇒A-24→A
100A+B→G
A+P→C
C≧24⇒C-24→C
100C+B→J
A+P-Q→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→U
Else If M=2
Then
A≧24⇒A-24→A
100A+B→U
A+Q→C
C≧24⇒C-24→C
100C+B→J
A+Q-P→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→G
Else If M=3
Then
If S:Then
0→S:P+1→P
Else
1→S:P-1→P
IfEnd
A-P→C
C<0⇒C+24→C
100C+B→G
Prog "TZM"
Else If M=4
Then
If T:Then
0→T:Q+1→Q
Else
1→T:Q-1→Q
IfEnd
A-Q→C
C<0⇒C+24→C
100C+B→U
Prog "TZM"

IfEnd:IfEnd
IfEnd:IfEnd
IfEnd

Prog "TZD"

WhileEnd




サブルーチン:TZM のプログラム (画面表示)
Locate 1,1,"0:JST"
Locate 1,2,"1:CET"
Locate 1,3,"2:PST"
Locate 13,2,"3:"
Locate 13,3,"4:"
Locate 1,4,"<AC>:QUIT"

If S:Then
Locate 5,2,"ST"
Locate 15,2,"DL"
Else
Locate 5,2,"T "
Locate 15,2,"ST"
IfEnd

If T:Then
Locate 4,3,"D"
Locate 15,3,"DL"
Else
Locate 4,3,"S"
Locate 15,3,"ST"
IfEnd




サブルーチン:TZC のプログラム (時間を「時」と「分」に分離):変更なし
If Z<100:Then
Z→X:0→Y
Else
Int(Z÷100)→X
Z-100X→Y
IfEnd




サブルーチン TZD のプログラム (時間の表示):変更なし
J=-1⇒Return

Locate 8,1,"0000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U




今回は、ロサンゼルスの夏時間設定機能を追加しました。
次回は、ヨーロッパのタイムゾーンを変更できるように、機能追加を行います。



つづく...


Casio Basic入門28 / 目次




応援クリックをお願いします。励みになるので...
にほんブログ村 IT技術ブログ 開発言語へ


 


keywords: fx-5800PCasioBasic、世界時間換算, プログラミング入門プログラム関数電卓

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



関連記事

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

Casio Basic入門26

Casio Basic入門
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します
最終更新: 2018/11/03

 4. CasioBasicを使ってみる(続き)

Chapter 5

◆ Chapter 5 の目標: サブルーチンを使いこなす

前回: Casio Basic入門25 を見る


[2018/11/03 追記]
 ソースコードの誤記を見直しました
 CcLinker を使ってfx-5800Pに転送して使えるプログラムファイル(CCLファイル)をダウンロードできます。


前回は、日本時間、ドイツ時間、LA時間のいずれかを入力すると、換算したそれぞれの時間を表示するところまで作りました。
今回は、ドイツ時間を夏時間や標準時間に切り替える機能、それに伴って正しい時間を表示する機能を追加してゆきます。

今回までで完成させるプログラムを一番下に掲載しているので、先にそれを見て分かれば、先に進んでも良いでしょう。



Chapter5-4
少し異なるルーチンを、わかりやすく追加する

今回は、ドイツの夏時間切り替え機能をメニュー番号3にします。同時に、現在は夏時間なのか、標準時間なのかを表示するようにします。

具体的には、以下のように 1:CET の右に ドイツ時間の夏時間設定用のメニューを追加表示します。

38-TZ4_main   


標準時間を ST、夏時間を DL と表示することにします。
ST は Standard Time (標準時間) の略で、DL は DayLight saving (アメリカでの夏時間の表現) からとりました。

上の画面は、起動時の初期表示で、起動時には標準時間となるようにします。そして、[3] キーを押したら夏時間に切り替わり、もう一度押したら標準時間に戻る...といった動作(トグル動作)にします。

プログラム内部で、現在がドイツの夏時間かどうかがわかるようにするために、新しい変数 S を夏時間フラグとして用い、

S = 0 時は標準時間で、S = 1 の時は夏時間

と決めます。


今回は、[3] キーを押してドイツ時間を夏時間に変更し、ドイツ時間を計算し、その結果を画面表示する機能を追加します。

1.初期化処理
先ず、今回追加する新しい変数 S (ヨーロッパの夏時間フラグ)の初期化を行う。
次に、初期表示の変更を行います。初期表示はサブルーチン TZM で受け持っているので、これを修正する。

2.メニュー番号取得処理
ループの中で Getkey コマンドを使って、[3] キーが押された時、メニュー変数 M に 3 を入れる。
なお、この処理では、何かキーが押されるまでプログラムは先に進まず、入力待ちの状態にする。

3.入力処理
M=3 の時は、入力処理は行なわない。但し、ドイツ時間 G が、夏時間か標準時間に変更されるので、G から「時」と「分」を分離する。

4.時間の計算
M=3 の時、変更されたドイツ時間を計算する。日本時間とロサンゼルス時間には影響が無いので、これらの計算は行わない。

5.時間表示の更新
時間表示サブルーチン TZD を用いて、これまでのように日本時間、ドイツ時間、ロサンゼルス時間の表示を更新する。

6.ループ構造
既にある While 1 ~ WhileEnd ループの中に、上記追加コードを入れる。


メインルーチンの擬似的なプログラムは、以下になります。今回追加・修正するところがはっきりと分かります。

[初期設定]

Prog "TZM"  [メイン画面表示]

While 1


   [メニュー番号取得処理] 

  If M=0:Then
    [日本時間入力処理] (時間から「時」と「分」の分離も行う)
  Else If M=1:Then
    [ドイツ時間入力処理] (時間から「時」と「分」の分離も行う)
  Else If M=2:Then
    [ロサンゼルス時間入力処理] (時間から「時と「分」の分離も行う)
  
Else If M=3:Then
    入力処理は行わず、時間から「時」と「分」の分離のみ行う
  IfEnd:
IfEnd
  IfEnd:IfEnd

  If M=0:Then
    [時間計算]
  Else If M=1:Then
    [時差計算]
  Else If M=2:Then
    [時間計算]
  
Else If M=3:Then 
    [時間計算] 

  IfEnd:
IfEnd
  IfEnd:IfEnd

  Prog "TZD"  [時間の再表示]

WhileEnd

(赤文字は追加・修正部分)



1.初期化処理
今回は、ドイツの夏時間フラグ S を追加して、これを 0 で初期化しておきます。
S = 0 は、標準時間であることを示します。

0→S

を追加します。



2.メニュー番号取得処理


[3] キーを押すと、メニュー変数 M に 3 を設定する。

メニュー番号取得処理のプログラム
-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M
K=35⇒1→M
K=36⇒2→M
K=37⇒3→M 
[今回追加]


[3] キーのキーコードは 37 です。




3.入力処理

ドイツ時間を、夏時間 - 標準時間 に切り替えるのみで、キー入力処理は行いません。ドイツ時間が切り替わっても、日本時間やロサンゼルス時間には影響が無いので、この時点での日本時間 J を分離して、「時」を 変数 A に、「分」を変数 B に入れておきます。

Else If M=3
Then
Int(J÷100)→A
J-100A→B
IfEnd



4.時間計算

夏時間になると時差が1時間減り、標準時間に戻る時は時差が1時間増えます。
但し、ドイツ時間が変わるだけで、日本時間やロサンゼルス時間は変化しません。

これを具体的にプログラムにすると、以下のようになります。

Else If M=3
Then
If S:Then
0→S:P+1→P
Else
1→S:P-1→P
IfEnd
A-P→C
C<0⇒C+24→C
100C+B→G
Prog "TZM"
IfEnd


この中で、以下の部分は、夏時間フラグの変更と時差の変更を行います。

  If S:Then
  0→S:P+1→P
  Else
  1→S:P-1→P
  IfEnd


現状が夏時間の時は、S=1 になっています。
  If S:Then
は、S1 の時の分岐処理なので、
夏時間フラグ:S 0 にし、時差:P を1時間増やします。

Else 以下は、現状が標準時間の時の処理で、
夏時間フラグ:S1 にし、時差:P を1時間減らしています。


この後に続く処理では、ドイツ時間を計算し、時間表示サブルーチン TZM を呼び出します。

  A-P→C
  C<0⇒C+24→C
  100C+B→G
  Prog "TZM"


入力処理のところで、現在の日本時間 J から「時」:A と「分」 B を算出するようにしました。
ドイツ時間は、日本時間の「時」 A と時差 P から計算するので、A - P でドイツ時間の「時」が得られます。

この計算の結果が負の数になる場合は、ドイツはまだ前日と言うことになります。この場合は、得られた負の数に 24 を足せば、24時制の「時」になります。

そこで、A - P を一旦変数 C に入れておき、それが負の数なら 24 を足しておきます。
   A-P→C
   C<0⇒C+24→C


ドイツ時間:G は、100C + B で計算できます。
   100C+B→G 

最後に、サブルーチン TZM を呼び出す
   Prog "TZM"


さて、画面表示サブルーチン TZM をドイツの夏時間に対応するように変更します。

サブルーチン TZM のプログラム
Locate 1,1,"0:JST"
Locate 1,2,"1:CET"
Locate 1,3,"2:PST"
Locate 13,2,"3:"
Locate 1,4,"<AC>:QUIT"

If S:Then
Locate 5,2,"ST"   [1:CET を 1:CEST に表示を切り替える]
Locate 15,2,"DL"  [3:ST を 3:DL に表示を切り替える]
Else
Locate 5,2,"T "   [1:CEST を 1:CET に表示を切り替える]
Locate 15,2,"ST"  [3:DL を 3:ST に表示を切り替える]
IfEnd


(赤文字は追加分)

下から3行目で表示するのは "T " で、 T の後に空白1文字が付加されていることに注意してください。この空白文字があることで、"ST" と表示されている2文字を"T " で上書きして、 表示を 1:CEST から 1:CET に変更できるわけです。


ヨーロッパの標準時間と夏時間の略称は、以下のように標準時間は3文字、夏時間は4文字の表記になっています。
そこで、略称の2文字目以降を T と ST で切り替えると、標準時間と夏時間の略称表示を切り替えられます。

タイムゾーン標準時間 夏時間 
西ヨーロッパ時間WETWEST
中央ヨーロッパ時間CETCEST
東ヨーロッパ時間EETEEST
極東ヨーロッパ時間FETFEST



5.時間の再表示


時間の再表示は、サブルーチン TZD で行います。これまでに作った 時間表示サブルーチン TZD のソースコードを示します。

サブルーチン TZD のプログラム
Locate 8,1,"0000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U


プログラムを起動した直後は、以下の画面になっています。

38-TZ4_main 

先に、ドイツを夏時間に切り替えてから、時間を入力しようとします。つまりこの画面で [3] キーを押すと、以下のような画面になってしまいます。

40-TZ5_problem 

日本時間が 0000、ドイツ時間が 1700、ロサンゼルス時間が 0000 となっているのは、明かに異常です。

しかし、プログラムを上から順に見ながら確かめると、この状態ではどの地域の時間も入力していないので、当然このような表示になります。では、何が悪いのか?

要するに、この時点で各地域の時間を表示する意味がありません。むしろ表示してはいけない、と考えます。

仮に、どこかの地域に時間を入力すれば、正しい時間が計算される筈です。試しに、日本時間に 20:00 を設定してみます。

41-TZ5_normal 

正しい時差で、時間が表示されているのが分かります。

どの地域にも時間を入力していない状態、つまりプログラム起動直後の状態では、サブルーチン TZD による時間表示が行われないようにすれば、この問題を解決できます。

このような細かい処理は、メインルーチンを変更するよりも、サブルーチンで対処した方が、プログラムは分かりやすくなるので、TZD をどのように変更すべきかを考えます。


1つの方法として、日本時間の変数 J を -1 で初期化する手があります。プログラムを走らせている時は、J が -1 になることは絶対にありません。と言うのも、INPI は仕様上、負の値を戻すことが無いからです。一回でも、どこかの地域に時間を入力すれば、J0 か正の値になるわけで、-1 は初期状態を示すためだけに使えます。敢えて、J-1 で初期化するのが、今回の作戦です。

言い換えれば、変数 J に、初期状態フラグとしての働きも持たせるわけです。
そこで、サブルーチン TZD では、J の異常値 -1 を検出させて、異常値なら何も動作しないで終了し、メインルーチンに戻るようにします。TZD の最初の行に、以下のコードを追加します。

J=-1⇒Return

Return コマンドは、プログラムを強制終了させます。サブルーチン内では、Return コマンドがあると、そのサブルーチンを直ちに終了させ、メインルーチンに戻ります。
 ⇒ Casio Basicコマンドリファレンス: Return


サブルーチン TZD を以下のように変更します。

サブルーチン TZD のプログラム
J=-1⇒Return

Locate 8,1,"000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U


これに合わせて、忘れずにメインルーチン TZ の [初期化処理] ブロックでの J の初期化を -1→J に変更しておきます。

では、TZ を起動し、いきなり最初に [3] キーを押して、ドイツを夏時間にしてみます。以下のように、時間が表示されないことを確認してください。次に、日本時間を 20:00 にしてみます。ドイツ時間が 1300、ロサンゼルス時間が 0300 になっていれば正常です。

41-TZ5_normal 

では、[3] キーをもう一度押して、夏時間から標準時間へ戻してください。日本時間とロサンゼルス時間は、当然変化なしで、ドイツ時間が 1200 と表示され、プログラムが正しく動作していることがわかります。



今回までに作成したプログラムは、以下の通り(今回追加した部分を赤文字で示す):

 CcLinkerを使ってfx-5800Pに転送できるCCLファイルのダウンロード
 ※ CcLinker の紹介

メインルーチン:TZ のプログラム
8→P:17→Q
-1→J:0→G:0→U
0→S
Prog "TZM"

While 1

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

If M=0:Then
8→X:1→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→J
Else If M=1
Then
8→X:2→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→G
Else If M=2:
Then
8→X:3→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→U
Else If M=3
Then
Int(J÷100)→A
J-100A→B
IfEnd:
IfEnd
IfEnd:IfEnd

If M=0:Then
A≧24⇒A-24→A
100A+B→J
A-P→C
C<0⇒C+24→C
100C+B→G
A-Q→C
C<0⇒C+24→C
100C+B→U
Else If M=1
Then
A≧24⇒A-24→A
100A+B→G
A+P→C
C≧24⇒C-24→C
100C+B→J
A+P-Q→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→U
Else If M=2
Then
A≧24⇒A-24→A
100A+B→U
A+Q→C
C≧24⇒C-24→C
100C+B→J
A+Q-P→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→G
Else If M=3
Then
If S:Then
0→S:P+1→P
Else
1→S:P-1→P
IfEnd
A-P→C
C<0⇒C+24→C
100C+B→G
Prog "TZM"
IfEnd:
IfEnd
IfEnd:IfEnd

Prog "TZD"

WhileEnd




サブルーチン:TZM のプログラム (画面表示)
Locate 1,1,"0:JST"
Locate 1,2,"1:CET"
Locate 1,3,"2:PST"
Locate 13,2,"3:"
Locate 1,4,"<AC>:QUIT"

If S:Then
Locate 5,2,"ST"
Locate 15,2,"DL"
Else
Locate 5,2,"T "
Locate 15,2,"ST"
IfEnd




サブルーチン:TZC のプログラム (時間を「時」と「分」に分離):変更なし
If Z<100:Then
Z→X:0→Y
Else
Int(Z÷100)→X
Z-100X→Y
IfEnd




サブルーチン TZD のプログラム (時間の表示)
J=-1⇒Return

Locate 8,1,"0000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U




今回は、ドイツの夏時間設定機能を追加しました。
次回は、ロサンゼルスの夏時間設定を追加してゆきます。



つづく...


Casio Basic入門27 / 目次



応援クリックをお願いします。励みになるので...
にほんブログ村 IT技術ブログ 開発言語へ


 


keywords: fx-5800PCasioBasic、世界時間換算, プログラミング入門プログラム関数電卓

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



関連記事

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

Casio Basic入門25

Casio Basic入門
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します
最終更新: 2018/11/03

 4. CasioBasicを使ってみる(続き)

Chapter 5

◆ Chapter 5 の目標: サブルーチンを使いこなす

前回: Casio Basic入門24


[2018/11/03 追記]
 ソースコードの誤記を見直しました
 CcLinker を使ってfx-5800Pに転送して使えるプログラムファイル(CCLファイル)をダウンロードできます。


前回は、日本時間を入力したら、ドイツ時間とロサンゼルス時間を表示するところまで、作りました。
今回は、ドイツ時間やロサンゼルス時間を入力したら、日本、ドイツ、ロサンゼルスの時間を表示するように、プログラムを書き足してゆきます。

今回完成させるプログラムを一番下に載せているので、それを見て分かれば先に進むのも良いでしょう。



Chapter5-3
同様の機能を追加する

起動時の画面は以下のようになります。

35-TZ1_main  

今回追加する機能は、[1] キーを押してドイツ時間 (CET) を入力させ、[2] キーを押してLA時間を入力させ、それぞれの場合に日本時間、ドイツ時間、ロサンゼルス時間を計算し、その結果を画面表示する機能を作ります。


1.初期化処理
新たに追加する変数は、予期しない値にならないように、初期化しておく。

2.メニュー番号取得処理
ループの中で Getkey コマンドを使って、[1] キーが押された時、メニュー変数 M1 を設定する。
さらに、[2] キーが押された時、メニュー変数 M2 を設定する。
なお、この処理では、何かキーが押されるまでプログラムは先に進まず、入力待ちの状態にする。

3.入力処理
M=1 の時、入力処理を行い、その結果を ドイツ時間の変数 G に入れる。さらに、G から「時」と「分」を分離する。
M=2 の時、入力処理を行い、その結果をLA時間の変数 U に入れる。さらに U から「時」と「分」を分離する。

4.時間の計算
M=1 の時、入力されたドイツ時間に基づき、日本時間とロサンゼルス時間を計算する。
M=2 の時、入力されたロサンゼルス時間に基づき、日本時間とドイツ時間を計算する。

5.時間表示の更新
日本時間、ドイツ時間、ロサンゼルス時間の表示を更新する。

6.ループ構造
既にある While 1 ~ WhileEnd ループの中に、上記追加コードを入れる。


メインルーチンの擬似的なプログラムは、以下になります。追加・修正するところが、はっきりと分かります。

[初期設定]

Prog "TZM"  [メイン画面表示]

While 1


   [メニュー番号取得処理] 

  If M=0:Then
    [日本時間入力処理] (時間から「時」と「分」の分離も行う)
  
Else If M=1:Then
    [ドイツ時間入力処理] (時間から「時」と「分」の分離も行う)
  Else If M=2:Then
    [ロサンゼルス時間入力処理] (時間から「時」と「分」の分離も行う)
  IfEnd:IfEnd

  IfEnd:

  If M=0:Then
    [時間計算]
  
Else If M=1:Then
    [時差計算]
  Else If M=2:Then
    [時間計算]
  IfEnd:IfEnd

  IfEnd

  Prog "TZD"  [時間の再表示]

WhileEnd

(赤文字は追加・修正部分)


この方針で、プログラムを具体的に書いてゆきます。



1.初期化処理


今回は、ドイツ時間の変数 G とロサンゼルス時間の変数 U を追加します。
前回、J を 0 で初期化したのと同じ理由で、GU0 で初期化しておきます。

0→G:0→U

を追加します。



2.メニュー番号取得処理


[1] キーを押してドイツ時間入力をさせ、[2] キーでロサンゼルス時間を入力させるので、この部分を追加します。

メニュー番号取得処理のプログラム
-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M
K=35⇒1→M  [今回追加分]
K=36⇒2→M  
[今回追加分]


[1] キーのキーコードは 35 、 
[2] キーのキーコードは 36 です。



3.入力処理

ここで用いる「入力ボックス:INPI 」 については、以下を参照してください。
 ⇒ fx-5800P プログラムライブラリ - 入力ボックス
 ⇒ Casio Basic入門24: 世界時間換算プログラムを作る の Chapter 5-2


ドイツ時間の入力処理
1:CET の右横、(X, Y) = (8, 2) の位置に、4桁の入力ボックスを表示し、小さいインジケータ(▶E)を表示するので、ソースコードは以下のようになります。変数 G は、ドイツ時間を格納する変数です。
省略入力への対応、時間から「時」と「分」を分離する処理は、前回作った日本語入力処理と同様に、サブルーチン: TZC が受け持ちます。

8→X:2→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
Z→G


ロサンゼルス時間の入力処理
2:PST の右横、(X,Y) = (8, 3) の位置に、4桁の入力ボックスを表示し、小さい確定ガイド(▶E) を表示するので、プログラムは以下のようになります。変数 U は、ロサンゼルス時間を格納する変数です。
上と同様にして、サブルーチン: TZC を使います。

8→X:3→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
Z→U



以上を追加すると、入力処理は以下のようになります。

メインルーチン [入力処理] ブロックのプログラム
If M=0:Then
8→X:1→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→J
Else If M=1
Then
8→X:2→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→G
Else If M=2:
Then
8→X:3→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→U
IfEnd:IfEnd

IfEnd


(赤文字は今回追加分)


サブルーチン:TZC のプログラム
If M=0:Then
8→X:1→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→J
IfEnd


(変更はありません)



4.時間計算

メインルーチン TZ に処理を追加します。

M=1 の時、入力したドイツ時間から日本時間とロサンゼルス時間を得る処理
サブルーチン TZC での簡易入力機能の結果、0:05 としたい場合は 2405 と入力する必要があり、その場合は A の値が 24 を超えることになります。

・ドイツ時間:
  - 「時」 = A (サブルーチン TZC で、時間から「時」を分離して得た値)
   但し、A が 24以上になる場合は、24 を引く
   プログラムは、
    A≧24⇒A-24→A
   
となる。
  - 「分」 = B (サブルーチン TZC で得られた値)
  - ドイツ時間: G = 100A + B
   プログラムは、
    100A+B→G 
   
となる。


・日本時間: ドイツ時間に時差 P (8時間) を足す
 - 「時」 = A + P (一旦、変数 C に代入しておく)
  但し、A + P = C が 24以上になる場合は、24 を引く (この場合は日付が変わる)
  プログラムは、
   A-P→C
   C≧24⇒C-24→C
  
となる。
 - 「分」 = B
 - 日本時間: J = 100C + B (サブルーチン TZC で得られた値)
  プログラムは、
   100C+B→J 
  
となる。

・ロサンゼルス時間: 日本時間から時差 Q (17時間) を引く
 - 「時」 = A + P - Q (一旦、変数 C に代入しておく)
  但し、A + P - Q の結果が 0 未満になる場合は、24 を足す (この場合は日付が変わる)
  また、A + P -Q24 以上になる場合は、24 を引く (この場合も日付が変わる)
  プログラムは、
   A+P-Q→C
   C<0⇒C+24→C
   C≧24⇒C-24→C

  
となる。
 - 「分」 = B
 - ロサンゼルス時間: U = 100C + B
  プログラムは、
   100C+B→U
  
となる。

以上のようにして、J (日本時間)、G (ドイツ時間)、U (ロサンゼルス時間) が計算できます。ここまでを、まとめておきます。

日本、ドイツ、ロサンゼルスの時間を計算するプログラム
If M=0:Then
A≧24⇒A-24→A
100A+B→J
A-P→C
C<0⇒C+24→C
100C+B→G
A-Q→C
C<0⇒C+24→C
100C+B→U

Else If M=1
Then
A≧24⇒A-24→A
100A+B→G
A+P→C
C≧24⇒C-24→C
100C+B→J
A+P-Q→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→U
IfEnd:
IfEnd


(赤文字は追加分)


M=2 の時、入力したロサンゼルス時間から、日本時間とドイツ時間を得る処理

M=1
の時とほぼ同様の処理となります。

・ロサンゼルス時間:
  - 「時」 = A
   但し、A が 24以上になる場合は、24 を引く (この」場合は日付が変わる)
   プログラムは、
    A≧24⇒A-24→A
   
となる。
  - 「分」 = B
  - ロサンゼルス時間: U = 100A + B
   プログラムは、
    100A+B→U 
   
となる。

・日本時間: ロサンゼルス時間に時差 Q (17時間) を足す
 - 「時」 = A + Q (= C とおく)
  但し、A + Q の結果が 24以上になる場合は、24 を引く (この場合は日付が変わる)
  プログラムは、
   A+Q→C
   C≧24⇒C-24→C
  
となる。
 - 「分」 = B
 - 日本時間: J = 100C + B
  プログラムは、
   100C+B→J 
  
となる。

・ドイツ時間: 日本時間から時差 P (8時間) を引く
 - 「時」 = A + Q - P ( = C とおく)
  但し、A + Q - P の結果が 0 未満になる場合は、24 を足す (この場合は日付が変わる)
  また、A + Q - P が 24 以上になる場合は、24 を引く (この場合も日付が変わる)
  プログラムは、
   A+Q-P→C
   C<0⇒C+24→C
   C≧24⇒C-24→C

  
となる。
 - 「分」 = B
 - ドイツ時間: G = 100C + B
  プログラムは、
   100C+B→G 
  
となる。

以上のようにして、J (日本時間)、G (ドイツ時間)、U (ロサンゼルス時間) が計算できます。ここまでを、まとめておきます。

メインルーチン [時間計算] ブロックのプログラム
If M=0:Then
A≧24⇒A-24→A
100A+B→J
A-P→C
C<0⇒C+24→C
100C+B→G
A-Q→C
C<0⇒C+24→C
100C+B→U

Else If M=1
Then
A≧24⇒A-24→A
100A+B→G
A+P→C
C≧24⇒C-24→C
100C+B→J
A+P-Q→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→U
Else If M=2
Then
A≧24⇒A-24→A
100A+B→U
A+Q→C
C≧24⇒C-24→C
100C+B→J
A+Q-P→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→G
IfEnd:
IfEnd
IfEnd


(赤文字は追加分)



5.時間の再表示


時間の再表示は、サブルーチン TZD で行いますが、特に変更の必要はありません。

サブルーチン TZD のプログラム
Locate 8,1,"0000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U




今回までに作成したプログラムは、以下の通り(今回追加した部分を赤文字で示す):

 CcLinkerを使ってfx-5800Pに転送できるCCLファイルのダウンロード
 ※ CcLinker の紹介

メインルーチン:TZ のプログラム
8→P:17→Q
0→J:0→G:0→U
Prog "TZM"

While 1

-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M
K=25⇒1→M
K=36⇒2→M


If M=0:Then
8→X:1→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→J
Else If M=1
Then
8→X:2→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→G
Else If M=2:
Then
8→X:3→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→U
IfEnd:IfEnd

IfEnd

If M=0:Then
A≧24⇒A-24→A
100A+B→J
A-P→C
C<0⇒C+24→C
100C+B→G
A-Q→C
C<0⇒C+24→C
100C+B→U
Else If M=1
Then
A≧24⇒A-24→A
100A+B→G
A+P→C
C≧24⇒C-24→C
100C+B→J
A+P-Q→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→U
Else If M=2
Then
A≧24⇒A-24→A
100A+B→U
A+Q→C
C≧24⇒C-24→C
100C+B→J
A+Q-P→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→G
IfEnd:IfEnd

IfEnd

Prog "TZD"

WhileEnd




サブルーチン:TZM のプログラム (メイン画面表示):変更なし
Locate 1,1,"0:JST"
Locate 1,2,"1:CET"
Locate 1,3,"2:PST"
Locate 1,4,"<AC>:QUIT"




サブルーチン:TZC のプログラム (時間を「時」と「分」に分離):変更なし
If Z<100:Then
Z→X:0→Y
Else
Int(Z÷100)→X
Z-100X→Y
IfEnd




サブルーチン TZD のプログラム (時間の表示):変更なし
Locate 8,1,"0000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U




今回は、ドイツ時間やロサンゼルス時間を入力した時の処理を追加しました。
次回は、ドイツ時間の夏時間設定機能を追加してゆきます。



つづく...


CasioBasic入門26 / 目次



応援クリックをお願いします。励みになるので...
にほんブログ村 IT技術ブログ 開発言語へ


 


keywords: fx-5800PCasioBasic、世界時間換算, プログラミング入門プログラム関数電卓

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



関連記事

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

Casio Basic入門24

Casio Basic入門
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します
最終更新: 2015/07/03

 4. CasioBasicを使ってみる(続き)

Chapter 5

◆ Chapter 5 の目標: サブルーチンを使いこなす

前回: Casio Basic入門23 を見る


[2018/11/03 追記]
 ソースコードの誤記を見直しました
 CcLinker を使ってfx-5800Pに転送して使えるプログラムファイル(CCLファイル)をダウンロードできます。


「世界時間表示プログラム TIME ZONE 」 を実際に作ってゆきます。

Chapter 5 では、以前実際に考えたり作ったりしたことを振り返るために、以前の記事やCasio Basicコマンドリファレンスへのリンクも紹介してゆきます。

プログラムを作る時は、できるだけわかりやすくソースコードを書く ことを心がけます。機能追加が楽になり、バグの発生も少なくなるからです。そして、最初から欲張って多くの機能を盛り込もうとはせずに、全体の骨組みになる部分から作り始めます。その後、徐々に機能を追加するのが確実です。今回は、サブルーチンをうまく使ってゆきます。

そこて、最初に大まかな方針を作ります。


大まかな方針

方針1. 1 画面内で表示と入力を行う。
  → 入力ボックスを使う

方針2. 最初に、日本・ドイツ・ロサンゼルス(LA)時間の換算プログラムを作り、後から機能追加して夏時間の計算とヨーロッパ・北米のそれぞれのタイムゾーンへの変更と計算をできるようにする。

方針3. ドイツは8時間、ロサンゼルスは17時間だけ日本時間から戻せば(引き算)すれば良い。これは夏時間でない時。

方針4. 時間は24時制を使う。

方針5. 時間は 1024、930 といった整数で扱い、時間を格納する変数には、この整数を入れる。

方針6. 時間表示は、必ず4桁表示とする。例えば 1024、0930、0010 、0004 など、3~1桁の場合は頭に 0 を付加する。4桁に揃えないと、一覧表示が見づらく、勘違いする可能性が増える。

方針7. 大きな骨組みとして、プログラム構造を考える。

 [初期設定] 
 [初期表示]
 While 1
   [メニュー番号取得処理]
   [メニュー番号に応じた入力処理]
   [メニュー番号に応じた時間計算]
   [時間表示の更新]
 WhileEnd


方針8. あとは、実際に作りながら考え、細かいところは必要に応じて変更する。


今回作成するのは、日本時間を入力すると、中央ヨーロッパ時間と北米太平洋時間を表示する機能です。

今回完成させるプログラムを一番下に載せているので、先にそれを見て分かれば先に進むのも良いでしょう。



Chapter5-2
Getkey、入力ボックス、Locate の活用

では、大まかな方針に従って、具体的にプログラムを書いてゆきます。

先ず最初に、日本時間を入力すると、ドイツとロサンゼルスの時間を表示する機能を作ります。

画面デザイン

メイン画面を以下のようにします。

35-TZ1_main   

0:JST
これは日本時間です。[0] キーを押すと日本時間を入力します。項目 1 や 2 で海外の時間を設定した場合は、それに合った日本時間を、ここに表示します。

1:CET
これは、中央ヨーロッパ時間 (Central Europe Time)で、プログラム起動時の初期設定を CET とします(私の好みです...)。[1] キーを押すと CET の時間を入力します。ドイツ、フランス、イタリアなど多くの国がこのタイムゾーンに含まれます。項目 0 や 2 で時間を設定した場合は、それに合った CET 時間がここに表示されます。ドイツが含まれるので、しばらくはドイツ時間と言うことにします。

2:PST
これは、アメリカの太平洋時間 (Pacific Standard Time)で、プログラム起動時の初期設定を PST とします。[2] キーでの入力や表示については、上と同様です。ロサンゼルス(LA)が含まれるので、しばらくはロサンゼルス時間と言うことにします。


この画面を作るプログラムは、以下の通り。

Locate 1,1,"0:JST"
Locate 1,2,"1:CET"
Locate 1,3,"2:PST"
Locate 1,4,"<AC>:QUIT"


上の方針で決めたように、後で機能追加する時に、夏時間を設定する機能や、タイムゾーンを変更する機能を追加します。その時、前回紹介したようにタイムゾーンの略称を現地で使われるように変更する予定なので、画面表示を変える必要がでてきます。つまり、上の5行のプログラムは、徐々に複雑になることが予想されるので、画面の表示をサブルーチンにしてメインルーチンから呼び出すようにします。

このようにすると、画面の表示を変える場合でも、メインルーチンを変更せずに済むので、プログラムがわかりやすいままで、バグの発生も抑えられる筈です。

画面表示サブルーチンのファイル名を TZM とします(メイン画面 → MainM なので、TZ + M )。
ちなみに、TZTIME ZONE の略称。

TZM のプログラム
Locate 1,1,"0:JST"
Locate 1,2,"1:CET"
Locate 1,3,"2:PST"
Locate 1,4,"<AC>:QUIT"



次に、メインルーチンを作ってゆきます。
メインルーチンのファイル名を TZ とします。TIME ZONE だから、TZ です。

ドイツと日本の時差は、夏時間でない時は8時間、ロサンゼルスとの時差は17時間です。この値は、プログラムで絶対に使うので、変数に入れておきます。ドイツとの時差を変数 P として 8 で初期化、ロサンゼルスとの時差を変数 Q として 17 で初期化します。
8→P:17→Q


ここまでの TZ のプログラム
8→P:17→Q
Prog "TZM"




今回具体的に作るのは、[0] キーを押した時、日本時間 (JST) を入力させ、ドイツ時間とロサンゼルス時間を計算し、その結果を画面表示する機能を作ります。

1.メニュー番号取得処理
ループの中で Getkey コマンドを使って、[0] キーが押された時、メニュー変数 M0 を設定する。なお、この処理では、何かキーが押されるまでプログラムは先に進まず、入力待ちの状態にする。

2.入力処理
M=0 の時、入力処理を行い、その結果を 日本時間を格納する変数 J に入れ、0:JST の右に入力した時間を表示する。

3.時差計算
M=0 の時、入力された日本時間に対応したドイツ時間とLA時間を計算する。

4.時間表示の更新
日本、ドイツ、LAの時間の表示を更新する。

5.ループ構造
項目1~4の処理は繰り返し行うので、これらを While 1 ~ WhileEnd ループの中に入れる。


以上を、擬似的なプログラムで表現してみます。

While 1

   [メニュー番号取得処理] (ここで入力待ち)

  If M=0:Then
     [日本時間の入力処理
  IfEnd

  If M=0:Then
     [時間の計算] 
  IfEnd

  [時間表示の更新]


WhileEnd



While 1WhileEnd は無限ループです。PCなどのプログラムでは、無限ループはCPUパワーを無駄に食いつぶすだけでなく、プログラムを正常終了できなくなる可能性もあるので、基本的に使うべきではありません。特に Windows プログラミングでは、できるだけ速やかに制御を Windows (OS) に戻すのが作法です。

しかし、Casio Basic の場合は、[AC] キーを押せば、いつでもプログラムを終了可能で、終了のための特別な処理が不要です。今回は [AC] キーで終了させるようにします。




1.メニュー番号取得処理

Getkeyコマンドの使い方は、以下に詳しく説明していますので、まだよく分からない場合は参照してください。
 ⇒Casio Basic コマンドリファレンス: Getkey
 ⇒Casio Basic入門3: Getkey と Locate コマンドを使いこなす


条件ジャンプの ⇒命令については、以下のコマンドリファレンスや、過去のCasio Basic入門を参考にしてください。
 ⇒Casio Basic コマンドリファレンス: ⇒命令


メインルーチンTZ:メニュー番号取得処理のプログラム
-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M


[0] キーのキーコードは 25 です。


ここで、1つ大切な注意点:

最初に、変数 M を -1 で初期化しています。キーコード取得のための Do ループは、K の値が 0 の時ループを継続します。キーコードが 0 と言うのは、キーが何も押されていない状態を示します。

さて、このプログラムを起動する前に、電卓を様々な用途で使うわけで、その際に変数 M に 0 以外の何かの値が入ることが十分有り得ます。

もし、-1で M を初期化しておらず、M に 0 が入っていた場合、[0] 以外の何かキーが押されたことを想定します。その場合、このループを脱出して先に進み、M には想定外の値 0 が入っています。すると、[0]を押していないのに、メニュー番号0が選択されたと誤判定されます。このように想定外の M の値によって、プログラムが意図しない動作をするわけです(要するにバグ)。
そこで、変数 M を完全に把握して制御することで、プログラムを意図に従った動作以外できなくします。

このバグは簡単に発生します。メニュー番号変数 M は、0 以上の整数とするつもりなので、絶対にメニュー番号になり得ない -1 で初期化しておきます。

使う変数は、使う前に初期化をする癖を付けると、バグが入りにくくなってプログラミングが楽になります。



2.入力処理

本プログラム TIME ZONE では、時間を24時制とし、4桁の数字で時間を表すことにしています。
 ・10:24 は、1024
 ・9:30 は、0930
 ・0:20 は、0020
 ・6:00 は、0600
 ・0:05 は、0005


INPI の使い方

入力には、入力ボックス:INPI を使います。
Chapter 3 / Chapter 6 で 入力ボックス:INPI を作りました。その時に作ったプログラムが fx-5800P に残っていない場合は、以下のプログラムライブラリにアクセスし、ソースコードからご自分で fx-5800P に入力するか、CCLファイルをダウンロードして CcLinkerを使って fx-5800P に転送してください。

 ⇒ fx-5800P プログラムライブラリ - 入力ボックス 
入力ボックスは Ver 2.0/2.1 になっており、[Chapter 6 参照]、キー入力の反応が大幅に改善しています。 

INPI の使い方や動作について、詳しくは上記プログラムライブラリーを参照してください。


サブルーチン:INPIメインルーチンから呼び出す直前に、4つの変数 XYDE の値を設定します。INPI はこれらの変数を参照して動作します。

 ・X: 入力ボックス開始位置の X 座標
 ・Y: 入力ボックス開始位置の Y 座標
 ・D: 入力ボックスの桁数
 ・E: インジケータの表示方法(サイズ)を設定するフラグ、0 で大きな表示、1 で小さな表示

サブルーチン:INPI は、入力確定してメインルーチンに戻る時、変数 Z に入力値を格納します。従って、INPI の直後で、変数 Z の値を、メインルーチンで使用する変数に代入しておく必要があります。

INPI を使う時は、5つの変数(XYDEZ)は、その値が変化します。つまり、これらの変数をメインルーチンで使う時は、値が変化することを前提にしてください。

0:JST の横、(X, Y) = (8, 1) の位置に、4桁の入力ボックスを表示させ、小さいインジケータ(▶E)を表示させるので、プログラムは以下のようになります。変数 J は、上でも述べたように、日本時間を格納する変数です。

8→X:1→Y:4→D:1→E
Prog "INPI"
Z→J


INPI の変数とメインルーチンの予約変数
メインルーチンでは、日本時間 J、ドイツ時間 G、ロサンゼルス時間 U、時差 P, Q など、他のサブルーチンで勝手に変更されては困る変数があります。これを予約変数と呼び、他で値が変更されても構わない変数を使い捨て変数と呼んでいます。
INPIで使う変数は当然それらの値は変更されるので、メインルーチンの予約変数には使えません。

メインルーチンの予約変数は、以下のINPIで使う変数を避けて使います。

INPI で使う変数
 C: 入力中の桁数
 D: 入力ボックスの桁数
 E: 確定ガイドフラグ
 I: for文制御変数、入力キー
 K: キーコード
 X: 入力開始桁
 Y: 入力開始行
 Z: 入力数値
 配列変数 Z[n]n = 21~23, 25, 31~33, 35~37


・時間から「時」と「分」を分離して計算する

本プログラムでは、時差の計算が最も重要な仕事です。

時差は時間単位で決まっています。そこで、日本時間 10:24 に対して、例えばドイツ時間は 2:24 であり、「分」はそのままで、「時」だけが 8 減っています。

そこで、時間から「時」と「分」を分離して、「時」を変数 A に入れ、「分」を変数 B に入れておくと、時差計算が便利になります。

時間の変数に格納される整数について、下位2桁が「分」となります。例えば日本時間 J については、以下のようにすれば「時と「分」が得られます。

Int(J÷100)→A
J-100A→B


J の値が、3桁 (0905など)、2桁(0020など)、1桁(0005など)でも、この計算が正しいことは、試してみると分かります。

ここで使っている Int( ) 関数は、( ) 内の数値の整数部分を取り出すものです。
 ⇒ Casio Basicコマンドリファレンス: Int( ) / Frac( )


・省略した入力への対応

例えば、9:00 を入力したい時、900 と 3桁を入力するよりは、9 と1桁の入力で済ませた方が楽です。6:30 を入力するには、630 と 3桁入力が楽です。

入力を省略できるのは、1桁および2桁入力の時で、入力したものを「時」として判断するようにします。そこで、入力して得られた数が2桁以下の時、つまり 100未満の数の時、その数は「時」であると判断させます。具体的には、以下のプログラムになります。

If J<100:Then
J→A:0→B

Else
Int(J÷100)→A
J-100A→B
IfEnd


これには、上記の「時」と「分」の分離計算を含みます。

但し、この計算は日本時間を入力する時だけでなく、ドイツ時間やLA間の入力時にも使いますので、サブルーチンにしておくことにします。

そこで、INPI 実行直後は、変数 Z は入力した時間になっているので、このサブルーチンでは、変数 Z で時間の値を受け取ります。サブルーチン実行後は、「時」を変数 X に、「分」を変数 Y に入れることにして、サブルーチン直後で、X→A:Y→B とすれば、メインルーチンの変数 A B に「時」」と「分」を受け渡しできます。

※ このロジックだと、例えば0時20分を入力するために 0020 と入力したり、0時5分を入力するために 0005 と入力すると、おかしなことになります。0020 と入力して [EXE] キーを押すと 2000 と表示され、0005 と入力して [EXE] キーを押すと 0500 と表示されます。0時xx分のときだけは、24xx と入力する必要があります。0時台の時間入力を例外的に 24xx と入力させるのですが、他の時間の入力の利便性を優先させることにします。

このサブルーチンのファイル名を TZC とします。計算 (Calculation) の C を使って、TZ + CTZC です。

サブルーチン:TZC のプログラム
If Z<100:Then
Z→X:0→Y
Else
Int(Z÷100)→X
Z-100X→Y
IfEnd



以上をまとめると、日本時間の入力処理は以下のようになります。

メインルーチンTZ:入力処理のプログラム

If M=0:Then
8→X:1→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→J
IfEnd




3.時間の計算

・入力した日本時間からドイツ時間とLA時間を得る方法

さて、今後使う予定のメインルーチンの予約変数を先に決めておきます。

 ・J: 日本時間
 ・G: ドイツ時間 (中央ヨーロッパ時間)、実はドイツ = Germany から変数を G にしました。
 ・U: LA時間 (アメリカ太平洋時間)、アメリカ = USA から変数を U にしました。
 ・A: 入力した時間を分割した「時」
 ・B: 入力した時間を分割した「分」
 ・P: 日本とドイツとの時差
 ・Q: 日本とLAとの時差

AB、P、Q  から、J、G、U を計算して、それを表示するのが、ここでの処理です。

・日本時間:
  - 「時」 = A
   但し、A が 24以上になる場合は、24 を引く (この場合は日付が変わる)
   コードは、
    A≧24⇒A-24→A
   
となる。
  - 「分」 = B
  - 時間: J = 100A + B
   コードは、
    100A+B→J
   
となる。

上記の省略入力機能では、0:05 と設定するために 0005 や 005 と入力すると 5:00 と認識され、このままだと 0:05 と設定できません。そこで、0:05 の代わりに、24:05 と設定すると、つまり 2405 と入力すれば 0:05 と認識できれば良いわけです。そこで、

A≧24⇒A-24→A

としました。

・ドイツ時間: 日本時間から時差 P (9時間) を引く
 - 「時」 = A - P (= C とおく)
  但し、A - P の結果が 0 未満になる場合は、24 を足す (この場合は日付が変わる)
  プログラムは、
   A-P→C
   C<0⇒C+24→C
  
となる。
 - 「分」 = B
 - 時間: G = 100C + B
  プログラムは、
   100C+B→G
  
となる。

・LA時間: 日本時間から時差 Q (17時間) を引く
 - 「時」 = A - Q ( = C とおく)
  但し、A - Q の結果が 0 未満になる場合は、24を足す (この場合は日付が変わる)
  プログラムは、
   A-Q→C
   C<0⇒C+24→C

  
となる。
 - 「分」 = B
 - 時間: U = 100C + B
  プログラムは、
   100C+B→U
  
となる。

日本時間が 7:00 の時、ドイツは時差8時間なので、「時」から 8 を引き算するのですが、7 - 8 = -1 となります。これは前日の 23:00 である筈なので、7 に 24 を足した上で、8 を引けば 23 が得られます。

日本時間が 7:00 の時、LAでは 前日の 14:00 ですが、7 から時差の 17 を引くと、-10 となってしまうので、上と同様にして、一旦 24 を足してから 10 を引く計算をします。

これが、C<0⇒C+24→C とした理由です。

以上のようにして、J (日本時間)、G (ドイツ時間)、U (LA時間) を計算できるようになりました。これをまとめておきます。

メインルーチン TZ:日本、ドイツ、LAの時間を計算するプログラム
If M=0:Then
A≧24⇒A-24→A
100A+B→J
A-P→C
C<0⇒C+24→C
100C+B→G
A-Q→C
C<0⇒C+24→C
100C+B→U

Prog "TZD"
IfEnd



4.得られた時間を更新表示

時間を更新表示する部分は、何度も繰り返し使うので、サブルーチンにします。

ファイル名: TZD
表示 = Display なので、TZ + D から TZD としました。

先ずは、以下のプログラムが出発点です。

Locate 8,1,J
Locate 8,2,G
Locate 8,3,U


ここで、J は日本時間、G はドイツ時間、U はLA時間です。


時間の変数 J、G、U には、4桁だけでなく、3桁や 2桁、さらに1桁の場合もあります。一方で、大まかな方針で決めたように、表示は必要なら頭に 0 を加えて、必ず4桁の表示にします。

そこで、一旦 0000 と表示したところに、上書きして時間を表示します。

サブルーチン TZD のプログラム
Locate 8,1, "0000"
Locate 8,1,J
Locate 8,2,"0000"
Locate 8,2,G
Locate 8,3,"0000"
Locate 8,3,U



一旦、ここまでで メインルーチンTZのプログラムをまとめてみます。

メインルーチンTZ のプログラム
8→P:17→Q
Prog "TZM"

While 1

-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M

If M=0:Then
8→X:1→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→J
IfEnd

If M=0:Then
A≧24⇒A-24→A
100A+B→J
A-P→C
C<0⇒C+24→C
100C+B→G
A-Q→C
C<0⇒C+24→C
100C+B→U
IfEnd

Prog "TZD"

WhileEnd



これを実行してみます。

日本時間を 8:04 にするとき、804 と3桁を入力してみると、以下のような表示になりました。

36-TZ1_wrong_time  

本来は、以下の表示になるべきなので、プログラムに問題があります。

0:JST      0804
1:CET     0004
2:PST     1504
<AC>:QUIT


日本時間の変数 J には 804 が、ドイツ時間の変数 G には 4 が、LA時間の変数 U には 1504 が入っています。
従って、
 ・Locate 8,1,J 804 を8桁目から表示
 ・Locate 8,2,G4 を8桁目から表示
しているので、おかしくなります。

Locate 8,3,U
は、変数 U に入っている4桁の数 1504 を表示するので、たまたま問題ない、と言うことが分かります。

そこで Locate コマンドでは、
 ・表示する数が、1桁の場合は、11桁目から表示
 ・表示する数が、2桁の場合は、10桁目から表示
 ・表示する数が、3桁の場合は、9桁目から表示
 ・表示する数が、4桁の場合は、8桁目から表示

となるようにすれば良いことが分かります。

そこで、変数 JGU の桁数が分かれば、それぞれ

 ・Locate 12-[J の桁数],1,J
 ・Locate 12-[G の桁数],2,G
 ・
Locate 12-[U の桁数],3,U

に変更できれば、うまくゆきます。あとは、数の桁数を知る方法があれば、問題解決です。

・・・・・・・・・・

いきなり解決策を提示します。
J に入っている数の桁数は、下記の式で求められます。

1+Int(log(J))

これは、自分のプログラムで多用しており、非常に便利なものです。この式について、詳しくは以下を参考にしてください。

Casio Basic入門: Locate

fx-5800P: Locate【桁数のコントロール】


これで、Locate で正しく時間を表示できるようになりました。

Locate 8,1,"0000"
Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
Locate 11-Int(log(U)),3,U


但し、このままですと、日本時間を 0:00 にするために、0 を入力するとエラーが発生します。

実は、対数関数 log( ) を使う際の非常に重要なポイントを忘れていたからです。

対数関数 log( ) は、( ) の中の数は正の数でなければなりません。これは fx-5800P 固有の問題ではなくて、対数関数の定義です。時間は 0:00 となることがあり、日本時間の変数 J は、0:00 にするために、0 と入力すれば、0 になることがあります。日本時間が 8:00 の時は、ドイツ時間は 0:00 となり、ドイツ時間の変数 G の値は 0 になります。

幸いなことに、上の時間表示のソースでは、先ず最初に 0000 と表示してから、Locate コマンドで時間を上書きするようになっているので、時間の変数が 0 の時は、上書き表示を行わないようにすれば 0000 の表示のままで、00:00 を示します。

そこで、J が 0 でない時に時間表示を行うようにします。

例えば、Locate 11-Int(log(J)),1,J を

If J≠0:Then
Locate 11-Int(log(J)),1,J
IfEnd


とすれば良いわけです。

If 文の条件判定は、その条件が「真」なら Then 以下の処理を実行し、「真」でない( = 「偽」) ならば実行しないとなっています。

そこで、以下のようにしても良いですね。

If J:Then
Locate 11-Int(log(J)),1,J
IfEnd


「真」とは、J0 でないことで、J0 だと「偽」となります。


この3行の処理を、以下のように、スッキリと1行に記述することもできます。

J⇒Locate 11-Intlog(J)),1,J

条件ジャンプ命令 ⇒ を使っています。実は、上の If 文よりも ⇒ 命令の方が、処理速度が少し速くなります。

そこで、今回は ⇒命令を使ったコードを採用します。


If 文や ⇒命令について、詳しくは以下を参考にしてください。

Casio Basic コマンドリファレンス: If ~ then ~ IfEnd

Casio Basic コマンドリファレンス: ⇒ 命令 (条件ジャンプ)


そこで、TZD は以下のようになります。

サブルーチン TZD のプログラム
Locate 8,1,"0000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U


では、変更した TZD の動作確認のために、TZ を起動し、[0] キーを押して日本時間として 804 と入力してみます。
以下のように、目標通りに表示することを確認できました。

37-TZ1_correct_time 


log(J) は、J が正の数の時のみ正しく計算します。J が負の数の時はエラーとなります。
上のソースでは、J が 0 でない時に Locate 11-Int(log(J)),1,J を実行するようにしました。

J⇒Locate 11-Int(log(J)),1,J

対数関数 log( ) の定義では、J>0 とすべきです。これを具体的に書けば、

If J>0:Then
Locate 11-Intlog(J)),1,J
IfEnd


とすべきです。すでに、気付いて、オカシイと思われた方もいらっしゃるでしょう。


大きなうっかりミス

INPI は、負の数を扱わない仕様なので、INPI で入力すれば必ず 0 か正の数が得られます。プログラム上 J が負になる可能性はゼロです。

上の If J>0 を使ったソースのままで、もし万一 J が負になる場合は、表示が 0000 のままになります。エラーが出ずに、間違った結果を表示することになり、このバグに気付かないかも知れません。

従って、プログラム上は、絶対に J が負にならないが、他の理由で J が負いなることがあるかどうか?
もしあれば、その原因を最初から潰す必要があります。

・・・・・・・


正直に言えば、私は当初 J が負になるケースを全く想定していませんでした。でも、何度か使っているうちに、Argument ERROR (引数エラー) が発生し、問題に気付きました。うっかりしていました。

J が負になる可能性が、1つ残っていました。

電卓で他のプログラムを走らせたり、何か計算を行っている時に、J に負の数が入る可能性があります。しかし、本プログラムが起動した直後は J の値は決まっていません。と言うのも J が初期化されていないからです。

J が 0 の時は、上記のサブルーチン:TZD で対数関数 log( ) を使う時の対処で、 問題に対処できています。
プログラムが起動する前に J に負の数が入っている可能性を取り除くには、初期化処理において J を 0 で初期化します。

0→J

を、初期化処理に追加することにします。


使う変数は、できるだけ初期化してその値を確定しておくのが安全だと、再認識しました。



ここまでで、作ったプログラムは、以下の通り:

 CcLinkerを使ってfx-5800Pに転送できるCCLファイルのダウンロード
 ※ CcLinker の紹介

メインルーチン TZ のプログラム
9→P:17→Q
0→J
Prog "TZM"

While 1

-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M

If M=0:Then
8→X:1→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→J
IfEnd

If M=0:Then
A≧24⇒A-24→A
100A+B→J
A-P→C
C<0⇒C+24→C
100C+B→G
A-Q→C
C<0⇒C+24→C
100C+B→U
Prog "TZD"
IfEnd

WhileEnd




サブルーチン:TZM のプログラム (メイン画面表示)
Locate 1,1,"0:JST"
Locate 1,2,"1:CET"
Locate 1,3,"2:PST"
Locate 1,4,"<AC>:QUIT"




サブルーチン:TZC のプログラム (時間を「時」と「分」に分離)

If Z<100:Then
Z→X:0→Y
Else
Int(Z÷100)→X
Z-100X→Y
IfEnd




サブルーチン TZD のプログラム (時間の表示)
Locate 8,1,"0000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U





今回は、日本時間を入力したら、ドイツ時間とLA時間が表示されるところまで、作りました。
次回は、ドイツ時間やLA時間を入力した時の処理も追加してゆきます。



つづく...


Casio Basic入門25 / 目次




応援クリックをお願いします。励みになるので...
にほんブログ村 IT技術ブログ 開発言語へ


 



keywords: fx-5800PCasioBasic、世界時間換算, プログラミング入門プログラム関数電卓

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


関連記事

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

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

やす (Krtyski)

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


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

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

なお管理人はカシオ計算機の関係者ではなく、Casio Basicが面白いと感じる1ユーザーです。


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

リンク
月別アーカイブ
Sitemap

全ての記事を表示する

ブロとも申請フォーム

この人とブロともになる

QRコード
QR