e-Gadget - プログラム関数電卓 2022年10月

Casio Pythonへの移植:モンテカルロ法(1)

Python Casio Python
 Casioグラフ関数電卓の Python を使ってみる
     - Casio Python への移植:モンテカルロ法(1) 
目次


初版:2020/06/24
表現の修正:2020/06/27
追記:2020/10/20
追記・修正:2020/11/03
修正:2022/08/17
修正:2022/10/28

前の記事 - 3. Casio Python の入出力 |  次の記事 - 5. 関数の作成と活用


4. Casio Python への移植:モンテカルロ法(1)<fx-CG50 OS3.40以降>

Casio Basic プログラムを Casio Python へ移植しながら、ざっくりと Python の理解を進めてゆきます。

Casio Python では、入力がシェル画面でしか行えません。そこで、入力はシェル画面で行い、出力はグラフィックス画面で行う方針でスクリプト全体の構造を考え、あとは細かく作ってゆきます。

以下の動作をするスクリプトを作ってゆきます。


このスクリプトは、モンテカルロ法により円周率を求めるシミュレーションです。最初にシミュレーション回数を入力させ、シミュレーション実施の状況をグラフィカルに表示しながら、回数と円周率(pi)の値の変化をリアルタイム表示するものです。


スクリプトの構造

円を描画する関数を定義
 circle() 関数を自作

初期化処理

シェル画面でメニューを表示して、試行回数を入力させる
 print() でメニュー表示
 input() で回数を入力させ整数を取得
 ifによる条件分岐
   テンキー以外を押した時に異常終了しない処理

グラフィックス画面に出力する
 自作関数 circle() で円を描画
 draw_string() 関数で文字列を出力
 whileによる繰り返し(入力した回数分だけ繰り返し)
   random() 関数により正方形内の座標(x, y)を取得
   set_pixel() 関数で正方形内にに点を描画
   点の座標から円周率を計算 (Note 参照)
   draw_string() 関数で回数と円数率を表示
   (ここまでを繰り返す)
 draw_string() 関数でシミュレーション終了の表示


スクリプトの上から下へ制御が流れて行き、if 文while 文 で流れが変化する構造です。

Note:モンテカルロ法による円周率の計算方法
  1. 半径1の円と一辺2の外接正方形を考えます。
  2. x=1-2×[0~1の乱数]、y=1-2×[0~1の乱数] を計算して、-1<x<1-1<y<1 の (x, y)を得ます。
    つまり、(x, y) は一辺2の正方形内のランダムな点の座標となります。
  3. 正方形内にランダムに円を打って行き、全ての点の数を outs とし、そのうち x2+y2<1 になる(円内になる)回数を ins とします。(オリジナルのCasio Basic プログラムでこういう感じなので、単純に移植するために追従します)
  4. [正方形の面積]:[円の面積]outs:ins=4:π なので、π=4×ins/outs となります。

円描画関数の作成
Casio Python には、円を描画する組み込み関数が無いので、自分で作る必要があります。
ここでは、円の中心位置を決める x 座標と y 座標、そして円の半径 r をパラメータに指定して円を描画する関数を作ります。
Python の書式に従って、
 def circle(x, y, r):
  必要な処理

と記述します。詳細は 4.4 circle() 関数の作成 で説明します。

初期化処理
各変数の初期値を設定します。個別の処理と一緒に説明します。

シェル画面でメニュー表示と入力
主に、print() 関数と input() 関数の使いこなしがポイントです。if 文も使います、詳しくは 4.3 メニュー機能の作成 で説明します。

グラフィックス画面に出力
set_pixel() 関数と draw_string() 関数、そして clear_screen() 関数と show_screen() 関数の使いこなしがポイントです。 while 文も使います。詳しくは 4.5 グラフィックス出力 で説明します。 



今回作るスクリプトは、"これだけ知っていれば、簡単なスクリプトは作れる最低限の Casio Python の知識" で作りました。今回のメインテーマは、そのレベルの知識を紹介することです。

今回紹介する内容について、ネットで詳しく調べたり、より Python らしいコードを習得すれば、学習が深まると思います。


4.1 コメントの書き方 <fx-CG50, fx-9750GIII, fx-9860GIII OS3.40以降>

Pythonスクリプトでコメントを書くには、# を使うか トリプルクォート を使います。

Python公式:Comments
PEP 8 - Style Guide ofr Python の Comments の項 に推奨するコメントのスタイルが書かれています。ここでは、# を使ったブロックコメントとシングルラインコメントの推奨スタイル、そして3重ダブルクォーテーションを使った docstrings の推奨スタイルについて書いてあります。

Note:PEP 8
Python 公式文書 では、開発者のためのガイドラインや開発した機能が Python Enhancment Proposals (PEPs) にまとめられています。そして、全ての PEP はインデックス番号で文書管理されていて、コメントに関する推奨スタイルは PEP 8 にまとめられています。

#
# から行末までが、コメントとして扱われ、実行されません。公式推奨スタイルでは、# のあとにスペース1個を置いてからコメントを書くことになっています。また、説明を入れる記述と同じインデントレベルで書くことを推奨しています。
Casio Python は画面が狭いので、管理人は #  の後のスペースを入れないことが多いです。

Key Press:#
エディタ画面(スクリプト編集画面) で、[F3] (SYMBOL) - [F6] (▷) と押すと、[F1] (#) で # を入力できます。


''' (トリプルクォート - 3重シングルクォーテーション)
'''''' の間がコメントとして扱われます。複数行をまとめてコメントにすることができます。

Key Press:'
エディタ画面で、[F3] (SYMBOL) - [F6] (▷) と押すと、[F2] (') で ' を入力できます。


""" (トリプルクォート - 3重ダブルクォーテーション)
"""""" の間がコメントとして扱われます。複数行をまとめてコメントにすることができます。
Python のスタイルガイドでは、公開する関数やメソッドに関する説明は、3重ダブルクォーテーションを使った Documentation Strings を推奨しています。

Keypress:"
エディタ画面で、[F3] (SYMBOL) - [F6] (▷) と押すと、[F3] (") で " を入力できます。

Python公式:Domumentation Strings (Docstrings)
PEP 8 - Style Guide for Python の Documentation Strings の項 に詳しく書かれています。
・def 文の行の下の行を """ で始め、これに続いてその関数の説明をできるだけ簡潔に1行以内で書きます。
・そして、空行を入れます。
・空行の下から、パラメータや戻り値の説明を入れます。

Casio Python では、"""""" の間はピンク色になって分かりやすくなります。度 (degree) で表した角度をラジアン (radian) に変換する関数での Docstrings の一例です(たった2行のスクリプトなので、コメントばかりで大げさになっています);

 def rad(x):
 
"""Returns angle in radian

 Parameters:

 ーーーーーーーーーーーーー
 x: float
  angle in degree

 Returns:

 ーーーーーーーーー
 float
  angle in radian
 """

  return pix/180


4.2 モジュールの呼び出し - import <fx-CG50, fx-9750GIII, fx-9860GIII OS3.40以降>

Python は、最初から組み込まれている builtins モジュールに加えて、後からモジュールを追加して機能を増やせるようになっています。Casio Python は、math モジュールと random モジュールが追加された状態で最初にリリースされ、その後 casioplot モジュールが追加されました。今回は、これら全てを使いますので、モジュールの呼び出しをスクリプトの冒頭に書く必要があります。

例えば、set_pixel() 関数を使いたい場合は、それが含まれている casioplot モジュールを呼び出します。関数を使う前に、モジュールの呼び出しを記述しなければなりません。呼び出し方法は2通りあり、それによって関数の使い方が変わります。


import モジュール名

書 式
import casioplot
casioplot.set_pixel(x, y)

モジュールに含まれる関数を使う際は、関数の前に モジュール名. を追加しなければなりません。
casioplot オブジェクトに帰属する関数は、. で繋いで明示的に帰属関係を示す必要があります。これはオブジェクト指向言語に共通する書式と言えます。


from モジュール名 import *

書 式
from casioplot import
set_pixel(x, y)

はワイルドカードで、casioplot から全ての関数を呼び出すという意味で、帰属関数の関数名だけを書いて使えるようになります。

 これまでをまとめたスクリプト:
"""Sample script

Exercise;
porting from Casio Basic
"Monte Carlo Method"

by Krtyski/e-Gadget
"""

from casioplot import *
from random import *
from math import *



4.3 メニュー機能の作成 <fx-CG50, fx-9750GIII, fx-9860GIII OS3.40以降>

シミュレーション試行回数を変数 temp_try に入れることにします。試行回数 (try数) の仮変数という意味で temp を使って、temp_try という変数名にしました。

そこで、入力処理で最低限必要な記述は、

temp_try = input()

となります。

これを実行するとシェル画面で入力待ちになりますが、何も表示されず入力を待っています。そしてテンキーで数値を入力してから[EXE]キーを押すと、変数 temp_try に数値が格納されます。但し、input() の戻り値は、数値ではなくて文字列になるのが仕様で、これに留意します。

さて、次のようにすれば、入力の際に分かりやすくなります;
temp_try = input('Input number:')


Reference:⇒ input()

Note:Python での文字列 - ' ' と " "
string = '12345abcd'
あるいは
string = "12345abcd"
と書けば 変数 string は文字列型の変数として自動的に定義され、srting に文字列データ格納されますす。
Python では、シングルクォーテーションでもダブルクォーテーションでも、どちらでも使えます。
例えば、文字列の一部に " が入っている時、文字列の定義で ' を使えば " が文字列の一部として使える、といったメリットがあります。
string = 'He said "Wow"'
print(string)
を実行すると、
He said "Wow"
と出力されます。

Python で文字列は、シングルクォーテーション ' あるいは ダブルクォーテーション " で挟みます。Python 公式文書ではシングルクォーテションを使う事例が普通に使われているので、ここでは ' を使うことにします。そこで、文字列をパラメータに指定して input('Input number') と書きます。

これを実行すると、シェル画面では以下のようになります;

Input number:

そして、Input number: の直後でカーソルが点滅しているので、入力が分かりやすくなります。

monteca_input_1 

これで十分ですが、管理人は余計な表示を消したくなります。それだけでなく、このプログラムの説明も表示したくなります。

シェル画面では、[EXE}キーを押して改行すると、表示が上へスクロールされます。シェル画面の表示をクリアする関数が用意されていないので、余計な表示は改行でスクロールするしかありません。

そこで、print() 関数を使って表示を追加してみます。

以下のような表示を目標にします。
monteca_first_screen 

プログラム開始時は、試行回数500回をデフォルトにしておき、[EXE]キーでスグにシミュレーション開始。回数を変えたい場合は入力してから[EXE]キーを押してシミュレーション開始、となる仕様にします。これは、print() 関数と input() 関数だけで実現できます。

print(文字列) とするとシェル画面に文字列が表示され、改行されるのが、デフォルトの仕様です。
文字列なしで、単に print() とすると、文字列はシェル画面に表示されずに、改行だけが行われます。

すると、上の表示を行ってから最後に入力待ちにするには、以下のようにします。
・改行のみ
・Monte Carlo: calc Pi と表示して改行
・改行のみ
・# of try:500 と表示して改行
・[EXE] to start. と表示して改行
・改行のみ
・input() で Change the #? と表示して入力待ちして、変数 n に格納

これをスクリプトで書くと、文字列は ' ' の間に書くので、以下のようになります。
print()
print('Monte Carlo: calc Pi')
print()
print('# of try:500')
print('[EXE] to start.')
print()
temp_try = input('Change the #?')


ところで、エスケープシーケンスの1つである '\n' を文字列に使って print('\n') を実行しても改行されます。\ はバックスラッシュといい、/ (スラッシュ) とは傾きが違っていることに注意してください。

Key Press:\ (バックスラッシュ)
エディタ画面で、[F4] (CHAR) を押して、キャラクタ一覧から \ を選びます

そこで、上のスクリプトを書き換えてみます。

print('\nMonte Carlo: calc Pi')
print('\n# of try:500')
print('[EXE] to start.')
temp_try = input('\nChange the #?')


さて、ここで変数 temp_try に代入されるのは文字列です(input() の仕様)。例えば 1000 とキー入力すると temp_try には 文字列 '1000' が格納されます。ここでは、シミュレーション回数の変数 n_try に数値として 1000 を代入したいところです。
そこで、関数 int() を使います。

Note:int()
int(x) は、浮動小数点あるいは文字列の x を整数に変換します。浮動小数点については、小数点以下を切り捨てて整数にします。文字列については、数字だけの文字列なら整数に変換し、数字以外の文字列が含まれるときはエラーになります。

n_try = int(temp_try) とすると、n_try に整数が格納されます。

temp_try が数字だけの文字列かどうかを判定するには、isdigital() 関数が使えます。これは文字列オブジェクトの帰属関数なので、文字列型オプジェクト名に . を使って繋げて記述します。ここでは、文字列型のオブジェクトである temp_try の帰属関数として使うので、temp_try.isdigit() と書きます。

n_try = 500
if temp_try.isdigit():
 n_try = int(temp_try)


こうすると、デフォルトの試行回数が500回で、正しく数値が入力されたときは、その整数値を n_try に代入し、数値以外の文字が含まれた時は、n_try にはデフォルトの500回が適用された状態で、次の処理に進みます。

Note:if 文
if 文の書式
 if
条件1:
  処理1
  ・・・
 elif 条件2:
  処理2
  ・・・
 else:
  処理3
  ・・・
条件1が True (真)のとき(成り立つ時)あるいは 0 でない時、処理1を実行、
条件2が True (真)のとき(成り立つ時)あるいは 0 でない時、処理2を実行
それ以外のとき、処理3を実行
ifelifelse の行末にはコロン : が必要です。
コロン : の次の行には、インデントを1段深くします。深くなったインデントレベルが同じ行が if の範囲を示します。
elif でインデントレベルが1段戻り、if と同じインデントレベルにします。これにより ifelif が同列だと示します。
elif の行末にもコロン : が必要で、その下の行のインデントレベルで elif の範囲を示します。
else: の範囲も同様です。
このように、インデントレベルはスクリプトの正しい実行のために、極めて重要です。


Note:Python のデータ型
Casio Python で使う頻度の高いデータ型は、ざっくりと 数値型とシーケンス型に分けられます。そして数値型とシーケンス型は、いくつかのデータ型にさらに分けられます。
数値型: 整数型浮動小数点型に分けられます。
シーケンス型文字列型リスト型タプル型辞書型集合型に分けられます。
 シーケンス型は、複数要素を , で区切って並べたデータ型です。
データの種類に応じて、以下のデータ型があります。定義方法も異なります。

数値型変数の定義:   val = 123
浮動小数点型変数の定義:val = 12.34

文字列型
変数の定義:val = '12.34'
リスト型変数の定義:val = [12, 16, 24, 48]  val=['I', 'have', 'a', 'pen', '.']
タプル型変数の定義:val = (255, 255, 0)
辞書型変数の定義: val = {'ketchup':'red', 'mustard':'yellow', 'coffee':'black'}
集合型変数の定義: val = {'sun', 'mercury', 'venus', 'earth', 'mars', 'jupiter'}
   要素を囲む記号とコロン : の有無で、シーケンス型に属する細かいデータ型が決まります。
    Casio Python のオブジェクト一覧 を参照

今回は、整数型、浮動小数点型、文字列型の3つのデータ型を使います。


 これまでをまとめたスクリプト:
"""Sample script

Exercise;
porting from Casio Basic
"Monte Carlo Method"

by Krtyski/e-Gadget
"""

from casioplot import *
from random import *
from math import *

#initializing
n_try 500

#display menu to select try#
print('\nMonte Carlo: calc Pi')
print('\n# of try:'+str(n_try))  #ココの説明がまだでした!
print('[EXE] to start.')
temp_try input('\nChange the #?:')
if temp_try.isdigit():
 n_try int(temp_try)

まだ説明していなかった点を補足します。

上の作りかけのスクリプトでは
 print('\n# of try:') 

 print('\n# of try:'+str(n_try))
に変更しています。

数値変数 n_try を文字列に変換したものを + (文字列結合)を使って、文字列 '\n# of try:' に結合しています。
数値を文字列に変換するために、str() 関数を使っています。

Note:str()
str(x) は、オブジェクト x を文字列に変換して返します。x に整数型や浮動小数点型を指定すれば、文字列型で返します。


これで、以下の表示と動作の目標を達成しました。
monteca_10000_start 


4.4 circle() 関数の作成

これから、円を描画する circle() 関数を作ります。

この関数の書式を以下のようにします。
 circle(x, y, r)
 x: 整数型 (int型)、円中心の x 座標
 y: 整数型 (int型)、円中心の y 座標
 r: 整数型 (int型)、円の半径


関数を定義するには、def 文を使います。

 def circle(x,y,r):
  処理1
  処理2
   :
   :


def 文の行末には、コロン : が必要です。
コロン : の下の行は、インデントレベルを1段深くし、このインデントレベル以下の行が、def の範囲を決めます。

circle() 関数を使う場合は、例えば、circle(100,100,50)circle(px, py, r) のように書きます。3つのパラメータは、第1引数は x 座標値、第2引数は y 座標値、第3引数は 半径、といったように引数の順序、つまりその位置で意味が決まります。これを位置引数 (Positional Argument) と言います。

circle() 関数の定義は、circle() を使う前に記述する必要があります。スクリプトは上から下へ実行されるからです。今回は、スクリプトの冒頭、モジュール呼び出しの下に記述することにします。

 circle_desc 
グラフィックス画面 (描画画面) では、左上の座標が (0, 0) 、右方向へ正の x 軸、下方向へ正の y 軸になります。circle() 関数で、中心座標が (x, y)、半径 r の円を描画するようにします。

円を p 個の点で描画する時、描画する点(上で赤い点)を i を 0 から p-1 まで1づつ変化させながら、角度 i*a (=θ)で描画します(上の図を参照)。ここで、円を描く際の角度の1刻みが 角度 a になります。

以下のような方法で円を描画することにします;

def circle(x, y, r):
 p = (式)
 a = (式)
 for i in range(p):
  px = x + r*cos(i*a)
  py = y + r*sin(i*a)  
  draw_pixel(int(px), int(py))
  show_screen()


==========

この方針に従ってスクリプトを仕上げます。ap をどうやって決める(計算する) のかがポイントです。

Casio Python での三角関数は、角度がラジアンに限定されていますので、スクリプトはラジアンを使って角度を記述する必要があります。そこで、1周360° が 2π ラジアンなので、p 個の点で円を描画するときの角度の1刻み a は、2πp で割った角度になります。
 a = 2*pi/p
これで、a を算出できます。

さて、math モジュールには 円周率を返す関数として pi があります。そこで、math モジュールを呼び出した上で、上のように pi を使います。

すると、上の図から分かるように、i 番目の点の座標 (px, py) は次のように計算できます。
 px = x + r*cos(i*a)
 py = y + r*sin(i*a)

 
座標 (px, py) に点を描画するには、
 set_pixel(px, py)
を使いますが、px と py は整数でないとダメです。液晶パネルのドットは整数の座標で決まります。
しかし、上で計算した px と py は浮動小数点になっています。そこで、int() 関数を使って、浮動小数点の小数を切り捨てて、整数に変換します。

 set_pixel(int(px), int(py))

とすればOK。

そして、set_pixel() 関数でVRAMにデータ転送したものを、show_screen() 関数で画面に転送すれば、点が表示されます。

==========

この点の描画を、i を 0 から p-1 (整数) まで1づつ変化させながら繰り返すには、for 文を使います。

for i in range(p):
 px = x+r*cos(i*a)
 py = y+r*sin(i*a)
 set_pixel(int(px), int(py))

 show_screen()

set_pixel() 関数は、VRAMにデータを書き込むだけで、画面への転送を行いません。そこで、show_screen() 関数で画面にデータ転送を行うことで、描画が完了します。

Note:for 文
for i in range(p):
 処理

は、ip-1 になるまで1つづつ増やしながら、処理を繰り返します。
for 文の行末にはコロン : が必要です。コロン : の下の行はインデントレベルを1段深くします。このインデントレベルが同じ行がfor の範囲、つまり繰り返し処理の対象になります。ここでも、コロン : とインデントレベルは、正常動作のために極めて重要です。

==========

最後に、円を描画するために使う点の数 p の値を決めます。

[2020/11/03 追記修正]
先ず、CGモデル (fx-CG50) 向けに検討し、最後に FXモデルへの対応を検討します。

円の描画は、できる限りきれいで滑らかにしたいので、p は十分に大きくすれば良いのでしょうが、一方、できる限り短い時間で効率よく描画するには、p の値は必要最小限にしたいところです。必要最小限の点の数 p をどうやって決めるのかを考えてみます。適当で良いのかも知れませんが、チョットこだわってみます。

円を描画するとき、点と次の点の間隔が一番大きくなるのは、画面横幅分の 387 ドットの半径の円がx軸と垂直に交わる時です(必要条件)。その時に点と点の間隔の y座標の変化が1ピクセルになるときの点の数を Pmax とします。Pmax は、半径が 383 (画面横幅)の円を描画する時の点の数です。383 よりも小さな半径 r の円を描くための点の数 p は、Pmax よりは少なく

p = Pmax × (r/383)   (式1)

で十分だと分かります (Pmax を半径 383r で比例配分したもの)。

半径 383 の円で y座標値が一番急激に変化するのは、角度 0 の時なので、y座標値が 1 (pixel) だけ変化するときの角度変化を θ とすると、この θ は、滑らかに円を描画するために無駄のない最大の角度刻みとなります。これ以下の角度刻みは無駄だし、これ以上だと歯抜けの円となります。

この角度刻み θ は、383×sin(θ) = 1 となるときの θ です。この式を変形すれば、θ は以下のように計算できます。

θ = sin-1(1/383)

半径 383 で、さらに角度刻み θ で点を描画して円にするとき、1週するのに必要な点の数、つまり Pmax は以下になります。

Pmax = 2π/θ = 2π/sin-1(1/383)  (式2)

(式1) と (式2) から、以下の式で p が決まります。この p は、半径 r の円を描画するときに、滑らかでかつ無駄のない最小の描画点数です。

p = r * 2π/sin-1(1/383) / 383 = r*6.283178168  (CGモデル用)

この式を FXモデル用に適用するためには、383127 に置き換えれば良いことになります。383 はCGモデルでの画面の横幅で、127 はFXモデルでの画面の横幅です。

p = r * 2π/sin-1(1/127) / 127 = r*6.28312038  (FXモデル用)

CGモデル用とFXモデル用を見比べると、r の係数が小数点以下4桁まで同じだと気がつきます。そこで有効数字を考慮して r の係数を 6.283 とすれば、CGモデルとFXモデルの両方で共通して使えると思います。

p = r*6.283  (CGモデルとFXモデル共用)

ようやく p が決まったので、これから a が求められ、あとは上のロジックでスクリプトを書けば、circle() 関数が完成します。

==========
求めた p の妥当性
p を決める計算に登場する r の係数 (= 6.283) は、ほぼ 2π (π = 3.1415926...) になっています。円周の長さ (2πr) の値を に採用しても小数点以下3桁まで同じ計算結果になります。離散的なピクセルの間隔から必要最小限の p の数を求めた結果、FXモデルのように解像度の低い液晶画面でも、連続的な円周の長さの公式  p=2πr を採用しても大きな支障がないことが確認できました。 
==========

以上まとめると、中心座標が (x, y)、半径が r の円を描画する関数は、以下になります。

def circle(x, y, r):
 p = r*6.283
 a = 2*pi/p
 for i in range(p):
  px = x+r*cos(i*a)
  py = y+r*sin(i*a)
  set_pixel(int(px), int(py))
  show_screen()


さて、描画しようとする点 (pxpy) がグラフィックス画面の外側の時は、描画しないて次へ進んだ方が、さらに処理時間が節約できて、より効率化できます。

そこで、px を求める計算の直後で、px<0 または px>383 の時は、set_pixel() をスキップして、次の繰り返しを実行するようにします。それには、以下の赤の2行を追加します。

  px = x+r*cos(i*a)
  if px<0 or px>383:
   continue


同様にして、py を求める計算の直後に、py<0 または py>191 の時は、set_pixel() をスキップして、次の繰り返しを実行するように、以下の赤の2行も追加します。

  py = y+r*sin(i*a)
  if py<0 or py>191:
   continue



Note:continue
繰り返し処理(ループ)を行う for 文 と while 文 で、繰り返し処理の中で continue を使うと、それ以降の処理を行わずに forwhile にジャンプできます。

ここで、CPython に慣れた方は、上の range(p) に違和感を覚えるかも知れません。range() 関数の引数は整数でないとエラーになる筈なのに、Casio Python ではエラーになりません。これは独自仕様と言えそうです。

Reference:⇒ range()


以上で circle() 関数ができました。


 これまでをまとめたスクリプト:
"""Sample script

Exercise;
porting from Casio Basic
"Monte Carlo Method"

by Krtyski/e-Gadget
"""

from casioplot import *
from random import *
from math import *

#draw circle
def circle(xyr):
 r*6.283
 2*pi/p
 for i in range(p):
  px r*cos(i*a)
  if px<0 or px>383:
   continue
  py r*
sin(i*a)
  if py<0 or py>191:
   continue 
  set_pixel(int(px)int(py))
  show_screen()

#initializing
n_try=500

#display menu to select try#
print('\nMonte Carlo: calc Pi')
print('\n# of try:'+str(n_try))
print('[EXE] to start.')
temp_try input('\nChange the #?:')
if temp_try.isdigit():
 n_try int(temp_try)

#display graphics
#これ以降を書いて、プログラムを完成させます


4.5 グラフィックス出力 <fx-CG50 OS3.40以降専用>

Casio Python でグラフィックス画面 (描画画面) へ出力する関数は、点を描画する関数 set_pixel() と 文字列を描画する draw_string() の2つしかないので、これらを使いこなしたいと思います。set_pixel() については既に説明したので、ここでは、draw_string() に焦点を当てます。

これらのグラフィックス出力関数は、VRAMへのデータ転送を行い、画面への出力までは実行しません。従ってフラフィックス画面への出力は、show_screen() 関数を実行する必要があります。

グラフィックス画面を消去する clear_screen() 関数も使います。これは OS3.4 では隠し関数でしたが、OS3.5以降は公式関数となっています。

Note:Casio Python 組み込み関数を調べる
既に紹介しているように、隠し関数を調べるために ObjName.py が使えます。
これで見つかるのはオブジェクト名なので、ネットで詳細を調べる必要があります。


モンテカルロ法シミュレーションプログラムのグラフィックス画面への出力ブロックは、冒頭で書いたように、以下の手順でスクリプトを書いてゆきます。

 =============================================
 4.5.1 自作関数 circle() で円を描画
 4.5.2 draw_string()
関数で文字列を出力
 4.5.3 while
文による繰り返し(入力した回数分だけ繰り返し)
 4.5.4  random()
関数により正方形内の座標(x, y)を取得
 4.5.5  set_pixel()
関数で正方形内に点を描画
 4.5.6  
点の座標から円周率を計算
 4.5.7  draw_string()
関数で回数と円数率を表示
      
(ここまでを繰り返す)
 4.5.8 draw_string()
関数でシミュレーション終了の表示
 =============================================

4.5.1 自作関数 circle() で円を描画

円の中心座標を (290, 96) とし、半径を 90 とするので、以下を記述すればOKです。
そこで、それぞれを以下の変数に代入したものを使います。(数値を直接使っても問題ありませんが、あとで変更する可能性を考えて、初期化処理のブロックで変数宣言して、それを使うことにします。

以下を 初期化処理のブロックに追加します。
 r = 90 #radius
 dx = 290dy = 96 #center


Note:文の句切り文字 - ;
Python では、文の句切りとして改行が使われます。1行に複数の文を記述したいときは、文の句切り文字としてセミコロン ; も使えます。

円を描画するために、コメント #display graphics の下に
 circle(dx, dy, r)
を追記します。


4.5.2 draw_string() 関数で文字列を出力

以下のような出力になるようにスクリプトを書きます。
monteca_graphics_2 

 #initializing
 n_try 500
 r 90 #radius
 dx 290dy 96
#center


 #display graphics
 clear_screen()
 circle(dx,dy,r)
 draw_string(12,0'C=')
 draw_string(0,16'pi=')
 draw_string(0,160'# of try:'+str(n_try))
 draw_string(0,176'AC:Quit')
 show_screen()

今回既に説明した内容で書けると思います。


4.5.3 while 文による繰り返し

Python
には、繰り返し処理 (ループ) を行うために for 文と while 文の2つしかありません。for 文は既に使ってみました。ここでは While 文を使います。

Note:while 文
while 条件:
 処理1
 処理2

これが、while文の書式で、while の行末にはコロン : が必要で、コロンの行の下のインデントレベルを1段深くします。同じインデントレベルの行が、while による繰り返し処理の対象になります。

今回の繰り返し条件については、あとで説明します。


4.5.4 random() 関数により正方形内の座標(x, y)を取得

乱数発生関数 random() を使います。random() は、0 以上 1 未満のランダムの数値を返します。
ここでは、x が -1 ~ +1、y が -1 ~ 1 の間の乱数を取得します。

 x=1-2*random()
 y=1-2*random()



4.5.5 set_pixel() 関数で (x, y) に点を描画

点を描画するのは、円の中心 (dx, dy) と同じ座標を中心として1辺が2の正方形の範囲内です。そこで、点を描画する座標は、
 (dx+r*x, dy+r*y) 
となります。但し、set_pixel() のパラメータは、整数でないとエラーになるので、それぞれ int() で小数点以下を切り捨てて整数にします。

さらに、点を描画するには、set_pixel() を実行後に show_screen() を実行します。

 set_pixel(int(dx+r*x), int(dy+r*y))
 show_screen()



4.5.6 点の座標から円周率を計算

Note:モンテカルロ法による円周率の計算方法 (再掲)
  1. 半径1の円と一辺2の外接正方形を考えます。
  2. x=1-2×[0~1の乱数]、y=1-2×[0~1の乱数] を計算して、-1<x<1-1<y<1 の (x, y)を得ます。
    つまり、(x, y) は一辺2の正方形内のランダムな点の座標となります。
  3. 正方形内にランダムに円を打って行き、全ての点の数を outs とし、そのうち x2+y2<1 になる(円内になる)回数を ins とします。(オリジナルのCasio Basic プログラムでこういう感じなので、単純に移植するために追従します)
  4. [正方形の面積]:[円の面積]outs:ins=4:π なのて、π=4×ins/outs となります。
これをスクリプトで表現します。

 if x**2+y**2<1:
  ins+=1
 outs+=1
 pai = round(4*ins/outs, 11)


さて、While の条件を保留にしていましたが、ここで決めます。点を1つ描画するために 変数 outs が1づつ増えます。そこで、outs が試行回数 n_try よりも小さいこと、つまり outs<n_try を繰り返しの条件とします。

Note:累乗演算子 - **
x2Python では、x**2 と書きます。

Note:累算代入演算 (+=, -=, +=, /=, %=)
ここで、+= という演算があります。C言語系の経験があれば、おなじみだと思いますが、累算代入演算と言います。
ins+=1 は、ins=ins+1 と同じで、これを省略して記述するための演算子です。
a = a+b は、a+=b
a = a-b は、a-=b
a = a*b は、a*=b
a = a/b は、a/=b
a = a%b は、a%=b
と書けます。
一方、C言語系でおなじみに ++ 演算子(インクリメント、1増やす) を使って ins++ とすると、Pythonではエラーになります。

Note:四捨五入 - round()
Casio Python の浮動小数点は、小数点以下の有効桁数は15です。
シェル画面で、
 from math import *
 pi
を実行すると円周率が表示されますが、小数点以下15桁になっています。
今回のプログラムでは、計算結果の円周率は、何もしないと小数点以下15桁で表示されます。この桁数だと点描画の領域にテキストが上書きされます。これを避けるために、round() 関数を使って、
 pai = round(4*ins/outs, 11)
により、小数点以下11桁を指定して四捨五入しています。


4.5.7 draw_string() 関数で回数と円周率を表示

draw_string(36, 0, outs)
draw_string(36, 16, pai)


とすれば良いはずです。


ここまでをまとめます。

 これまでをまとめたスクリプト:
"""Sample script

Exercise;
porting from Casio Basic
"Monte Carlo Method"

by Krtyski/e-Gadget
"""

from casioplot import *
from random import *
from math import *

#draw circle
def circle(x,y,r):
 r*6.283
 2*pi/p
 for i in range(p):
  px x+r*cos(i*a)
  if px<0 or px>383:
   continue
  py y+r*sin(i*a)
  if py<0 or py>191:
   continue
  set_pixel(int(px)int(py))
  show_screen()

#initializing
n_try 500
ins = 0; outs = 0
90 #radius
dx 290dy 96 #center

#display menu to select try#
print('\nMonte Carlo: calc Pi')
print('\n# of try:'+str(n_try))
print('[EXE] to start.')
temp_try input('\nChange the #?:')
if temp_try.isdigit():
 n_try int(temp_try)

#display graphics
clear_screen()
circle(dx, dy, r)
draw_string(12,0'C=')
draw_string(0,16'pi=')
draw_string(0,160'# of try:'+str(n_try))
draw_string(0,176'AC:Quit')
show_screen()

while outs<n_try:
 x 1-2*random()
 y 1-2*random()
 set_pixel(int(dx+r*x), int(dy+r*y))
 if x**2+y**2<1:
  ins+=1
 outs+=1
 pai round(4*ins/outs,11)
 draw_string(36,0str(outs))
 draw_string(36,16, str(pai))
 show_screen()


さて一番下から3行の部分は、この通りに動作するとテキスト表示が次々と上書きされ、結果として真っ黒になってしまいます。
そこで、数字をカウントアップして、次々と変化が見えるようなスクリプトを検討します。


カウントアップのスクリプト

先ず、以下のスクリプトを作って検討します;

from casioplot import *
c = 0
clear_screen()
while c<=1000:
 draw_string(0, 0, str(c
))

 show_screen()
 c+=
1


変数 c を while ループを回るたびに 1 づつカウントアップし、それをグラフィックス画面に表示しています。
下から3行目 は、次々と上書きするので、以下のようになります。
countup_1 

そこで、同じところに空白文字で上書きすることで消去したのち、c の値を出力すれば良いというのは、いつも行うことです。
 draw_string(0, 0, '   ')
 draw_string(0, 0, s)


これでは、解決しません。スペースは空白文字ではないことが分かります。
では、明示的にスペースのエスケープシーケンス \x20 (16進数) あるいは \32 (10進数) を使ってみます。
 draw_string(0, 0, '\x20\x20\x20\x20')
 draw_srting(0, 0, s)


これでもダメです。
ちなみに、スクリプト編集画面で、[F4] (CHAR) を押してキャラクタセットを見てみると、そこには空白文字が見当たりません。スペースあるいは空白文字で上書きする方法は、Python では有効ではなさそうです。ネットで調べてみても、それらしい解決方法が簡単には見つかりません。

draw_string() 関数の第3パラメータ(引数) で、文字色を設定できます。そこで、同じ文字列を背景色の白で描画すれば、消去できるはずです。ループで前回描画したときのカウント cprev_c 変数に代入しておき、次に prev_c を白で描画すれば、目的の動作が可能になりそうです。そこで、次のようにスクリプトを変更してみます。

from casioplot import *
c = 0
clear_screen()
while c<=1000:
 draw_string(0, 0, str(prev_c), (255,255,255)) #追加
 draw_string(0, 0, str(c
))

 show_screen()
 prev_c = c #追加
 c+=
1


文字色の指定は、RGB指定なので、(255,255,255) で白を指定します。
これで目的が達成できました!!

ところで、追加した draw_string(0, 0, prev_s, (255,255,255)) の次に show_screen() も追加してみると、数値表示がチカチカして見づらくなります。show_screen() で画面への転送を行うと、消去した文字列が一旦表示されるのが原因です。そこで、VRAM上で、文字列消去と次の文字列データの書き込みを行ったのち、一気に画面への転送を行うのが良いわけです。


これと同じ方法を、モンテカルロ法のスクリプトに適用します。outs と pai の値を prev_outs と prev_pai の2つの変数に一旦格納し、次のループでの文字列表示の前に、前回の文字列を白色で出力します。

 これまでをまとめたスクリプト:
"""Sample script

Exercise;
porting from Casio Basic
"Monte Carlo Method"

by Krtyski/e-Gadget
"""

from casioplot import *
from random import *
from math import *

#draw circle
def circle(x,y,r):
 r*6.283
 2*pi/p
 for i in range(p):
  px x+r*cos(i*a)
  if px<0 or px>383:
   continue
  py y+r*sin(i*a)
  if py<0 or py>191:
   continue
  set_pixel(int(px)int(py))
  show_screen()

#initializing
n_try 500
ins = 0; outs = 0
prev_outs = 0
prev_pai = 0
90 #radius
dx 290dy 96 #center

#display menu to select try#
print('\nMonte Carlo: calc Pi')
print('\n# of try:'+str(n_try))
print('[EXE] to start.')
temp_try input('\nChange the #?:')
if temp_try.isdigit():
 n_try int(temp_try)

#display graphics
clear_screen()
circle(dx, dy, r)
draw_string(12,0'C=')
draw_string(0,16'pi=')
draw_string(0,160'# of try:'+str(n_try))
draw_string(0,176'AC:Quit')
show_screen()

while outs<n_try:
 x 1-2*random()
 y 1-2*random()
 set_pixel(int(dx+r*x), int(dy+r*y))
 if x**2+y**2<1:
  ins+=1
 outs+=1
 pai round(4*ins/outs,11)
 draw_string(36, 0, str(prev_outs), (255,255,255))
 draw_string(36, 16, str(prev_pai), (255,255,255))
 draw_string(36,0str(outs))
 draw_string(36,16, str(pai))
 show_screen()
 prev_outs = outs
 prev_pai =
pai


4.5.8 draw_string() 関数でシミュレーション終了の表示

シミュレーションが終了したときは、以下のように、左下の表示を Finish=>[EXIT] に変更しようと思います。
monteca_500 

シミュレーション実行中は、左下に AC:Quit と表示されています。そこで、これを白色で出力したのち、Finish=>[EXIT] を黒で出力すれば良いことは既に分かっています。

draw_string(0, 176, 'AC:Quit', (255,255,255))
draw_string(0, 176, 'Finish->[EXIT]')
show_screen()



このスクリプトは、while ループの外で実行するので、インデントレベルは while の中の処理よりも1段浅くしなければなりません。

 完成したスクリプト: monteca1.py のダウンロード
"""Sample script

Exercise;
porting from Casio Basic
"Monte Carlo Method"

by Krtyski/e-Gadget
"""

from casioplot import *
from random import *
from math import *

#draw circle
def circle(x,y,r):
 r*6.283
 2*pi/p
 for i in range(p):
  px x+r*cos(i*a)
  if px<0 or px>383:
   continue
  py y+r*sin(i*a)
  if py<0 or py>191:
   continue
  set_pixel(int(px)int(py))
  show_screen()

#initializing
n_try 500
ins = 0; outs = 0
prev_outs = 0
prev_pai = 0
90 #radius
dx 290dy 96 #center

#display menu to select try#
print('\nMonte Carlo: calc Pi')
print('\n# of try:'+str(n_try))
print('[EXE] to start.')
temp_try input('\nChange the #?:')
if temp_try.isdigit():
 n_try int(temp_try)

#display graphics
clear_screen()
circle(dx, dy, r)
draw_string(12,0'C=')
draw_string(0,16'pi=')
draw_string(0,160'# of try:'+str(n_try))
draw_string(0,176'AC:Quit')
show_screen()

while outs<n_try:
 x 1-2*random()
 y 1-2*random()
 set_pixel(int(dx+r*x), int(dy+r*y))
 if x**2+y**2<1:
  ins+=1
 outs+=1
 pai round(4*ins/outs,11)
 draw_string(36, 0, str(prev_outs), (255,255,255))
 draw_string(36, 16, str(prev_pai), (255,255,255))
 draw_string(36,0str(outs))
 draw_string(36,16, str(pai))
 show_screen()
 prev_outs = outs
 prev_pai =
pai

draw_string(0, 176, 'AC:Quit', (255,255,255))
draw_string(0, 176, 'Finish->[EXIT]')
show_screen
()


4.6 まとめ

Casio Python でスクリプトを書くための最低限の知識をざっくりと説明しました。
入出力に必要な関数、構造制御構文である 条件分岐 (if)、繰り返し処理(for, while) について、今回のスクリプトでおおよその使い方が分かったのではないかと思います。

各関数やメソッドについて詳しく知りたい場合は、ネットで確認してください。なお、Casio Python特有の仕様と思われるものは、別途 Reference として取り上げました。



目 次

前の記事 - 3. Casio Python の入出力

次の記事 - 5. 関数の作成と活用





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




keywords: fx-CG50Pythonプログラム関数電卓

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



関連記事

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

番外編 - Windows10 ソフトウェア例外 0xe06d7363 エラーの解消

2022/10/18

Windows10で ソフトウェア例外 0xe06d7363 エラーの解消


3年10ヶ月使っている DELL Inspiron 5480 で、4ヶ月ほど前から以下のエラーが頻繁に発生するようになった。このエラーはファイルエクスプローラを全て閉じた後だけに発生する。

0ぇ06d7363_ErrorMessage

このエラーが表示される以外は、日常的に使っていて Windows 10 やアプリの動作に問題が見当たらない。しかし原因不明のまま使い続けるには、非常に気になるエラーだ。このエラーが発生するようになったきっかけが思い至らない。

最終的にはエラーが解消され、同時に原因も分かった。様々な試みを行ったのでそれを記録する。

この記事は自分のための記録である。ソフトウェア例外エラーに悩んでいる方のために簡単に解決策をアドバイスできないが、原因追求の考え方の参考になればと思う。

ソフトウェア例外エラーについて
アプリケーション例外エラーの原因究明と解決には、即効性のあるものは無いと思う。
殆どのまともなソフトウェアは、動作時に異常な状態を検知して必要な処理を行うようになっていて、想定外の異常に対して例外処理を行う。それでも対処できないときに例外エラーとなる。だから、その原因を探すのは地道に調べるしかない。

DELLプレミアムサポート
色々な人と話ができると、自分の思考に変化を与えてくれる。身近に詳しい人が居れば良いが、私も含めて多くの場合はそのような人は身近にいないであろう。ネットでかなり調べても、自分が直面しているソフトウェア例外エラーを解消するためのピッタリの情報が見つかることは殆どない (原因が千差万別だから)。

それでも私はDELLのプレミアムサポートを利用する。解決を丸投げしたり安直に解決策を求めるのではなく、解決に向かうためのヒントを貰うのが目的だ。解決の主役は自分自身しかない。DELLのプレミアムサポートは、そんなユーザーにも気持ち良く対応してくれる担当者がとても多い。だからDELLのPCを購入して、追加費用を払ってプレミアムサポートの契約をしている。
 今回も2人の担当者に対応頂き、確実なエラー解消方法は無いのに、当方に気持ち良く付き合って貰えた。



エラーのログを調べる

"イベントビューアー" ⇒ "管理イベントの要約" を調べる

スタートを右クリック ⇒ コンピュータの管理(G) でコンピュータの管理を開く

"システムツール" ⇒ "イベントビューアー" を開く

"最近表示されたノード" と "ログの要約" の右端にある ▲ をクリック
 これで "管理イベントの要約" が広くなる

イベントの種類 のうち エラー を展開する
 ここから今回のエラーを探す。

Event

エクスプローラを全て閉じると今回のエラーはほぼ再現されるので、何度も再現させ、エラー発生時刻を記録しておく。

そして、"過去1時間" や "24時間" の下に回数が表示されるので、多く再現させたエラー回数からログを絞り込む。

記録していたエラー発生時刻と照らし合わせて、今回のエラーを特定する。

 ErrorEvents

 エラー発生時刻から特定したのは
 - イベントID:1000
 - ソース:Application Error
 - ログ:Application
 だと判明した。

見つけたログの上で左ダブルクリック ⇒ 各エラーを左ダブルクリック
 殆どが、
 - 障害が発生しているアプリケーション名:explorer.exe
 - 障害が発生しているモジュール名:
KERNELBASE.dll
 KernelBase_dllのエラー

 頻度が低いが、以下も見つかった。
 - 障害が発生しているアプリケーション名:explorer.exe
 - 障害が発生しているモジュール名:ucrtbase.dll
 ucrtbase_dllのエラー

0xe06d7363 エラーの殆どは KERNELBASE.dll が絡み、たまに ucrtbase.dll が絡んで explorer.exe で発生していることがわかった。


原因の推定

explorer.exe (ファイルエクスプローラ), KERNELBASE.dll, ucrtbase.dll はいずれもMicrosoftが提供しているものだ。
 - KERNELBASE.dll:アプリ実行時にメモリ上のアドレスの割り振りを行う
 - ucrtbase.dll:Cで書かれたコードのランタイムライブラリ


そして、今回のアプリケーションの例外 0xe06d7363 エラーは、エクスプローラを全て閉じた後だけに発生する。explorer.exeが終了処理を行っている時に発生するエラーの可能性が高く、それもサードパーティーのアプリの影響が原因として考えられる。
遠因としては、Windows Updateにより更新されたシステムファイルと、いずれかのサードパーティーアプリとの整合性がとれなくなったことは間違いない。

いずれにせよ、おおまかに以下の可能性が考えられる。
 - Windows Update で最新でないシステムファイルによるバグによる可能性
 - システムファイルが壊れて悪影響を及ぼす可能性
 - 古いサードパーティーアプリによる例外アプリケーションエラーの可能性
 - explorer.exe のプラグインアプリによる影響

以下の確認を行って、エクスプローラを開いてから閉じて、アプリケーションの例外 0xe06d7363 エラーが発生するか、解消されるかを調べた。

Windows Update 実施
エラーは解消されない。

チェックディスク実施
 ・スタート(左下のWindowsマーク)を右クリック ⇒ Windows PowerShell(管理者) を起動
 ・chkdsk c: /f/r と入力 ⇒ [Enter] キー
 ・再起動時に実行するかと聞かれるので、[y] + [Enter]
 ・PCを再起動 ⇒ チェックディスクが実行される
ディスクに異常はなかった。エラーは解消されない。

Windowsシステムファイルの修復
 スタ-トを右クリック ⇒ Windows PowerShell(管理者)を起動
 sfc /scannow と入力 ⇒ [Enter] キー 
システムファイルの破損はなかった。エラーは解消されない。

Windowsをセーフモードで起動
 起動方法はここを参照
エラーは解消されない

Windowsをクリーンブートする
 起動方法はここを参照
エラーは解消されない


以上の結果から、サードパーティのアプリを徹底的に調べることにした。


インストールしているアプリのチェック

エラー発生以降にインストール/アップデートしたサードパティーアプリのアップデート
 時間がかかったが、1つづつアップデートした。
エラーは解消されない

怪しいアプリをアンインストールして挙動を確認
 スタートアップのアプリを1つひとつ無効にしてエラー発生を調べた。
 それ以外は、起動させてエラー発生を調べた。
 エラー発生に繋がるアプリが見つかった。
 問題発生しているのはDELLのPCで、DELLのアプリ2つをアンインストールするとエラーが解消されることを確認した。
 - DELL Update
 - SupportAssist
 あとで分かることだが、これらはエラーの真の原因ではなかった。

サービス管理ツールで、エラー発生に繋がるサービスを探す
 スタートで右クリック ⇒ タスクマネージャ ⇒ [サービス]タブをクリック
  TaskMgr_Service

下にある "サービス管理ツールを開く" をクリック
  Service_Ctrl_Tool
ここで、DellClientManagemantService (Dell Client Management Service) を無効にするとエラーの発生頻度が劇的に下がることが分かった。このサービスが動作しないと DELL UpdateSupportAssist が動作しない。 

  Service_Enabling

しかし、Dell Client Management Service を無効化してもエラーが発生することがあり、完全にエラーを解消できない。


エラーの真の原因が他にあり、Dell Client Management Service との干渉の頻度が高いと考えた。


 エクスプローラーのプラグインアプリを調べる
今回のエラーが発生する前まで正常に動作していたが、エクスプローラのプラグイン形式のアプリ - LANDisk (IO DATA のネットワークドライブ) がインストールされていた。
LANDisk

Ver 4.02 であったが、これを最新版 Ver 4.30 にアップデートした。

すると、

エラーが完全に解消した!!

エクスプローラで障害が発生していることが分かっているのだから、真っ先にプラグインアプリを疑えば良かったと後になって思う。

一旦エラーの原因と疑われた DELL UpdateSupportAssist をアンインストール後再インストールしたが、エラーが発生しないことを確認した。

IO DATA の ネットワークドライブのアプリ - LANDisk がエラーの根本原因で、DELL のアプリが動作するために必要な Dell Client Management ServiceKernelBase.dllucrtbase.dll といったモジュールレベルで何らかの干渉を受けてエラーになっていたことが判明した。


おわりに
Windowsシステムの再インストールをしても良い環境なら、サードーパーティーのアプリのインストールには最新版を使い、動作確認しながら進めるのが、最も手っ取り早い解決方法だろう。

私の場合、そして多くの場合は、システムの再インストールはできればしたくない。今回のエラー解消は、時間の合間を使ってジックリと根気よく進めた。真の原因にたどり着くまでに4ヶ月もかかったが、エラーが完全に解消されて気持ちいい!!

今回は、ネットで様々な情報を探した。その中で私個人的に最も参考になった記事を紹介する;
イベントID 1000 で記録される Application Error のイベントログについて

この記事は大変参考になり、真の原因を見つけるのに役だった。
実は、本ブログでも紹介している自作のデスクトップアプリ MyClock が原因ではないか? と真っ先に疑ったが、そうではなかった。この記事を先に読んでいれば良かったと悔やまれるが、あとで読んで安心感に繋がった。アプリを自作する方に特にお勧めだ。





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




keywords: Windows10 不明なソフトウェア例外エラー 0xe06d7363 エラー 修復

リンク集 | ブログ内マップ
関連記事

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

番外編 - Windowsシステムツールの修復

2020/10/08


Windows 10 のスタートメニュー / Windows システムツール の修復

3年10ヶ月使っている DELL Inspiron 5480 で、Windows システムツール にタスクマネージャーしか表示されないことに気がついた。この不具合を修復できたので、具体的な方法を記録しておく。


不具合と修復後の状況

Windowsシステムツールでタスクマネージャしか表示されない。

 不具合発生状況             修復後の状況
Windowsシステムツール_Before Windowsシステムツール_After



念のための検査

こうなった原因がよく分からない。何か変な操作をやった可能性もある。Windowsシステムの問題やストレージの故障によるファイルの損傷や損失の可能性もある。

Windows Update

Windows Updateで最新の状態にする
スタート ⇒ 設定 ⇒ 更新とセキュリティ ⇒ 更新プログラムのチェック


チェックディスク

システムのストレージ(HDDやSSD) をチェックする
1) 検索ボックスに cmd と入力 ⇒ コマンドプロンプト を右クリック ⇒ 管理者として実行 ⇒ [はい(Y)]
2) chkdsk /f /r と入力し [Enter] キーを押す
3) [Y] を押す ⇒ [Enter] キーを押す
4) コンピュータを再起動 ⇒ ディスクチェック
問題があれば修復される。
※ 私の場合は、問題なしであった。


システムファイルのチェック

上と同様に管理者としてコマンドプロンプトを開く
sfc /scannow を入力し [Enter] キーを押す

破損したシステムファイルがあれば、Windowsが自動的に修正する。
※ 私の場合は、問題なしであった。



修復方法

正しいショートカットを作り、正しいフォルダにコピーする。

以下、修復したい項目ごとに具体的に記載する。


コピー先の正しいフォルダ

 スタートメニューの "Windows システムツール" の下にある "タスクマネージャ" で右クリック ⇒ その他 ⇒ ファイルの場所を開く

Windows システムツール の下に何もない場合は、

エクスプローラで以下のようにフォルダを開く
> PC > OS (C:) > ProgramData > Microsoft > Windows > スタートメニュー > プログラム > Windows システムツール

あるいは、
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\System Tools
をエクスプローラのアドレスバーにコピペ

私の場合、不具合を見つけたときには desktop.ini と タスクマネージャのショートカットしか無かった。


ショートカット作成とコピー

コントロールパネル

 デスクトップで右クリック ⇒ 新規作成 ⇒ ショートカット

ショートカットの作成 ウィンドウが現れる。
Make_ShortCut

 "項目の場所を入力してください(T):" で control と入力 ⇒ [次へ(N)] クリック

make_control

 "このショートカットの名前を入力してください(T):" で コントロールパネル と入力 ⇒ [完了(F)] クリック

 デスクトップに作成されたショートカットを正しいフォルダにコピー
  (デスクトップのショートカットは削除しておく)


コマンドプロンプト

 同様に "ショートカットの作成" ウィンドウを開く

 "項目の場所を入力してください(T):" に cmd と入力 ⇒ [次へ(N)] クリック

 "このショートカットの名前を入力してください(T):" に コマンドプロンプト と入力 ⇒ [完了(F)] クリック

 デスクトップに作成されたショートカットを正しいフォルダにコピー
  (デスクトップのショートカットは削除しておく)


エクスプローラ

 同様に "ショートカットの作成" ウィンドウを開く

 "項目の場所を入力してください(T):" に explorer と入力 ⇒ [次へ(N)] クリック

 "このショートカットの名前を入力してください(T):" に エクスプローラ と入力 ⇒ [完了(F)] クリック

 デスクトップに作成されたショートカットを正しいフォルダにコピー
  (デスクトップのショートカットは削除しておく)


タスクマネージャー

もし タスクマネージャー が無くて復活したい場合も同様に追加できる。

上と同様に "ショートカットの作成" ウィンドウを開く

"項目の場所を入力してください(T):" に taskmgr と入力 ⇒ [次へ(N)] クリック

"このショートカットの名前を入力してください(T):" に タスクマネージャー と入力 ⇒ [完了(F)] クリック

デスクトップの作成されたショートカットを正しいフォルダにコピー
  (デスクトップのショートカットは削除しておく)


PC

PC を開く
デスクトップにPCのショートカットが無い場合は
 検索ボックスに PC とキー入力 ⇒ 検索結果から PC アプリ をクリック

アドレスバーにある PC のアイコンをドラッグ ⇒ [Ctrl] + [Shift] を押しながらデスクトップにドロップ

デスクトップに作成されたショートカットの名前を PC に変更

PCのショートカットを正しいフォルダにコピー
 (デスクトップのショートカットは削除しておく) 


ファイル名を指定して実行

スタートを右クリック ⇒ ファイル名を指定して実行 を左クリック
 タスクバーにアイコンが現れる。

タスクバーのアイコンを右クリック ⇒ タスクバーにピン留めする
at_TaskBar

タスクバーのアイコンを右クリック ⇒ ファイル名を指定して実行を右クリック ⇒  プロパティ クリック

全般タブ クリック ⇒ 場所: のパスを全選択コピー ( [Ctrl]+[C] )

Place_Property


エクスプローラのアドレスバーに貼り付け ( [Ctrl] + [V] )
 タスクバーのフォルダが開き、"ファイル名を指定して実行"  のショートカットがそこにある。

このフォルダから ファイル名を指定して実行 のショートカットを正しいフォルダにコピー

タスクバーに残っている ファイル名を指定して実行 のアイコンを右クリック ⇒ タスクバーからピン留めを外す クリック


Winsows管理ツール

コントロールパネル ⇒ 表示方法:小さいアイコン

管理ツールで右クリック ⇒ ショートカットの作成(S) クリック

Administrative_Tools


No_ShortCut

[はい(Y)] クリック ⇒ デスクトップにショートカットが作成される

ショートカットの名前を Windows管理ツール に変更 ⇒ 正しいフォルダにコピー
  (デスクトップのショートカットは削除しておく)



以上で無事に修復できた。




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




keywords: Windows10 Windowsシステムツール 修復

リンク集 | ブログ内マップ
関連記事

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

e-Gadget 読者アンケート

2019/09/24
更新 2019/11/06
更新 2021/08/24
更新 2022/10/06

当ブログに来られる方へのアンケートを始めたのが2019年9月。アンケートをしてくれる方が少しずつですが増えています。このアンケートではネット利用に関してお尋ねしています。

ご年齢についても伺っていて、10歳単位でみると50歳台が一番多い結果です。40歳台と60歳台がそれぞれ次のセグメントになっています。そして30歳台以下(0~39歳)までを一括りにしたセグメントが3番目です。

多分ティーンエイジャーでポケコンを愛用してプログラミングを楽しんだ世代が現在の50歳台と思われるので、40歳台が多いのはチョット面白い結果ではないでしょうか?


是非アンケートに答えてみてください。ネットの使い方や世代についてお尋ねしています。

アンケートにはGoogleアカウントが必要ですが、androidスマホを持っていればおそらくお持ちだと思いますし、新しいアカウントは簡単に取れます。ご協力頂ければ嬉しいです。結果は皆さんで共有できます。1人1回しか回答できないようにしました。


こちらからお願い致します。
前の回答を表示 ⇒ 回答結果全体を見られます
回答を編集 ⇒ 前に回答した内容を変更できます





関連記事

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

初めて作る C# プログラム - MyClock

プログラム電卓のためのC#プログラミング
e-Gadget

<トップページへ>


2017/01/31
大きく改訂 2017/02/22
更新 2022/10/04

更新: 最新版 MyClock Ver 1.19.1.3 を公開(ソース付き) 
   ▶ クイックマニュアルにヘルプ表示方法を追記。


初めて作る C# プログラム - MyClock

[2022/10/04 追記]
Visual Studio Community 2019 ver16.11.19 でリビルドしました。scClockも同様にしてリビルドして Ver 3.02にアップデートしました。システム安定性とセキュリティー向上が目的。

[2019/05/03 追記]
開発環境を Visual Studio Community 2019 に切り替えました。これまで作成していた VS Comunity 2015 のソースをそのまま修正無しでビルドできました (VS Community 2017 では修正が必要でした)。VS Community 2019 は起動が非常に速くなり、ビルドも速くなりお勧めです。

無償で入手できる開発環境 Visual Studio Community 2015 の C# を初めて触ってみながら、具体的なプログラムを作ってみます。

プログラミングの習得に効果的なのは、自分が欲しいプログラムを作ること、そして人に説明すること。私の持論です。最初は簡単に作れそうで、さらに機能追加すると自分が欲しいプログラムになるようなのが題材として良いですね。


はじめに

シンプルな時計から始めます。

というのも、10年以上前に、アクティブになっているウィンドウのタイトルバーに常に張り付く小さな時計 scClock を作り、10年以上愛用していました。番外編 - 小さな時計 - scClock をご参照。

ところが最近は、目が疲れてくると小さな時計のフォントの視認に困ることがあります。フォントを大きくするとタイトルバーには収まりそうにないので、半透明で大きなフォントの時計にすれば良いかも知れない...ということで、老眼が始まった世代のための邪魔にならないデジタル時計...というコンセプトでアプリを作ることにしました。


[2022/10/04 追記]
Visual Studio Community 2019 の最新版 ver16.11.19 でリビルド。

[2019/05/03 追記]
開発環境を Visual Studio Community 2019 に変更。Ver 1.19.1.1 で2重起動抑制ができなくなっていたのを修正。

[2019/01/25 追記]
古いPCにインストールした時に .NET Framework 3.5.1 がインストールできないことがあるのを修正、その他、細かいバグ修正

[2018/11/18 追記]
外観を変更した時やカタログ機能で外観を切替える時、時計の外観に反映するのが1秒間隔でした。これを0.2秒間隔に変更したので、実質上リアルタイムで反映するようになりました。Ver 1.19.1.0 以降で対応。

[2017/03/05 追記]
MyClock の外観がカスタマイズできるようになり、アクティブなキャプションバーに貼り付く機能も盛り込んだので、scClock 同一の外観と同一の機能を MClockのカスタマイズで適用できるようになりました。scClock は役割を終えたようです。10年以上ありがとう!

[2017/02/14 追記]
10年以上前に Active Basic (Windows XP) で作った 小さな時計 - scClock を作って常用してきました。今回作ったMyClock のフォントや外観を小さくすることで scClock として作り直し、アクティブなキャプションバーに貼り付く機能を追加しました。これを Win 7 以降 (対象のフレームワークは .NT Framework 3.5) に対応する scClock Ver 3.01 としました。 

小さな時計 - キャプションバーに張り付く時計 (ソース付き)
scClock Ver 3.02



PC保護の警告について

自作プログラムや信頼できる入手先からダウンロードしたプログラムを実行しようとすると、Windows 8 以降ではPC保護の警告がでます。

最近は悪質なマルウェアやインターネットサイトがあるので細心の注意は必要ですが、汚染されていない自信があるクリーンなPCで自分で作ったプログラムでも、ほぼ確実にこの警告がでます。さらにセキュリティーソフトが追いうちをかけて、警告を出します。

対策については、こちらをご覧ください。

自作プログラムがPC保護警告に引っかかる



最新の MyClock

初めてC#で作るプログラムの最新の MyClock は C#学習を反映しています。ここに至る道筋を簡単に記事にします。さらに自分なりのプログラミングTipsも紹介する予定です。

==========

邪魔にならないデジタル時計 (アラーム機能付き)
MyClock Ver 1.19.1.3 

最新版 (ソース付き) Ver 1.19.1.3 のダウンロード
  • アラーム機能があります。
  • 時計の外観をカスタマイズできます。
  • ポータブルアプリです(フォルダにコピーするだけで使え、不要になればフォルダごと削除するだけです)。
  • カタログ機能を追加。時計の外観を登録しておいて一発切替えできます。
動作に必要な最小限のファイル:
  • MyClock.exe
  • Interop.IWshRuntimeLibrary.dll
  • scClock.exe
一応 ReadMe.txt も入っています。

<MyClock>フォルダにソースファイルが入っています。MyClock.sln を実行するとVisual Studio で読み込んで起動します。Visual Studio Community 2015 で作ったものです。

MyClock紹介ページ
MyClock Ver 1.18.4 以降で、[MyClockについて]画面のキャプションバーにある[?]ボタンクリックで、このMyClock紹介ページがブラウザで開くようになっています。


シンプルなものから最新までの道筋

多分最も簡単に作れる時計アプリ

Ver1.00外観 

手始めに、前面表示する半透明でフォントの大きなのデジタル時計を作りました。
タイマーコントロール、フォームのプロパティ設定だけでできます。とは言っても初めてC#で作ったので、主にIDEの使い方やC#が自動生成するコードについて調べてみました。


クライアント領域のマウス操作、プロセスの排他処理

キャプションバーと枠を取り去ったデジタル時計に改造しました。そのためには、クライアント領域のマウス操作が不可欠になります。そこで、C#でマウスのイベントハンドラを使ってみました。

こんな感じになりました。
枠無し黄色半透明フォーム
 

アプリ用のアイコンリソースの使い方も試しました。さらに二重起動禁止にするため、mutex を使ったプロセスの排他処理を C#で試してみました。VC++の感覚で扱えることが分かりました。

[C#プログラミングTIPS] 2重起動禁止のいくつかの方法


キー入力の取得とモーダルダイアログ

[Esc]キーを取得してモーダルダイアログを表示させる処理を作ってみました。

[C#プログラミングTIPS] モーダルダイアログと[OK]での戻り値

アプリの機能としては、こんな感じのフォームでアラームの設定を行います。
アラーム設定画面 

私の Windows 10 環境だと標準のフォントサイズが 9pt になっていますが、そもそも大きな文字の時計を作るコンセプトなので、12pt を基本のフォントサイズにしました。

過去の VC++ でも使ったことの無い DateTimeコントロールを初めて使ってみました。他には、ボタン操作やチェックボックスなどの練習もできました。クリックすると [▶前面] ⇒ [▶最大化] ⇒ [▶前面中央] と3フェーズを循環するボタンを実装。[OK]ボタンは[Enter]キーと連動、[Cancel]ボタンは[Esc]キーと連動させるのは、フォームのプロパテティの設定で実装できることも試しました。


Win32 APIの利用

アラームが発動した時、目立つように点滅させます。そこで、キャプションバーとボーダーフレームを点滅させるWin32 API の利用を試しました(.NET Framework にはウィンドウ点滅の機能が準備されていないようです)。

[C#プログラミングTIPS] フォームを点滅させる Win32 APIの利用

こんな感じで、点滅します。
アラーム発動時に、ウィンドウの最大化やスクリーン中央への移動などのオプションを作りました。

アラーム発動 


ピクチャーボックとテキストボックス、アセンブリ情報の活用

ピクチャーボックスにアイコンを表示し、テキストボックスにクイックマニュアルを表示するのを試しました。

こんな感じのアプリ情報のダイアログを作り、[F1]キーを押して呼び出すようにしました。

ABout_1  

ここでも 標準の9pt よりも大きなフォントで表示しています。

さらに、アプリに埋め込まれるバージョンとかアプリ名などのアセンブリ情報の取得も試みました。
アセンブリ情報を利用は初めてで、ここで表示している「アプリの説明」、「アプリ名 (MyClock)」、「バージョン」、「Copyright表示」は全てアセンブリ情報から取得して表示。バージョンアップ時にアセンブリ情報を変更するだけで良く、フォームの変更は不要です。


外部アプリを起動してみる

外部アプリとして、以前作った scClock (小さな時計) を起動する処理を作ってみました。Win32 APIを使わずに .NET Framework と C# だけで起動しているプロセスの列挙、プロセスの終了、例外処理ができました。

[C#プログラミングTIPS] 外部プログラムを起動する


モードレスダイアログとプロパティグリッド

時計の外観をカスタマイズする機能を追加しました。外観の設定をリアルタイムに反映させるために、モードレスダイアログとプロパティグリッドの組み合わせが良さそうです。

[C#プログラミングTIPS] モードレスダイアログを使う

プロパティグリッドは初めて使ってみましたが、非常に便利なものですね!
プロパティグリッドは、基本的な使い方が分かれば、細かなユーザーインターフェースをコーディングする必要がありません。

[C#プログラミングTIPS] PropertyGrid を使う

今回作った時計は、その外観に "通常の外観"と"アラーム設定時の外観"の2つで1セットです。そこで、プロパティグリッドに表示するプロパティもそれぞれに併せて2つ用意します。2つの外観と2つのプロパティセットを動的に連動させました。

[C#プログラミングTIPS] 別フォームのプロパティにアクセス (set / get) する

さらに、プロパティグリッドの上にある外観変更ボタン (下の図では [通常の外観]ボタン) で2つの外観を強制的に変更し、プロパティグリッドの表示をこれに連動させました。

このように、異なるクラスのフォーム間で互いのフォームの表示を双方向で制御するC#のコーディングが試せました。

通常の外観のカスタマイズは、こんな感じ...
通常 

アラーム設定時の外観のカスタマイズは、こんな感じ...
アラーム設定時 

極端に小さくして scClock のような外観にもできます。
 小さな外観 


読者の方からのコメントでヒントを頂き、MyClock にキャプションバーに常に貼り付く機能を選べるようにしました。
外観の設定の画面に追加したボタンを押すことで、貼り付く / 貼り付かないを選択できます。

通常の外観をこんな感じにして、キャプションバーに貼り付いたところ...
貼り付き-通常


アラーム設定時の外観は、こんな感じにしてみます。
貼り付き-アラーム設定時

作ってみたら、良い機能だと気がつきました( ^^;


アプリケーション構成ファイル (*.exe.config) の思い込み

当初からレジストリや特殊フォルダを使わずに、インストールフォルダの中だけで完結するポータブルアプリを作っているつもりでした。アプリーション構成ファイルを使うと楽なので ビルドして得られる MyClock.exe.config をインストールフォルダに置いておけばポータブルアプリになると思い込んでいましたが、大きな勘違いでした。MyClock.exe.config は初期設定に使われるだけで、アプリケションの設定内容は AppData 配下のフォルダに作られていました。それもかなりの量のファイルやフォルダが作られていました。

さらに、アプリケーション構成ファイルは1つ前のバージョンの設定はそのまま引き継げますが、それ以前のバージョンで保存された設定情報を読み込めないという問題があることも知りました。

そこで、昔ながらの INIファイルにアプリの設定情報を保存して使うように変更しました。XMLファイルを設定ファイルとして使う方法もありますが、コーディングが楽な INIファイルを採用しました。Win32 API を呼び出してコーディングしますが、他の Win32 APIと異なり、C#用のラッパーの作成に少し悩みました。int 変数の読み書きは使わず、string (文字列) 変数のみの読み書きとしました。

[C#プログラミングTIPS] INIファイルを使う


ArrayList とトラックバー(スライダー)

時計の外観のプロパティを無制限に複数登録し、そこから任意のプロパティを呼び出す機能(カタログ機能)を追加するため、ArrayList と トラックバーを使ってみました。

ArrayListの良いところは、2次元配列と異なり、動的な要素の追加と削除が簡単にできる点にあります。非常に多くの外観のプロパティをArrayListに追加した場合でも、そのプロパティの個数の影響を受けずに選択しやすいインターフェースとしてトラックバーはメリットがあると思いました。登録数が増えればトラックバーの刻みを細かくするだけで良いからです。リストボックスやコンボボックスの利用も頭をよぎりましたが、これはVC++で以前使ったことがあり、登録保存するプロパティに何らかの名前(文字列)が与えられることが利用の前提となるのは使う時に煩わしいと感じたので、コンボボックスは使わないことにしました。

[C#プログラミングTIPS] ArrayListに配列を格納して使う

列挙したものを選択するコントロールとしては、
  • リストボックス
  • コンボボックス
  • イメージリスト
  • ツリービュー
  • ラジオボタン
  • ボタンを並べる
などが考えられますが、文字列を使わない(ユーザーがいちいち外観に名前を付ける手間が不要)、無制限に追加削除が簡単にできて決まった領域にコントロールを格納できる、といった要件を考え、さらにコーディングが楽そうだという理由から、最終的にトラックバー (スライダー)を使ってみることにしました。

そして、プロパティの登録作業用のクラスを作って、インデックスプロパティ、操作メンバなどをクラスにキャプシュレートして C#らしいコードに挑戦してみました。C#使いの方からみればダメダメなコードだと思いますが、約1ヶ月前にC#を始めたころから見れば進歩はしていると思います。ダメさ加減も含めてソースを公開しているのは、気を引き締めるためもあります。

さて出来上がったカタログ画面ですが、こんな感じでカスタマイズした外観を[追加]します。
カタログ機能

操作するコントロールが少ないですが、それだけに柔軟です。登録数が多くなってトラックバーの刻みが細かくなりすぎる時を想定して、フォームを横に広げられるようにしました。

時計の実際の外観、[時計のカスタマイズ]画面の表示、そして[時計のカタログ]画面の3つの異なるフォームの表示内容は、常に同期して変化するようにしました。

外観のプロパティを6個登録して、そこから INDEX 1/6 を通常の外観に適用した例...
カタログ機能2

時計のカスタマイズ(外観の設定)画面はプロパティグリッドを使って、リアルタイムに外観をカスタマイズできるよう作っていて、さらにカタログ機能も同期しているため、トラックバーを動かすと、実際に時刻を刻んでいる時計の外観が動的に変更されます。

こんな小さな外観を登録しておき、アラーム設定時の外観に適用したところ...
カタログ機能3

こんな小さな外観だと、色々なフォームが上に被さって行方不明になりそうなので、これらのフォームは時計に重ならないように「時計のカスタマイズ」ダイアログと「時計のカタログ」ダイアログを自動的に(タイマーを使って定期的に)再配置するようにしました。

なお、異なる3つのフォームの表示内容を同期させるために必要な変数を Public static にして、全てのフォームからアクセスするようにしました(C#としてはお行儀が悪いとの恐れがあります)。


特殊フォルダへのアクセスと実行中に自分自身のショートカットを作成する

これまで自分で使う際には、ショートカットファイル MyClock.lnk を作って、それをスタートアップフォルダへコピーしてログイン時に自動起動するようにしていました。そこでこれをアプリから自動的に設定できるようにしました。具体的には、実行中の自分自身のショートカット作成とスタートアップフォルダへのコピーを行う「ログイン時に起動する」機能を追加しました。タスクマネージャーのスタートアップで確認できます。

スタートアップ設定 

[ログイン時に MyClock を起動する] にチェックを入れるとその場でスタートアップフォルダにショートカットを作成し、チェックを外すとその場でショートカットを削除します。

[C#プログラミングTIPS] スタートアップフォルダに実行中のアプリのショートカットを作る

初めてC#を使いだして1ヶ月程度の間に機能を追加してきたアプリですが、かなり満足できる仕上がりになってきたと思います。肝心のC#の学習はまだ始まったばかりで、まだまだ分からないことが多くヘボなソースだと思います。

以下では、最初から順にソースを見直して学習したことの整理と定着を図りたいと考えています。



C#学習の履歴を以下にまとめます。

フォームを作り時刻を表示させる (Ver 0.10)

仕 様
  • フォントが大きい
  • 半透明で常に前面表示
試したこと
  • Visual Studio IDE の使い方と基本的な機能
 MyClock Ver 0.10 のページ



クライアント領域のマウス操作でアプリの終了と移動を行う (Ver 1.00)

更新履歴

 ・タイトルバーの無い小さな(邪魔にならない)外観に変更
 ・クライアント領域を左ダブルクリックで終了可能にする
 ・クライアント領域をマウスで掴んで移動可能にする
 ・マウス右クリックで最小化できるようにする

試したこと
  • イベントハンドラの作成と フォームデザイナーの挙動

 MyClock Ver 1.00 のページ



モーダルダイアログで設定した各種変数を親ウィンドウに反映させる

更新履歴

 ・アラーム機能を追加
  - [Esc]キーでアラーム設定
  - アラーム発動時マウスを左クリックで元に戻る

 MyClock Ver 1.10 のページ



MyClock Ver 1.11 にアップデート

更新履歴

 ・アラーム設置柄画面を時計の周りに重ならずに表示
 ・アラーム設定画面で、現在時刻をがが取得可能にした
 ・最小化からのアラーム発動では半透明最大化させる
 ・最前面に表示しないことがあったのを修正
 ・Alarm.exe 単独起動のエラーの場合メッセージを表示して終了。

 MyClock Ver 1.11 のページ


MyClock Ver 1.12 にアップデート

更新履歴

 ・以下を保存して再起動時に復元するようにした
  - アラーム設定時刻
  - アラーム解除設定状態
  - 時計の表示位置


 MyClock Ver 1.12 のページ


MyClock Ver 1.13 にアップデート

更新履歴

 ・終了時に補村して再起動時に復元する項目を追加
  - 終了時の時計のサイズ(ノーマル/最小化)
 
 MyClock Ver 1.13 のページ


MyClock Ver 1.14 にアップデート

更新履歴
 ・時計の表示状態ごとにアラーム発動時の外観を選択できます。
  - 時計の表示状態:前面表示 / 最小化
  - アラーム発動時の外観:前面表示 / 最大化
 ・アラーム発動時の外観設定を終了時に保存し再起動時に復元する。
 ・MyClock.exe から呼び出されず単独起動の場合の例外処理を追加。

 MyClock Ver 1.14 のページ


MyClock Ver 1.15 にアップデート

更新履歴

  2017/02/04 ・アラーム設定に「▶前面中央」を追加した。
        ・起動時に「MyClock の使い方」の表示ができるようにした。
         - 起動時の表示をするかどうかを設定できる




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





keywords: プログラム関数電卓、Windowsプログラミング

リンク集 | ブログ内マップ
関連記事

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

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

やす (Krtyski)

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


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

プログラム電卓を実際に使って気づいたこと、自作プログラム、電卓での Casio Basic, C.Basic そして Casio Python プログラミングについて書いています。

なお管理人はカシオ計算機の関係者ではありません。いつでもどこでもプログラミングができるプログラム電卓が好きな1ユーザーです。


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

リンク
月別アーカイブ
Sitemap

全ての記事を表示する

ブロとも申請フォーム

この人とブロともになる

QRコード
QR