Casio Pyhton - 目次

Python Casio Python
 Casioグラフ関数電卓の Python を使ってみる
     
- 目 次


初版:2020/06/13
更新:2022/02/21


コードを書いて実際に動かしてみる、さらにコードを書いて動かしてみる、これの繰り返しで実際に手を動かして学習をすすめるのがプログラミング学習の近道です。当ブログでは、2つの Casio Python 入門コースを用意します。

なおカシオのグラフ関数電卓の Python モード (Casio Python) は、MicroPython Ver 1.94 のライセンス下で実装されています。そこで MicroPython 自体の仕様やカシオが実装時の導入した独自仕様が、パソコンで動作する Python (uPython) と異なっている部分を調べて、読者と共有することも連載の目的です。


 目 次

ある程度プログラミングの経験がある人向けの連載と、過去のプログラミング経験が殆ど無い人向けの2つの連載を進めます。
これらの連載では、以下のモデルとOSバージョンを前提にします。
Casio fx-CG50 OS3.40 以降 (日本国内サポートあり)  ⇒ fx-CG50 の概要
Casio fx-9750GIII OS3.40 以降 (日本国内では非売品)  ⇒ fx-9750GIII の概要
Casio fx-9860GIII OS3.40 以降 (日本国内では非売品)  ⇒ fx-9860GIII の概要

< 1 > プログラミング経験者のための Casio Python (←クリック)
Python を基礎から勉強するのではなく、パソコンで使う高級言語や Casio Basic でのプログラミング経験がある人 (管理人もその部類) がとりあえず Casio Python でコードを書いて、納得しながら進める連載。
その実態は、管理人の学習プロセスに沿って色々なプログラムを作ってゆく過程を紹介するもの。

< 2 > Casio Python 入門 (←クリック)
プログラミングをあまり知らない人が Python を基礎から学びながら Casio Python を使えるようになるための連載。基礎と重要なポイントを1歩づつ抑えながら、サンプルスクリプトを書いてから動作確認を行うようにして進めます。

< 3 > Casio Python のリファレンス (←クリック)
連載記事とサンプルスクリプトを作成しながら判ったことをまとめたものです。Casio Python 特有の仕様も含んでいます。Casio Python のオブジェクト一覧、ステートメント、メソッド(関数)、特有な動作環境、そして e-Gadget オリジナルのユーザーモジュールも紹介します。

< 4 > コラム
Casio Python についてのトピックスの紹介。

< 5 >
Python の無料入門書
Python そのものを無料で基本から学べる入門書を紹介




プログラミング経験者のための Casio Python 

0. Casio Python のポテンシャル
Casio Python のグラフィックス描画は Casio Basic より100倍以上速い


1.
はじめに: 電卓で作る初めてのスクリプト
Pythonモード (Casio Python) でのスクリプト作成/編集の概要
  1.1 Casio Python での初めてのスクリプト
   1.1.1 fx-CG50 の準備
   1.1.2 Casio Python の起動
   1.1.3 スクリプトファイルの作成
   1.1.4 スクリプトの作成
   1.1.5 スクリプトの実行
  1.2 シェル画面
  1.3 スクリプト作成と編集の2つの方法
    Note: Python スクリプトファイルの正体
    Note: VIsual Studio Code について


2. Casio Python とは?:MicroPython と CPython
Casio Python は、CPython のサブセット版である microPython をカスタマイズしたもの
  2.1 Casio Python の素性
   2.1.1 MicroPython 1.9.4
    Note: Casio Python へのライセンス
   2.1.2 CPython 3.5.4
  2.2 Casio Python に組み込まれているオプジェクト名の一覧
    Note: CGモデルとFXモデルでの出力の違い
  2.3 Casio Python の学習方法


3. Casio Python の入出力:プログラムのデザイン
Casio Python (OS3.4/3.5) は入出力機能がとても限定的である
  3.1 入力 - input()
    Note: Casio Python の制限
  3.2 出力 - print() とグラフィックス出力関数
    Note: シェル画面とグラフィックス画面の切替
  3.3 Casio Pyhton で作るプログラム


4. Casio Python への移植:モンテカルロ法 (1)
Casio Python でスクリプトを書くための最低限の知識を紹介
    Note: モンテカルロ法による円周率の計算方法
  4.1 コメントの書き方
    Python公式: Comments
    Note: PEP 8
    Python公式: Docummentation Strings (Docstrings)
  4.2 モジュールの呼び出し - import
  4.3 メニュー機能の作成
    Reference: ⇒ input( )
    Note: Pythonでの文字列 - ' ' と " "
    Note: int( )
    Note: if 文
    Note: Python のデータ型
    Note: str( )
  4.4 circle() 関数の作成
    Note: continue
    Reference: ⇒ range( )
  4.5 グラフィックス出力
    Note: Casio Python 組み込み関数を調べる
   4.5.1 自作関数 circle() で円を描画
    Note: 文の句切り文字 - ;
   4.5.2 draw_string() 関数で文字列を出力
    Note: while 文
   4.5.3 while 文により繰り返し
   4.5.4 random() 関数により正方形内の座標(x, y)を取得
   4.5.5 set_pixel() 関数で (x, y) に点を描画
   4.5.6 点の座標から円周率を計算
    Note: モンテカルロ法による円周率の計算方法 (再掲)
    Note: 累乗演算子 - **
    Note: 累算代入演算 (+=, -=, *=, /=, %=)
    Note: 四捨五入 - round( )
   4.5.7 draw_string() 関数で回数と円周率を表示
   4.5.8 draw_string() 関数でシミュレーション終了の表示


5. 関数の作成と活用:grp_color() 関数の作成
Casio Python での関数の作り方と使い方の基本を紹介
  5.1 関数の引数について
  5.2 関数内の変数の有効範囲 - 変数のスコープ
  5.3 circle() 関数の拡張
  5.4 色指定関数を追加
   5.4.1 RGBによる色指定
   5.4.2 タプル型
   5.4.3 色指定方法の拡張
   5.4.4 グラフィック画面での色指定関数 grp_color() 関数の作成
    Note: type( )
    Note: リストの定義
    Note: タプルの定義
    Note: Python の比較演算子
    Note: 帰属検査の in
  5.5 circle() 関数拡張の書き換え
  5.6 モンテカルロ法(2) - monteca2.py


6. グラフィックス出力関数の追加:line() とユーザーモジュールの作成
ユーザーモジュールの作り方と使い方を紹介
  6.1 line() 関数の作成
  6.2 グラフィックスユーザーモジュールの作成
  6.3 line() 関数の動作確認 - ckLine.py
  6.4 line() 関数の動作確認 - ckLine2.py
    Note: 除算の余りを求める - %


7. テキスト出力関数の追加:locate() をユーザーモジュールに追加
Casio Python では必須の locate( )関数の作成と使い方を紹介
  7.1 locate() 関数の作成
   7.1.1 フォントピッチ dx, dy の設定
   7.1.2 column から x を、row から y を算出
   7.1.3 フォントサイズ指定の処理
   7.1.4 locate() の完成 
  7.2 locate() をユーザーモジュールに追加
  7.3 locate() の動作確認 - ckLocate.py
  7.4 モンカルロ法(2) - monteca3.py


8. シェル画面入力の工夫:高速素因数分解(1)
Casio Basic から Casio Python へ強引に移植する例
  8.1 高速素因数分解プログラム - FactorG のざっくりした分析
  8.2 入力と入力値のチェック
    エラーを検知し制御を取り戻す - Try / except
  8.3 変数の初期化
  8.4 素数が素因数かどうかをチェック
    Note: Python の単文と複文
  8.5 "エラストテレスの篩い" で素因数の探索
  8.6 ckpwr() 関数の作成
  8.7 disp() 関数の作成 


9. Python らしい反復処理:高速素因数分解(2)
オプジェクト指向言語 Python ならではの for の使い方を紹介
  9.1 frac() 関数をユーザーモジュール (u.py) に追加
  9.2 不要な処理を削除
  9.3 disp() 関数のスリム化
    Note: range( ) の書式
  9.4 素数が素因数かどうかをチェックする部分のスリム化
  9.5 素因数を探索する残りの部分のスリム化
  9.6 スリム化したスクリプト - FactorG2.py
    Note: Casio Python スクリプトファイルのサイズ制限


10. 大きな数の計算:高速素因数分解(3)
Casio Python では15桁の精度が得られることを利用する事例を紹介
  10.1 変更箇所の洗い出し
  10.2 増加する素因数に合わせて表示桁数を拡張する - disp() の変更
  10.3 入力桁数の制限を拡張し、それに合わせてエラー表示を変更する
  10.4 素因数探索回数の表示を追加する
  10.5 素因数が10桁を超えるときの表示の変更 - disp() の変更


11. 関数呼出オーバーヘッド:高速素因数分解(4)
Casio Python は関数呼出が比較的速い - 関数を無くせばさらに高速化可能
  11.1 関数呼出あり (ver 3) となし (ver 4) の実行速度の違い
  11.2 Casio Python の関数呼出オーバーヘッド


12. 要素数の多いリスト:高速素因数分解(5)
Casio Python は巨大リストを処理するスクリプト実行時にスタックサイズエラーが発生する
⇒ CPythonではジェネレータで対処。本事例では処理速度優先のためジェネレータ使わず...
  12.1 増分リストを拡張する
  12.2 要素数480個の探索数増分リスト
  12.3 探索数を拡大して15桁対応高速素因数分解のスクリプト
  12.4 探索数拡大による高速化
  12.5 増分リストをさらに拡張する


13. 10進数除算の出力と精度:高速素因数分解(7)
Casio Python 内部演算精度15桁が原因で、割り切れる整数の除算が浮動小数点になることがある
  13.1 Casio Python での除算結果のデータ型
  13.2 Casio Python での関数計算結果のデータ型
  13.3 Casio Python での除算計算の精度
    Note: Windows版 Python のインストール
    Note: 浮動小数点演算 - その問題と制限 (Python 公式サイト) 参照
  13.4 0 および負の整数入力の処理
  13.5 入力ルーチンの修正
   13.5.1 入力委が小数点以下 0 の小数の場合に処理を追加 
   13.5.2 入力値が負の数値の場合の処理
   13.5.3 入力が 0 の時の処理
  13.6 完成した FactorG7.py の動作確認


14. CGモデルとFXモデルのPythonモードの違い
CGモデルとFXモデルの判定方法とその関数化を紹介
  14.1 CGモデルからFXモデルへのスクリプトの移植
   14.1.1 CGモデルからFXモデルへのスクリプト移植のポイント
   14.1.2 CGモデルとFXモデルの判定方法
  14.2 FXモデルのPythonモードの制限 - バッファサイズ
   14.2.1 編集できるスクリプトファイルの行数制限
   14.2.2 print() 出力のスタック・バッファサイズ
   14.2.3 Shell 画面出力のスタック・バッファサイズ
  14.3 Casio Python自体の機能の違い
   14.3.1 CGモデル OS3.40 と OS3.50 の違い
   14.3.2 CGモデル OS3.50 と FXモデル OS3.40 の違い


15. RGB値による色設定
fx-CG50 のカラー液晶は16bitカラーであることを理解した上で、RGB値で色指定する方法を紹介
⇒ ピクセルの色指定と色読取りの実験を CGモデルとFXモデルで実施
  15.1 RGB値の色を確認するプログラム
  15.2 fx-CG50 の高精細カラー液晶 - 実は 16bit カラー
  15.3 モノクロ液晶モデルでのRGB値による色設定
  15.4 RGB値でのピクセル色設定と読取りの実験 - CGモデルとFXモデル


16. circle() 関数のFXモデルへの拡張
画面の画素数が異なる CGモデルとFXモデルの両方に対応したスクリプト作成を紹介
  16.1 CGモデルとFXモデルの場合分け
  16.2 circle() 関数を使ってみる



17. shell 画面とグラフィック画面の活用:コラッツ問題
出力先としてグラフィックス画面とシェル画面の両方を活用する事例を紹介
  17.1 コラッツ問題 (Collatz Problem) とは?
  17.2 コラッツ数列の計算
  17.3 出力の工夫ポイント
   17.3.1 input() での入力
   17.3.2 フォントサイズを変えて添え字の描画
   17.3.3 リアルタイムに変わる数値の表示
   17.3.4 グラフの描画
   17.3.5 数列の最大値を求めて表示
   17.3.6 shell 画面でのスクロール出力
  17.4 コラッツ問題で遊んでみる

18. Casio Pyhton - turtle / matplotl モジュール 
Casio Pyhton用 turtle / matplot モジュールの入手

[準備中]





Casio Python 入門

(以下予定)

00. はじめに

01. Casio Python に触れる(1)

02. Casio Python に触れる(2)

03. 変数・代入とオブジェクト

04. Python の基本

05. 条件分岐と繰り返し

06. 組込型とオブジェクト

07. ユーザ定義関数
  
08. クラスの基本







[準備中]





リファレンス

Casio Python - オプジェクト一覧 (← をクリック)
Casio Python に実装されているものを網羅しています。
  • オブジェクト一覧には、個別に作成したリファレンスへのリンクがあります。
  • 個別のリファレンスには、Python 公式サイトでの解説へのリンクを掲載しています。
  • 個別のリファレンスには、Casio Python 独自の項目を優先して記述します。
  • 一旦作成したものは、随時追記。修正します。


e-Gadgetで作成したユーザーモジュール - オブジェクト一覧 (↓下記)
e-Gadget で作成したユーザーモジュールに含まれているもの

最新バージョン: ver 1.5 <ダウンロード>
サポートモデル / OS:
  ・CGモデル - fx-CG50 / OS3.40以降
  ・FXモデル - fx-9750GIII
/ OS3.40以降
  ・FXモデル - fx-9860GIII
/ OS3.40以降

ファイル名: u.py / ufx.py
  全サポートモデルに対応 - CGモデル/FXモデルの自動判定機能あり
  ・ufx.py は FXモデルで開くために、u.py から一部コメントを削除して150行以下にしたもの
実装オブジェクト
  isCG(): CGモデルかFXモデルかを判定
  grp_color(): グラフィック描画関数の様々な色設定をタプル型に変換
  circle(): グラフィックス画面に円を描画
  line(): グラフィック画面に線分を描画
  locate(): グラフィック画面にテキストを出力
  frac(): 浮動小数点型数値の小数部を取得





コラム


 Casio Python - Casio Education で e-Gadgetのモンテカルロ法が紹介







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


 


keywords: fx-CG50Pythonfx-9750GIIIfx-9860GIIIプログラム関数電卓

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

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

Casio Python - Casio Education で e-Gadgetのモンテカルロ法が紹介

Python Casio Python - コラム
 Casioグラフ関数電卓の Python を使ってみる
     - Casio Education US で 当ブログオリジナルの montec31.py と u.py が紹介された
目次

初版:2022/01/03


Casio Education US は、カシオアメリカで作成してい電卓使いこなしのウェブセミナー (Webinar) で カシオ電卓の使いこなし動画が多くアップロードされています。これらの中で、当ブログ管理人が作成したプログラムが紹介されていました。

以下の動画を眺めていました;

Casio Ecuation Webinar: Python Live!




この動画を見ていたら、管理人が作成したスクリプトファイル名と同じ名前がでてきました。

Montecarlo_webinar_1

ファイルリストに montec31.py (モンテカルロ法で円周率を求めるもの) と e-Gadget製ユーザーモジュール u.py が有りました。これをみた時、「アメリカ人も同じファイル名をつける人がいるものだ...」と思いました。

この動画では、最初はコラッツ問題を Casio Python でリアルタイムコーディングして動作させています。
そういえば、当ブログでもコラッツ問題のPythonスクリプトを紹介しています。Casio Python の題材の取り上げ方、目の付け所まで同じなアメリカ人がいるものだなぁ、と思いながら引き続き見ていました。

そしていよいよ montec31.py の説明に進んできました;

Montecarlo_webinar_2

このプレゼンター (メインで話をしている人) が「これは自分で作ったものではなくて、YouTubeから拝借してきた great program です。」と言ってスクリプト画面を開きました;

Montecarlo_webinar_3

ナント、by Krtyski / e-Gadget と表示されているのを見て、驚きました!
管理人が作ったプログラムコードではありませんか!

ここで、思い出しました!
そういえば、動作画面の動画をYoutubeにアップロードしていて、ソースコードに興味があるから入手できないか?とコメントがあったのです。その時の人の名前が、この動画のプレゼンターの名前と同じだったことも確認できました。
そうか、あのときの人が今しゃべっているんだな...と。

その時は、ダウンロード用の html は日本語表記だけどGoogle翻訳すれば意味はわかるし、ソースは全部英語表記なので問題ないと思うと書き添えて、以下のリンクを連絡しました。

モンテカルロ法 Ver 3.1 スクリプトのダウンロード
fx-CG50 (高精細カラー液晶モデル) か fx-9750GIII / fx-9860GIII (耐解像度モノクロ液晶モデル) かを自動判定するので、どのモデルでも正常動作します。

管理人が作成したモンテカルロ法の スクリプトを使って、ユーザーモジュール u.py の紹介、CGモデルとFXモデルを判定する関数、カラー設定する関数、円を描く関数の紹介、そしてやユーザーモジュール u.py の簡単な説明と、その使い方、YoutTubeなどで入手したスクリプトの導入方法の説明をしています。



ところで、このyouTube動画では fx-CG50 のエミュレータの画面がメインで使われていますが、グラフィック画面の更新が全画面正しく行われないようです。実際の動作は全画面更新されますので、エミュレータの不具合かも知れません。動画内でも言っていました。
実際には、上記からダウンロードして実際に Python モードで動かしてみてください。



最後に、この動画では、e-Gadget という名前のグループ (英語では company、会社じゃなくて仲間という意味合い) の人達が作ったプログラムだと言っていますが、実際は管理人が1人で作ったのですけどね~


登録者数 6450人のうち せいぜい 1140回程度の視聴回数ですが、チョット嬉しいです!




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


 


keywords: fx-CG50Pythonfx-9750GIIIfx-9860GIIIプログラム関数電卓

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

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

Casio Pyhton - turtle / matplotl モジュール

Python Casio Python
 Casioグラフ関数電卓の Python を使ってみる
     - Casio Python 用 turtle / matplot モジュールの入手
目次

初版:2022/01/03


Casio Python 用に turtle モジュールと matplotl モジュールが CASIO USA から公開されました。これらモジュールを使ってみたいと思いますが、先ずは入手方法を紹介します。


CasioEducation US の YouTube
CasioEducation US の YouTube にアクセス

Casio_Turtle

この画面の下にある CasioEducation US のコメントで "もっと見る"  をクリック。

Casio_Turtle_2

MatPlot libraryTurtle のURLをクリックすると、それぞれで Dropbox が開くので、そこから matplotl.pyturtle.py をそれぞれダウンロードする。


Matplotl モジュール

matplot


Turtle モジュール

turtle


ダウンロードしたモジュールのインストール

Pythonモードが搭載されている電卓 (fx-CG50) をPCと接続し、py ファイルが格納されているフォルダにダウンロードした matplot.pyturtle.py をコピーします。

これで、MatPlot モジュールturtle モジュールが使えるようになります。





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


 


keywords: fx-CG50Pythonfx-9750GIIIfx-9860GIIIプログラム関数電卓

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

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

Python の無料入門書

Python Casio Python
 Casioグラフ関数電卓の Python を使ってみる
     - Python の無料入門書
目次

初版:2021/10/21


Casio Python は、一般に使われている Python の機能限定版であり、さらに細かい仕様が変更されている部分もあります。しかし基本的な部分は共通分がかなり多いので、Python 初学者には一般のPythonの入門書が役に立ちます。

そこでこの記事では 一般のPython入門書の中で、無料で公開されていて管理人が良いだろうと思ったものを紹介します。


Python入門 (ネット記事)
ITmedia Inc. が公開しているもの。プログラミング経験があればとても判りやすく、ある程度深いレベルでの解説は役立ちます。
Python入門

※ 管理人はこれで勉強しました。



京都大学 プログラミング演習 Python 2020
京都大学が全学共通科目として実施されるプログラミング演習 (Python) の教科書として作成されたもの。Pythonという言語について教えることよりも、実際に初学者が Python でプログラムがかけるようになることを優先して書かれたものです。無料公開されています。

京都大学では、プログラム初学者がつまずきやすいのは何処に有るのか、などの初学者向けのプログラミング教育に関する研究内容や結果を一般にも公開していて、管理人は以前から着目していました。そして今回の無料の入門書でも、初学者の躓きに配慮したものだと明記されています。最初から読み進めてゆけばスムーズに理解が深まると思います。
京都大学 プログラミング演習 Python レポジトリ
  本文とコラムがそれぞれ別のpdfファイルにまとめられています。

※ 初学者にお勧めです。



今後お勧めが見つかれば、追記してゆきます。



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


 


keywords: fx-CG50Pythonfx-9750GIIIfx-9860GIIIプログラム関数電卓

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

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

Casio Python - ユーザー関数 frac()

Python Casio Python
 Casioグラフ関数電卓の Python を使ってみる
     - リファレンス 
目次
frac()

ユーザーモジュール u.py に含まれる関数 u.py ver 1.5 ダウンロード

初版:2021/06/09

[対応モデル] - fx-CG50 OS3.20 以降、fx-9750GIII / fx-9860GIII OS3.21 以降

浮動小数点型数値から整数部を引いた値に変換します。
なお、内蔵モジュール (builtinモジュール) には、浮動小数点から整数部のみを返す int() 関数はありますが、小数部を返す関数がありません。


書 式frac( )

引 数浮動小数点値

返り値:引数から整数部を減算した値
      frac(12.345)0.345 を返します。


関数定義:

def float(x):
 return x - int(x): 





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


 


keywords: fx-CG50Pythonfx-9750GIIIfx-9860GIIIプログラム関数電卓

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

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

Casio Python のポテンシャル

Python Casio Python
 Casioグラフ関数電卓の Python を使ってみる
     - Casio Python のポテンシャル
目次


初版:2020/06/07
更新:2020/06/29
更新:2020/11/03
更新:2021/03/25

 次の記事 - 1. はじめに:電卓で作る初めてのスクリプト



カシオ・グラフ関数電卓にある Pythonモード - Casio Python

[2020/11/03 更新]
カシオグラフ関数電卓に Pythonモード <パイソン・モード> が搭載されるようになり、casioplot モジュールが追加されたので、それで遊んでみようと思います。Casio Basic やPCでのプログラミング経験があれば、Casio Python は意外に敷居が低いかも知れません。

管理人はネットでチョコチョコっと調べながら、結構使えています。そこで、 プログラミング経験はあるが Python 初心者の人向けに Casio Python のサンプルプログラム作成の連載をしばらくやってみようと思います。Casio Basic プログラムを Casio Python へ移植することからスタートし、Python らしいスクリプトの書き方の紹介へ進んでゆく予定です。併せて、Casio Python のリファレンス情報、特に Casio Python 特有の仕様があれば、それを公開してゆこうと思います。

本連載の全体像は 目 次 をご覧ください。

さて、Casio Python の連載は、管理人がそのポテンシャルの高さに驚いたことが全ての始まりなので、今回はそのあたりを紹介します。
==== 2020/11/03 更新ここまで ====


0. Casio Python のポテンシャル

Python の準備

Casio Python 搭載モデルの準備
Casio Python
搭載電卓を入手して、必要に応じてOSのアップデートをします。
現時点では casioplotモジュールが追加された fx-CG50 OS3.40 以降を強くお勧めします。

ちなみに、Casio Python が搭載されているのは、以下のモデルです (2020/06/07 現在);
fx-CG50, OS3.20 以降
fx-9750GIII, OS3.21 以降 (北米限定発売モデル)
fx-9860GIII, OS3.21 以降 (ヨーロッパ限定発売モデル)
GRAPH 90+E, OS3.20 以降/ GRAPH 35+EII, OS3.21 以降 (フランス専用モデル)
 それぞれが fx-CG50fx-9860GIII と同じ

[2020/10/22 追記]
Pythonモードで実用的なプログラムにするにはグラフィックモジュール casioplot が不可欠です。casioplot は OSアップデートで追加するしかありませんが、それが可能なのは下記のモデルとOSバージョンです (2020/10/15 現在)
 fx-CG50, OS3.40以降     このモデルの概要 
fx-9750GIII, OS3.40以降    このモデルの概要 
fx-9860GIII, OS3.40以降    このモデルの概要 
 GRAPH 90+E, OS3.40以降
 GRAPH 35+EII, OS3.30以降

fx-CG50 のOSは、2020/10/15 時点で OS3.50 にアップデート可能です。OSアップデートは、それぞれのモデルが発売されている地域のカシオサイトからアップデートファイル と アップデートされたマニュアルが入手できます。具体的なアップデートサイトについては上記の "このモデルの概要" ページで紹介しています。

Pythonモードでは、casioplotモジュールを使わないと、思うような出力ができる実用プログラムになりません。本連載は主に fx-CG50 OS3.40以降を前提にして進めてゆくつもりです。但し、モノクロ液晶搭載モデル fx-9750GIII や fx-9860GIII の Pythonモードに casioplot を追加するOSアップデートファイルが 2020/10/15 に公開されたので、これらをアップデートした Casio Python についても紹介する予定です (目次参照)。

 fx-CG50, OS3.40以降: 日本語マニュアルがあり国内どこでも入手できます。
 fx-9750GIII, OS3.40以降: 最安値のモデルです。国内でもAmazon USAで購入可で安価(英文マニュアル)。
fx-9860GIII, OS3.40以降: ヨーロッパ専用モデル。ほぼ同じ機能の fx-9750GIII をお勧めする。

モノクロ液晶搭載モデルのうち、現状最も安価に入週できる fx-9750GIII も無視できないとことがあります。これらモデルの Pythonモードはメモリの制限が強く、使い勝手が fx-CG50 よりも悪いのは残念です。

さて、Pythonモードのアップデートにより新機能や新モジュールが追加された場合は、随時 対応することにします。


Python スクリプト保存フォルダの作成
工場出荷状態では、ストレージメモリのルートにスクリプトファイルが保存されるようになっています。

これから多くのスクリプトファイルを作ってゆくので、ストレージメモリ直下に専用フォルダ、例えば @Python フォルダを作ると良いと思います。電卓内に新たなフォルダを作るには、PCとリンクしてからエクスプローラで電卓の内部を表示して、そこでフォルダを作ります。もし C.Basic を既にお使いの場合は、C.Basicプログラム専用フォルダを作り、そこへ移動しておくことも合わせてお勧めします。これで Python スクリプトと C.Basicプログラムが混在することを防げます。


Python スクリプトファイルの正体
スクリプトファイルは、アスキー文字で書かれたテキストファイルです。Python の構造制御に不可欠なインデントは半角スペースです。電卓上でスクリプトを書く場合、自動インデント機能によりスペース2個が付加されます。また、改行は Windows標準の CR LF (0x0d 0x0a)になっています。

PCに転送すれば、テキストエディタを用いて、スクリプトの確認や編集ができます。PCで編集する場合は、アスキーコード以外を入力しないように留意しましょう。



Casio Python とは? [2020/06/09 の夜に大幅改訂]

Casio Python は、カシオグラフ関数電卓にある Pythonモードを指します。ある程度の関数があらかじめビルトインされていますが、追加ビルトインするモジュールはカシオから提供されていません。自分で作った関数をモジュールとして使うことはできます。Casio Basic では自分で関数を作って使うことはできないので、その分 Casio Pythonは使い勝手が良いと言えます。

Pythonモードが公開された当初は、mathモジュールとrandimモジュールが追加された状態でした。その後 casioplotモジュールが追加されて、ようやくグラフィック描画が可能になりました (fx-CG50, fx-9750GIII, fx-9860GIII)。但し、ピクセル単位でドットを描画すること、ピクセルの色を得ること、テキスト文字を表示することのみができる程度で、Casio Basic のようにグラフを自在に描く機能はまだ公開されていません。今後カシオからさらに新しいモジュールが提供されることを期待しています。汎用的に使える自作関数を複数まとめて1つのモジュールにして、それを使うことも紹介してゆきます。

ところで、Casio Basic で書いたものはプログラムと言い、そのファイルをプログラムファイルと言っています。一方、Python については、取扱説明書の表現によれば、スクリプトを書いて、スクリプトファイルに保存する、と言っているので、本連載でもこの表現を使ってゆきます。

Python は機械学習やDeep Learningで多用されている言語で、"1つのことをするには1つの書き方しかない" といったポリシーで、分かりやすく使いやすいことを目指して作られた言語です。様々な専門分野に特化したライブラリ(=モジュール)が様々な人によって多く提供されるようになり、初心者でも専門家でも使いやすい言語して大きな広がりをみせています。また、Webサービスでも使われています。Pythonを使えるようになるのは、今後を考えると有意義なことだと思います。

Casio Python は組込用Pythonである Micro Python Ver 1.94 がライセンスされ、カシオがカスタマイズして電卓に組み込んだものなので、一般にPCで使われている Python (CPython) に比べて Casio Python は機能が限定されています。

実際に管理人がCasio Pythonを使い始めて感じるのは、提供されている機能が限定されているので、覚えることが少なくて、理解が容易だということです。カシオ電卓に搭載されている Python は、一般のPythonのサブセット版ではありますが、最近のソフトウェア技術のパラダイムに沿った基本仕様は損なわれていませんので、Python の味見用のお試し版、学校での学習用として使えると思います。

Casio Basic を使いこなして作ったプログラムを Casio Python に移植しようとすると、機能不足、関数不足のために、どうしても移植できないプログラムがあります。Casio Basic と同じ事を実現するために必要不可欠な機能が Casio Python にはまだ揃っていないのは残念なことですが、それなりに工夫すれば使いこなせると思います。
例えば、Casio BasicGetkeyLocate に相当するものが Casio Python にはありません。
Getkey ⇒ これは、どうにもなりません。カシオさんお願い...
Locate ⇒ locate() 関数を自分で作り使用中 ⇒ ユーザー関数 locate()

ところで、Python は本来オブジェクト指向言語です。ライブラリ(=モジュール)を呼び出して使う時に、オブジェクト指向特有のobject.method といった記述が必要なケースもありますが、オブジェクトとメソッドをあまり意識しないで、関数型言語のように使える側面もあると思います。特に Casio Python ではほとんど関数型言語のように使っても、とりあえずスクリプトが書けると思います。マニュアルの記述にもオブジェクトやメソッドという単語が殆ど出てこず、関数という表現が多用されています。



Casio Python の潜在能力 - fx-CG50 OS3.40以降

純正Casio Basic のプログラムから移植可能なものを 実際にCasio Python書き直してみました。すると、

Casio Basic に比べて実行速度が圧倒的に速い!

以下で紹介しますが、その爆速っぷりは、チョット驚きです!
俄然 Casio Python に興味を持ち、詳細を調べたくなりました。
先ずは、その速さを紹介します。


純正Casio BasicCasio Python の処理速度の比較 
Casio Python でグラフィックス描画、関数計算、加算計算をさせて、純正Casio Basic と比較してみます。

グラフィック描画の比較 - フラクタルでシダの葉

shida_py_s 

これは、以下の記事で取り上げたフラクタル図形の描画プログラムです。
fx-CG50 でフラクタル - シダの葉

そこで作成した 純正Casio Basic のプログラム SHIDACG.g3m を Python に移植しました。
Casio Basic プログラムファイルと Python スクリプトファイルのダウンロード

フラクタル図形描画時間の比較
純正Casio Basic40 分
Casio Python24.4 秒
アドイン版Casio Basic - C.Basic for CG Ver 1.45β43.0 秒
※ C.Basic for CG Ver 1.45βについては こちらを参照
※ C.Basic は、コードの最適化により、さらに10倍近く高速化可能です。
 比較のため下記の純正Casio Basic コードを走らせました。

Python は100倍速い!

Casio Basicオリジナルコードと Python スクリプトを以下に示します。できる限り忠実に再現していることが分かると思います。

shida_g3m_py_src3


関数計算の比較 - sin と cos の繰り返し計算

tstfinc2_g3m_py_src
TSTFUNC2.g3m と tstfunc2.py のダウンロード

N に1000 を入力した時 (1000回ループ) の関数計算の比較
純正Casio Basic6.5 秒
Casio Python0.6 秒
アドイン版Casio Basic - C.Basic for CG Ver 1.45β0.38 秒

Pythonでの関数計算が10倍速いことが分かります。


加算計算の比較 - 加算とループ

tstsum2_g3m_py_src2  
TSTSIM2.g3m と tstsum2.py のダウンロード

N に1000 を入力した時 (1000回ループ) の加算計算の比較
純正Casio Basic2.2 秒
Casio Python0.15 秒
アドイン版Casio Basic - C.Basic for CG Ver 1.45β0.02 秒

Pythonでの加算計算が15倍程度速い結果になりました。


Python が速い理由
加算計算や関数計算で10~15倍程度速いだけでなく、グラフィックス描画がさらに10倍程度速いことが分かりました。

ちなみに、シダの葉描画のPhytonスクリプトの最下行にある show_screen() を for ループの外に出すと、VRAM上で全てのデータが揃ってから一気に画面転送を行うことになり、この時は 20.8 秒とさらに速くなります。つまり、show_screen() による画面転送速度が極めて速いことが、シダの葉描画の爆速の原因と言えます。

複雑な計算やグラフィックスやグラフ表示には極めて役立つという、Casio Pythonの潜在能力が明らかになったと思います。今後のグラフィックおよびグラフ描画のためのモジュール追加が期待されます。

なお、シダの葉描画で利用した clear_screen() メソッドは、OS3.40では隠し機能でマニュアルやカタログ機能にありませんでしたが、OS3.50 で公開機能となりました。但し、マニュアルやカタログ機能で見つからない隠し関数がまだ多くあり、これらを探索する方法があります。
Casio Python とは? の "2.2 Casio Python に組み込まれているオブジェクト名の一覧" を参照してください。



Casio Python 探索

Casio Python の潜在能力が意外に高いことが分ったので、これから色々と詳細を調べながら探索を進めたいと思っています。

fx-CG50 や fx-9750GIII のマニュアルを読むと Python モードでの操作法は書かれていますが、関数やメソッドの使い方は殆ど書かれていません。幸いなことにネットで PCの Python (CPython) について簡単に調べて参考にできますが、Casio Python 独自仕様や制限があり、悩むことがあると思います。

そこで、Casio Python を探索しながら、使いこなしの記事を書こうと思います。



 目 次

次の記事 - 1. はじめに:電卓で作る初めてのスクリプト




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


 


keywords: fx-CG50Pythonfx-9750GIIIfx-9860GIIIプログラム関数電卓

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

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

Casio Python - Shell 画面とグラフィック画面の活用:コラッツ問題

Python Casio Python
 Casioグラフ関数電卓の Python を使ってみる
     - Shell 画面とグラフィック画面の活用:コラッツ問題 
目次


初版:2020/12/12


前の記事 - 16. circle() 関数のFXモデルへの拡張 |  次の記事 -


17. Shell 画面とグラフィック画面の活用:コラッツ問題

<fx-CG50 OS3.40以降にに対応>

Casio Python は、入出力に極めて大きな制限があります。そこで今回は、Casio Python で shell 画面とグラフィック画面 (描画画面) をうまく活用して、出力方法を工夫してみます。そのための題材として、コラッツ問題を取り上げます。


17.1 コラッツ問題 (Collatz Problem) とは?

数学の未解決問題の1つにコラッツ問題 (コラッツ予想) があります。

コラッツ問題
任意の正の整数 n に対して、関数 f(n) を以下のように定義する。
  f(n) = 3n+1  (n が奇数のとき)  
      n/2    (n が偶数のとき)
この関数を使って、繰り返し演算を続けて、以下のように数列 ai を作る。
 ・a0 = n
 ・ai = f(ai-1)
どのような 正の整数 n のときでも、数列は 1 に到達する。


要素が1になるまでの数列 ai (i≧0) をコラッツ数列と言います。小学生レベルの四則演算で計算できる一見単純そうな問題です。コンピュータを使って実際に計算して要素が1に到達しない例がまだ見つかっていません。5x260 まで計算されているそうです。しかし、数学的にまだ証明されていません。

数学的に証明されていない限り、もっと大きな整数でコラッツ予想が成り立たなくなる例が見つかるかも知れません。

実際に計算してみます。

(1) n=6 のときのコラッツ数列 (i≧0)
ai = 6, 3, 10, 5, 16, 8, 4, 2, 1
 最初に ai=1 になるとき i = 8 

(2) n=25 のときのコラッツ数列 (i≧0)
ai = 25, 76, 38, 19, 58, 29, 88, 44, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1
 最初に ai=1 になるとき i = 23

(3) n=27 のときのコラッツ数列 (i≧0)
ai = 27, 82, 41, 124, 62, 31. 94, 47, 142, 71, 214, 71, 214, 107, 322, 161, 484, 242, 121, 364, 182, 91, 274, 137, 412, 206, 103, 310, 155, 466, 233, 700, 350, 175, 526, 263, 790, 395, 1186, 593, 1780, 890, 445, 1336, 668, 334, 167, 502, 251, 754, 377, 1132, 566, 283, 850, 425, 1276, 638, 319, 958, 479, 1438, 719, 2158, 1079, 3238, 1619, 4858, 2429, 7288, 3644, 1822, 991, 2734, 1367, 4102, 2051, 6154, 3077, 9232, 4616, 2308, 1154, 577, 1732, 866, 433, 1300, 650, 325, 976, 488, 244, 122, 61, 184, 92, 46, 23, 70, 35, 106, 53, 160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1
 最初に ai=1 になるとき i = 111 

n1 から 26 までは、手計算でも順調にできますが、n=27 になると途端に大変になり、9232 まで大きくなってしまうと、本当に 1 になるのか不安になりますが、結果として 1 に到達できました。

より詳しくは "コラッツ問題" や "コラッツ予想" で検索すれば、色々な情報が得られます。 

管理人としては、Casio Python で、
 ・計算しながら、数列の要素をグラフ表示させ、
 ・最後は、コラッツ数列の全ての要素を出力させる
そのようなスクリプトを作りたくなりました。

計算中は、数列の i の値と ai の値 (数列の要素の値) がどんどん変化している様子をリアルタイムで表示させながら、ai の値の推移をグラフ表示させ、計算が終われば ai の最大値も表示させます。最後に算出した全ての ai (数列の全ての要素) を出力させます。

今回は、以下のような動作をする Casio Python スクリプト - Collatz.py を作ります。




 Collatz.py  ダウンロード

"""Sample script

 Collatz Problem Simulation ver1.0;
 - Graphical and numerical output of
  Collatz sequence a0, a1, a2 ... an

 Collatz.py
  for fx-CG50 OS3.40 or later
   by Krtyski/e-Gadget
"""


from u import *

#Input integer >1
print('\n\n\n== Collatz Problem ==\n\n')
n=int(input('Input number:'))

#Initialize variables
offset=150
scale=50
a=[0]; a[0]=ni=0

#Draw initial screen
locate(0, 0, 'a :', size='l')
locate(3, 1, '0', size='s')
locate(3, 0, a[0], color='blue', size='l')
locate(0, 1, 'i :', size='l')
locate(0, 2, 'a :', size='l')
locate(3, 5, 'i', size='s')
locate(03, 'a :', size='l')
locate(2, 7, 'max', size='s')
line(offset, 191, 383, 191)

#Calculate and draw element of sequence
while a[i]!=1:
 #Increment index
 i+=1

 #Erase previous numbers
 locate(3, 1, i-1, color=0, size='l')
 locate(3, 2, a[i-1], color=0, size='l')

 #Calculate next element of sequence
 if a[i-1]%2:
  a.append(3*a[i-1]+1)
 else:
  a.append(a[i-1]//2)

 #Draw updated numbers
 locate(3, 1, i, size='l')
 locate(3, 2, a[i], size='l')

 #Draw (update) graph of sequence
 if a[i]//scale<192:
  line(offset+i-1, 191-a[i-1]//scale, offset+i, 191-a[i]//scale, (2550, 0))

#Draw finally maximum element
locate(3, 3, max(a), size='l')

#Output all elements of sequence
locate(0, 7, '[EXIT]', size='l')
for i in range(i+1):
 print('a' + str(i) + '=' + str(a[i]))


このスクリプトを見て、何をやっているのかスグに判る場合は、Collatz.py を実行して遊んでみて下さい。

これ以降は、Cllatz.py の解説を行い、少し遊んでみた結果を紹介します。



17.2 コラッツ数列の計算


今回は、コラッツ数列をリストで表現することにします。

つまり、
 数列:ai = a0, a1, a2, ... ,ai-1, ai

 リスト:a = [a0, a1, a2, ... ,ai-1, ai]

とすると、i 番目の要素は a[i] で得られます。

スクリプトの冒頭で、リスト a の定義 (a=[0]) を行います。この定義では、要素が 数値 0 が 1個しかないリストを定義しています。計算が終わらないと要素数が判らないので、次の要素を算出したときに、.append() 関数を使ってリストにその要素を追加し、i を1つづつ増やすようにします。

1つめの要素は、i=0 のときであり、その値は n なので、a[0]=n とします。
すると、リスト a[i] は以下のようにして求められます。

a=[0]; a[0]=ni=0

while a[i]!=1:
 #Increment index
 i+=1

 #Calculate next element of sequence
 if a[i-1]%2:
  a.append(3*a[i-1]+1)
 else:
  a.append(a[i-1]//2)


これを解説します;

a[i]
を求めるには、1つ前の a[i-1] を使って、

a[i-1] が奇数のとき、
 言い換えると、a[i-1] を 2で割ったときの余りが 0 でない時、
 つまり a[i-1]%2 が 0 でない時
  3 × a[i-1] +1 を リスト a の末尾に追加する、つまり
  a.append(3*a[i-1]+1)

・そうでない時、つまり a[i-1] が偶数のとき
  a[i-1] / 2 をリスト a の末尾に追加する、つまり
  a.append(a[i-1]//2)
  ※ ここで、リストの要素を整数にしたいので、// 演算子 (割り算の商 = 整数部を得る)を使う

この処理を a[i] が 1 でない限り繰り返せば良いので、上記の処理を whilr a[i] != 1: のループの中に記述しています。


17.3 出力の工夫ポイント

17.3.1 input() での出力
最初に1以上の整数を入力させるには、Casio Python に備わっている唯一の入力関数 input() を使います。
input() を使うと、キー入力した文字列や数値は、全て文字列として返ります。今回は、入力した数値を 数値変数 n に代入したいので、input() の戻り値を int() 関数で整数に変換します。

n=int(input())

入力時に表示する文字列は input()( ) 内に指定します。

n=int(input('Input number:'))

さて、今回は以下のような入力画面にしてみます。
Collatz_input 

チョット格好良いですね!
ちなみに、Collatz Problemコラッツ問題 のことです。

このような配置にするには、改行を利用します。文字列の中に \n を入れたら、そこで改行します。

そこで、入力画面は以下のようにします。

print('\n\n\n== Collatz Problem ==\n\n')
n=int(input('Input number:'
))



17.3.2 フォントサイズを変えて添え字の描画
コラッツ数列 ai は、添え字を使っているので、出力画面でも添え字が表現できると格好イイですよね!
そこで、以下のような表示にしてみました。

Collatz_27_1    

ここでは、a0aiamax を表示しています。

実は最初は以下のような表示にしましたが、添え字の 0i 、特に i が見づらいので却下。上のように見やすさを優先しました。

Collatz_27_2   


グラフィック画面では、大、中、小 の 3つのサイズのフォントが使えます。フォントピッチ (フォントの大きさ) を考えると、大フォントのピッタリ 1/2 が小フォントになっているので、大フォントの添え字に小フォントを使うとうまくいきそう。

ユーザー関数 locate() を作っているので、これを使います。スクリプトはチョット面倒に見えますが、コンセプトは簡単なので、地道に作ってゆきます。

 ユーザー関数 locate() の説明
 ※ locate() を使うには、ユーザーモジュール u.py をインポートします。
   from u import *


結果は、以下のようになります。

locate(0, 0, 'a :', size='l')
locate(3, 1, '0', size='s')
locate(3, 0, a[0], color='blue', size='l')
locate(0, 1, 'i :', size='l')
locate(0, 2, 'a :', size='l')
locate(3, 5, 'i', size='s')
locate(03, 'a :', size='l')
locate(2, 7, 'max', size='s')


ところで、コラッツ数列 ai を、今回のスクリプトでは リスト a で扱っていて、コラッツ数列の定義から、a0n なので、
 a[0] = n
となります。

上の locate() が並んだスクリプトの、上から3番目に a[0] で出てきていますが、これは n に置き換えても同じです。そして、このときだけ 青色で表示していることは、color='blue' がパラメータに入っていることで判ります (ユーザー関数 locate() の仕様)。


17.3.3 リアルタイムに変わる数値の表示
これを実現するには、グラフィック画面 (描画画面) に文字列を描画するしかありません。print() でshell 画面に出力するのでは、スクロールしてしまいます。

グラフィック画面で文字列を描画するには、casioplot モジュールに含まれる draw_string() 関数を使えば良いのですが、より使いやすくするために作ったユーザー関数 locate() を使います。

描画した文字列を新しい文字列で上書きするには、以下の手順が必要になります。
 (1) 色を指定して文字列を描画
 (2) 同じ位置に同じ文字列を白で再描画して、文字列を消去
 (3) 同じ位置に新たな文字列描画
手順 (2) が不可欠です。

locate() を使うには、ユーザーモジュール u.py をインポートします。
  from u import *


コラッツ数列を リスト a として得るための while ループの中に、i の値と a[i] の値をリアルタイムで描画するコードを追加すると、以下のようになります。

#Calculate and draw element of sequence
while a[i]!=1:
 #Increment index
 i+=1

 #Erase previous numbers ◀ この2行↓を追加
 locate(3, 1, i-1, color=0, size='l')
 locate(3, 2, a[i-1], color=0, size='l')

 #Calculate next element of sequence
 if a[i-1]%2:
  a.append(3*a[i-1]+1)
 else:
  a.append(a[i-1]//2)

 #Draw updated numbers ◀ この2行↓を追加
 locate(3, 1, i, size='l')
 locate(3, 2, a[i], size='l')



17.3.4 グラフの描画
横軸に i の値、縦軸に a[i] の値 をとって、ユーザー関数 line() を使ってグラフを描画します。

基本的には、点 (i-1, a[i-1]) と 点 (i, a[i]) を結んだ線分を描画することになりますが、画面全体の左上が原点になる座標系から、所定の長方形のエリアの中に収まるように変換して描画する必要があります。

今回は、点 (x, y) について以下のように変換します。

横座標 (x座標) は、
  左から 150 ドットの位置から右側を使うので、変数 offset = 150 として、
  offset だけ右にずらすので、xoffset+x に変換します。

縦座標 (y 座標) は、
  上下反転させ、変数 scale = 50 として 50分の1に圧縮して整数部を取得するので、
  y191-y//scale に変換します。 

ちなみに、// 演算は除算した時の商、つまり割り算結果の整数部を得るもので、これにより整数値が得られます。line() 関数に指定する座標パラメータは整数でなくてはならない(仕様です)ので、// 演算を用います。


以上から、
 点 (i-1, a[i-1]) は、点 (offset+i-1, 191-a[i-1]//scale)
 点 (i, a[i]) は、点 (offset+i, 191-a[i]//scale)
変換できます。

そして、今回はグラフを赤 (r, g,b) = (255, 0, 0) で描画することにしているので、line() 関数を使った線分描画は、以下のようになります。

 line(offset+i-1, 191-a[i-1]//scale, offset+i, 191-a[i]//scale, (255, 0, 0))


ところで、今回のグラフ描画エリアも画面に表示します。但し長方形のエリアではなく、エリアの下端のみを直線で示すことにします。そこで、line() 関数を使って、以下のようにします。
 line(offset, 191, 383, 191)


さて、今の line() 関数の仕様では、画面の外の座標を指定すると、エラーにならず見えない範囲に線分描画の動作を行うので、見えない線分描画に時間がかかってしまいます。そこで、今回指定したグラフ描画エリアの外の座標を設定する場合は描画をスキップするようにして、全体として高速化します。

具体的には、a[i]//scale の値が グラフ描画エリアの高さ(縦幅)に収まるときだけ、line() 関数で描画するようにしました。
 if a[i]//scale192:
  line(offset+i-1, 191-a[i-1]//scale, offset+1, 191-a[i]//scale, (255, 0, 0
))


Collatz_27_1  


ユーザー関数 line() の説明
  ※ line() を使うには、ユーザーモジュール u.py をインポートします。
    from u impot *  


offset=150            ◀ この行を追加
scale=50             ◀ この行を追加
a=[0]; a[0]=ni=0

line(offset, 191, 383, 191) ◀ この行を追加

#Calculate and draw element of sequence
while a[i]!=1:
 #Increment index
 i+=1

 #Erase previous numbers
 locate(3, 1, i-1, color=0, size='l')
 locate(3, 2, a[i-1], color=0, size='l')

 #Calculate next element of sequence
 if a[i-1]%2:
  a.append(3*a[i-1]+1)
 else:
  a.append(a[i-1]//2)

 #Draw updated numbers
 locate(3, 1, i, size='l')
 locate(3, 2, a[i], size='l')

 #Draw (update) graph of sequence ◀ この2行↓を追加
 if a[i]//scale<192:
  line(offset+i-1, 191-a[i-1]//scale, offset+i, 191-a[i]//scale, (2550, 0))



17.3.5 数列の値の最大値を求めて表示
冒頭で、整数 27 からコラッツ数列を求めたところ、最大 9232 とかなり大きな数になったのに、少し驚きました。そこで、求めた数列の最大の要素を表示したいと思いました。

そこで while ループ終了後に、a[i] の最大値を求めて表示します。
リスト a の要素から最大値を返す関数 max() を使えば、max(a) が最大値を返します。

ところで、max() 関数は、最大値が2つ以上有る時は、リストの中で一番左にあるものを返します。今回は最大値のみに感心があるので、max() 関数を使うだけで十分です。

この最大値を locate() 関数で、所定の位置に描画するには、以下のように記述します。
 locate(3, 3, max(a), size='l')

==========

#Initialize variables
offset=150
scale=50
a=[0]; a[0]=ni=0

#Calculate and draw element of sequence
while a[i]!=1:
 #Increment index
 i+=1

 #Erase previous numbers
 locate(3, 1, i-1, color=0, size='l')
 locate(3, 2, a[i-1], color=0, size='l')

 #Calculate next element of sequence
 if a[i-1]%2:
  a.append(3*a[i-1]+1)
 else:
  a.append(a[i-1]//2)

 #Draw updated numbers
 locate(3, 1, i, size='l')
 locate(3, 2, a[i], size='l')

 #Draw (update) graph of sequence
 if a[i]//scale<192:
  line(offset+i-1, 191-a[i-1]//scale, offset+i, 191-a[i]//scale, (2550, 0))

#Draw finally maximum element ◀ この1行を追加
locate(3, 3, max(a), size='l')



17.3.6 shell 画面でのスクロール出力
最後に、コラッツ数列の全要素を表示したいのですが、計算するまでは要素数が判らないので、グラフィック画面に出力するよりも、shell 画面でスクロールさせて出力するのが良いと思います。スクロールアップ/ダウンも自由にできるので、全要素を詳しく見るのに適しています。

冒頭の動画で判るように、グラフィック画面 と shell 画面を、適材適所でうまく使い分けると良いと思います。

shell 画面でリスト a の要素 a[0] から a[i] までを表示するには、

 for i in range(i+1):
  print(a[i])


とすればOKです。

ここでは、コラッツ数列の要素を表示するのが本来な目的なので、例えば i = 70 のときの ai を表示する場合は、

 a70=991

と表示しようと思います。そこで、スクリプトは以下のようになります。

 for i in range(i+1):
  print('a' + str(i) + '=' + str(a[i
]))



グラフィック画面 (描画画面) が表示されているとき、shell 画面に切り替える方法が2つあります。
[EXIT]キーを押す
input() を実行する

今回は、[EXIT] キーを押せば良いので、グラフィック画面のまま維持しておき、[EXIT] キーを押してもらってから、shell 画面に切り替わるようにします。そこで、操作ガイドの意味で、グラフィック画面の左下に [EXIT] と表示しようと思います。
 locate(0, 7, '[EXIT]', size='l')

これに続いて、上記の リスト a の要素表示のスクリプトを追加すれば、うまくゆきます。

最後に Casio Python の制限について、付記しておきます。fx-CG50 の Pythonモードでは、print() 関数の出力は最大 200行に制限されています。コラッツ数列 (= リスト a) の要素数が 200 個を超えると、全ての要素が表示されません。

色々と整数を変えて遊んでいる限りは、今のところ 200 行を超えるケースがないので、なんとかなりそうです。以下の動画では、整数が20000以下のときは、要素数 200 を超える場合が結構少ないことが判ります。





もし 200 行を超えるものが沢山でてくるならば、チョット面倒ですが工夫次第でなんとかできると思います。

==========

全要素表示の部分を最後に追加し、今回検討したスクリプト全体を以下に示します。

from u import *

#Input integer >1

print('\n\n\n== Collatz Problem ==\n\n')
n=int(input('Input number:'))

#Initialize variables
offset=150
scale=50
a=[0]; a[0]=ni=0

#Draw initial screen
locate(0, 0, 'a :', size='l')
locate(3, 1, '0', size='s')
locate(3, 0, a[0], color='blue', size='l')
locate(0, 1, 'i :', size='l')
locate(0, 2, 'a :', size='l')
locate(3, 5, 'i', size='s')
locate(03, 'a :', size='l')
locate(2, 7, 'max', size='s')
line(offset, 191, 383, 191)

#Calculate and draw element of sequence
while a[i]!=1:
 #Increment index
 i+=1

 #Erase previous numbers
 locate(3, 1, i-1, color=0, size='l')
 locate(3, 2, a[i-1], color=0, size='l')

 #Calculate next element of sequence
 if a[i-1]%2:
  a.append(3*a[i-1]+1)
 else:
  a.append(a[i-1]//2)

 #Draw updated numbers
 locate(3, 1, i, size='l')
 locate(3, 2, a[i], size='l')

 #Draw (update) graph of sequence
 if a[i]//scale<192:
  line(offset+i-1, 191-a[i-1]//scale, offset+i, 191-a[i]//scale, (2550, 0))

#Draw finally maximum element
locate(3, 3, max(a), size='l')

#Output all elements of sequence ◀ この3行↓を追加
locate(0, 7, '[EXIT]', size='l')
for i in range(i+1):
 print('a' + str(i) + '=' + str(a[i]))


17.4 コラッツ問題で遊んでみる

適当に入力する整数を選んで、コラッツ数列の要素数 i が大きい順に並べてみました。ここでは、170 ⇒ 160 ⇒ 151 を例に挙げています。当然これより大きな要素数になるケースは間違いなくあります。

Collatz_4321 Collatz_5433 Collatz_2345 

グラフの縦軸は、縮尺率 scale = 50 にしているから、191 x 50 = 9550 が表示できる amax の上限です。これを超える場合は表示されていません。上の3つの例では、いずれも amax は 9550 以上になっています。
グラフのパターンの後半は a0 = 27 と同じになっているのが面白いですね。

これに続く要素数は、例えば以下のように 147 ⇒ 144 ⇒ 136 になりました。

Collatz_865 Collatz_654 Collatz_543 

要素数 i に関わらず要素の最大値 amax9232 になっています。最初に与える整数 a0 (=リストa[0]) が 27 の時も amax = 9232 で同じなので、数列要素の計算の終盤の計算パターン (グラフのパターン) が同じになっているようですね。amax が 9550 以下なので、グラフは描画エリア内に収まっています。

さらに、これに続く要素数は、例えば以下のように 132 ⇒ 127 ⇒ 125 なりました。

Collatz_1234 Collatz_235 Collatz_345 

要素の最大値 amax9232 になる計算パターン (グラフのパターン) は、a0 (=a[0]) が小さい時に多く見られるようです。

そして、amax9232 になるとき、a0 (=a[0]) の最小値は 27 なのは簡単に確認できます。その時の要素数 i111 です。

Collatz_27_3 

コラッツ問題 / コラッツ予想 で計算するコラッツ数列は、なんとも面白い動きをします。いずれ誰かが数学的に証明するのでしょう。その時が楽しみです。




目 次

前の記事 - 16. circle() 関数のFXモデルへの拡張

次の記事 -





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


 


keywords: fx-CG50Pythonfx-9750GIIIfx-9860GIIIプログラム関数電卓

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

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

Casio Python - ユーザー関数 locate()

Python Casio Python
 Casioグラフ関数電卓の Python を使ってみる
     - リファレンス 
目次
locate()

ユーザーモジュール u.py に含まれる関数 u.py ver 1.5 ダウンロード

初版:2020/12/09

[対応モデル] - fx-CG50 OS3.20 以降、fx-9750GIII / fx-9860GIII OS3.21 以降

文字(列)  や 数値を、桁と行で位置を指定してグラフィック画面に描画します。
併せて、描画の色とフォントサイズを指定することもできます。
さらに、画面に転送するか、VRAMのみに転送するかの選択も可能です。

書 式locate(column, row, obj, color=1, size='m', show=1)

引 数
- 第1引数 - column: 描画する文字(列) / 数値 の座標 (桁, 行) の 桁座標、0 以上の整数
- 第2引数 - row: 描画する文字(列) / 数値の座標 (桁, 行) の 行座標、0 以上の整数
- 第3引数 - obj: 描画する文字(列) / 数値
- 第4引数 - color: 色を指定するパラメータ引数で、省略可能でデフォルトは 1 です。
       この引数は、内部で使っているユーザー関数 grp_color() に渡されます。
       引数の具体的な設定については grp_color() のリファレンスを参照。
- 第5引数 - size: フォントサイズを指定するパラメータ引数で、'l', 'm', 's' のいずれか。
       これは省略可能で、省略時は 'm' になります。
       'l' - 大フォント、'm' - 中フォント、's' - 小フォント
- 第6引数 - show: 1 のときは液晶に出力し、0 のときはVRAMへ転送するだけです。
       これは
パラメータ引数で、省略時は 1 になります。

引数を5つ、値だけを指定するとエラーになります ⇒ 関数の引数は こちら を参照。
引数を5つだけ設定する場合は、パラメータと共に設定します。
  例) line(5, 50, 30, 60, color=4) / line(5, 50, 30, 60, show=0)
フォントサイズの詳細 (CGモデル)
   ・'l' (大): 桁は 0~21、行は 0~7  | フォントピッチは 横16 dot、縦24 dot
   ・'m' (中): 桁は 0~31、行は 0~11 | フォントピッチは 横12 dot、縦16 dot
   ・'s' (小): 桁は 0~47、行は 0~17 | フォントピッチは 横 8 dot、縦12 dot
 フォントサイズの詳細 (FXモデル)
   ・'l' (大): 桁は 0~20、行は 0~7 | フォントピッチは 横 6 dot、縦 8 dot
   ・'m' (中): 桁は 0~31、行は 0~9 | フォントピッチは 横 4 dot、縦 6 dot
   ・'s' (小): 'm' と同じ (↑)


関数定義:

from casioplot import *

def locate(column, row, obj, color=1, size='m', show=1):
 #set fontsize & pitch
 #from 4th argument(size)
 if isCG(): #CG model
  dx={'s':8, 'm':12, 'l':16}
  dy={'s':12, 'm':16, 'l':24}
 else: #FX model
  dx={'s':4'm':4, 'l':6}
  dy={'s':6, 'm':6, 'l':8}
 sz={'s':'small', 'm':'medium', 'l':'large'}

 #data transfer to VRAM
 draw_string(column*dx[size], row*dy[size], str(obj), grp_color(color), sz[size])

 if show: #data transfer to screen
  show_screen
()



スクリプトの解説:
 実行しているモデル(FXモデルかCGモデルか)の判定は自動で行います - ユーザー関数 isCG() 利用 
  テキスト出力関数の追加:locate() をユーザーモジュールに追加 ⇒ こちら
  isCG() ユーザー関数 [CGモデルとFXモデルの判定方法] ⇒ こちら
  grp_color() ユーザー関数 ⇒ こちら



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


 


keywords: fx-CG50Pythonfx-9750GIIIfx-9860GIIIプログラム関数電卓

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

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

Casio Python - 要素数の多いリスト:高速素因数分解(5)

Python Casio Python
 Casioグラフ関数電卓の Python を使ってみる
     - 要素数の多いリスト:高速素因数分解(5) 
目次


初版:2020/08/03
大幅な追記修正:2020/08/06
Windowsアプリ修正:2020/08/13
追記修正:2020/11/14

前の記事 - 11. 関数のオーバーヘッド |  次の記事 - 13. 10進数除算の出力と精度


12. 要素数の多いリスト:高速素因数分解(5) <fx-CG50 OS3.4以降>

前回、関数呼出を無くして、15桁対応素因数分解を少し高速化しました。

高速素因数分解 15桁対応、僅かに高速化版 - FactorF4.py のダウンロード

以下のように素因数が15桁になるケースでは、実行時間が 23分30秒 もかかり、素因数探索のループを回る回数が 435万回程度になります (search:4349444)。
15digit_prime 

ここでは以下のロジックで探索数を決めています。今回は、同じロジックで、探索数を拡張する方法を検討します。

要素数48個の探索数増分リストを用いる方法
現在のロジックは、探索数の重複を効率よく減らせる点に特徴があり、
a) 素数 2, 3, 5, 7, 11 を探索数として除算を繰り返し、
b) 13222 の整数で 2, 3, 5, 7 のいずれかの倍数でない探索数で除算を繰り返し、
エラストテレスの篩いで素因数を調べる、という手法を採用しています。


12.1 増分リストを拡張する
同じロジックで、探索数を拡張してみます。それにより探索の無駄をさらに減らして、高速化を試みます。
要素数48個の増分リストを以下のように拡張します。

 探索数増分リストを拡張する方法
A) 素数 2, 3, 5, 7, 11, 13 を探索数として除算を繰り返し、
B) 172326 の整数で 2, 3, 5, 7, 11 のいずれかの倍数でない探索数で除算を繰り返し、
エラストテレスの篩いで素因数を調べる、


素因数探索で取りこぼしを防ぐために 172326 までの整数のうち 2, 3, 5, 7, 11 のいずれかの倍数でない整数を用い、その探索数は 480 個あります。 探索数増分リスト increment[ ] の要素は 480 個になります。スクリプトとして書き出す際は、1行8要素として、リストの定義に60行必要になります。

探索数を 17~2326 の範囲で探し、それが480個になる詳しい説明は、fx-5800P 素因数分解 - 高速化 を参照してください。
簡単にまとめると、
  • 2, 3, 5, 7, 11 の最小公倍数は 2310
  • 2, 3, 5, 7, 11 のいずれかの倍数でない探索数の増分は 2310 の周期
  • 探索数を17から調べるので、1周期の終わりは 2326
  • 2, 3, 5, 7, 11 のいずれの倍数でない整数の個数:480個
  • これの算出方法は以下の通り;
  •  2 の倍数の個数:2310/2 = 1155
  •  3 の倍数の個数:2310/3 = 770
  •  5 の倍数の個数:2310/5 = 462
  •  7 の倍数の個数:2310/7 = 330
  •  11 の倍数の個数:2310/11 = 210 ⇒ 以上の合計:2927個
  • .
  •  2と3の公倍数の個数:2310/6 = 385
  •  2と5の公倍数の個数:2310/10 = 231
  •  2と7の公倍数の個数:2310/14 = 165
  •  2と11の公倍数の個数:2310/11 = 105
  •  3と5の公倍数の個数:2310/15 = 154
  •  3と7の公倍数の個数:2310/21 = 110
  •  3と11の公倍数の個数:2310/33 = 70
  •  5と7の公倍数の個数:2310/35 = 66
  •  5と11の公倍数の個数:2310/55 = 42
  •  7と11の公倍数の個数:2310/77 = 30 ⇒ 以上の合計:1358個
  • .
  •  2と3と5の公倍数の個数:2310/2/3/5 = 77
  •  2と3と7の公倍数の個数:2310/2/3/7 = 55
  •  2と3と11の公倍数の個数:2310/2/3/11 = 35
  •  2と5と7の公倍数の個数:2310/2/5/7 = 33
  •  2と5と11の公倍数の個数:2310/2/5/11 = 21
  •  2と7と11の公倍数の個数:2310/2/7/11 = 15
  •  3と5と7の公倍数の個数:2310/3/5/7 = 22
  •  3と5と11の公倍数の個数:2310/3/5/11 = 14
  •  3と7と11の公倍数の個数:2310/3/7/11 = 10
  •  5と7と11の公倍数の個数:2310/5/7/11 = 6 ⇒ 以上の合計:288個
  • .
  •  2と3と5と7の公倍数の個数:2310/2/3/5 = 11
  •  2と3と5と11の公倍数の個数:2310/2/3/5/11 = 7
  •  2と3と7と11の公倍数の個数:2310/2/3/7/11 = 5
  •  2と5と7と11の公倍数の個数:2310/2/5/7/11 = 3
  •  3と5と7と11の公倍数の個数:2310/3/5/7/11 = 2 ⇒ 以上の合計:28個
  • .
  •  2と3と5と7と11の公倍数の個数:2310/2/3/5/7/11 = 1個
  • .
  •  以上から 2927 - 1358 + 288 - 28 + 1 = 480個
この480個の増分リスト increment[ ] の要素は、エクセルを使って半手動で求めることができますが、計算の正確さ、計算結果をスクリプトに転記する作業の正確さ(これが最大の目的)、そして時間の節約のために、アプリ SearchNum11.exe を Visual Studio 2019 Community の C# で作りました。C# はマウスクリックするだけのプロパティ設定を行うだけで殆どを自動作成してくれ、具体的なコーディングは30行程度で済みました。

要素数480の探索数増分リストの要素を出力するWindowsデスクトップアプリ
 - SearchNum11 のダウンロード


ダウンロードファイルには、アプリの実行ファイル (SearchNum11.exe) だけでなくソースコードも同梱していますので、ご自由にお使いください。どのように計算しているのかに興味があれば、上からダウンロードしたzipファイルに含まれる SearchNum11.cs を右クリックして ”編集" を選んぶとソースコードがメモ帳で開きます(Windows10)。肝心の計算は private void CalcNum() にあります (480個、60行程度の出力なので簡易的なコードにしています。より出力が多くなる場合は、プログラムがCPUを占有しないようにチョット工夫が必要です。)

SearchNum11.exe を起動したところ:
SearchNum11_1

右上の [Calculate] ボタンを押すと、各要素とコンマ ,  がテキストボックスに出力されます。
SearchNum11_result
出力されると [Calculate] ボタンを押せなくしています。

1行あたり 8要素で改行するように出力しています。
テキストボックスでは、改行したり編集ができます。そこで、これをPC上でカットアンドペーストにより、エディタで開いた スクリプトに貼り付ければ、増分リストの要素を簡単に書き込めます。

例えば、上のテキストボックスの中でクリックしてから、[Ctrl]+[A] で全部を選択してから、[↑] キーを押して 最後の 12, のコンマの前まで (12 まで) 選択した状態で、[Ctrl]+[C] でコピーしてから、

エディタで、
increment=/
[ ]


] の中にカーソルを移動して、[Ctrl]+[V] とすればペーストできます。 


12.2 要素数480個の探索数増分リスト
先ずは、480個の探索数増分を要素数にするリスト increment[ ] を採用して、どの程度の実行速度改善が見られるのか、調べて見ます。

prime_list=[2,3,5,7,11,13]
for b in prime_list:
 search+=1
 d=a/b
 if frac(d)==0:
  e+=1
  z[e]=b
  while 1:
   a=int(d)
   z[e+21]+=1
   d=a/b
   if frac(d):
    break
  c=int(sqrt(a))
 if b>c:break


increment=\
[4,2,4,6,2,6,4,2,
 4,6,6,2,6,4,2,6,
 4,6,8,4,2,4,2,4,
 14,4,6,2,10,2,6,6,
 4,2,4,6,2,10,2,4,
 2,12,10,2,4,2,4,6,
 2,6,4,6,6,6,2,6,
 4,2,6,4,6,8,4,2,
 4,6,8,6,10,2,4,6,
 2,6,6,4,2,4,6,2,
 6,4,2,6,10,2,10,2,
 4,2,4,6,8,4,2,4,
 12,2,6,4,2,6,4,6,
 12,2,4,2,4,8,6,4,
 6,2,4,6,2,6,10,2,
 4,6,2,6,4,2,4,2,
 10,2,10,2,4,6,6,2,
 6,6,4,6,6,2,6,4,
 2,6,4,6,8,4,2,6,
 4,8,6,4,6,2,4,6,
 8,6,4,2,10,2,6,4,
 2,4,2,10,2,10,2,4
 2,4,8,6,4,2,4,6,
 6,2,6,4,8,4,6,8,
 4,2,4,2,4,8,6,4,
 6,6,6,2,6,6,4,2,
 4,6,2,6,4,2,4,2,
 10,2,10,2,6,4,6,2,
 6,4,2,4,6,6,8,4,
 2,6,10,8,4,2,4,2,
 4,8,10,6,2,4,8,6,
 6,4,2,4,6,2,6,4,
 6,2,10,2,10,2,4,2,
 4,6,2,6,4,2,4,6,
 6,2,6,6,6,4,6,8,
 4,2,4,2,4,8,6,4,
 8,4,6,2,6,6,4,2,
 4,6,8,4,2,4,2,10,
 2,10,2,4,2,4,6,2,
 10,2,4,6,8,6,4,2,
 6,4,6,8,4,6,2,4,
 8,6,4,6,2,4,6,2,
 6,6,4,6,6,2,6,6,
 4,2,10,2,10,2,4,2,
 4,6,2,6,4,2,10,6,
 2,6,4,2,6,4,6,8,
 4,2,4,2,12,6,4,6,
 2,4,6,2,12,4,2,4,
 8,6,4,2,4,2,10,2,
 10,6,2,4,6,2,6,4,
 2,4,6,6,2,6,4,2,
 10,6,8,6,4,2,4,8,
 6,4,6,2,4,6,2,6,
 6,6,4,6,2,6,4,2,
 4,2,10,12,2,4,2,10,
 2,6,4,2,4,6,6,2,
 10,2,6,4,14,4,2,4,
 2,4,8,6,4,6,2,4,
 6,2,6,6,4,2,4,6,
 2,6,4,2,4,12,2,12
]

while 1:
 for i in increment:
  search+=1
  b+=id=a/b
  if frac(d)==0:
   e+=1
   z[e]=b
   while 1:
    a=int(d)
    z[e+21]+=1
    d=a/b
    if frac(d):
     break
   c=int(sqrt(a))
  if b>cbreak
 if b>c
break


大きな要素数のリスト
ここで気になるのは、480個の整数要素のリストが正しく扱えるのかどうか?という点なので、チョット確認してみます。

というのも、以下のスクリプトを実行すると MemoryError が発生します。
lst = list(range(480))
print(lst)

ところで、要素数を 480 から 123 に変更して、
lst = list(range(123))
print(lst)
を実行すると、MemoryError が発生しなくなります。

つまり、この MemoryError は、print() が使用するスタックメモリが不足して発生していることが分かり、これは Casio Python 特有の仕様だと思われます。


さて、以下のスクリプトを試します。

n=480; s=0
lst = list(range(n))
for i in range(n):
 s+=lst[i]
print(len(lst))
print(s)

これは、
・リスト lst = [0, 1, 2, ... , 477, 478, 479] を作り、
・各要素の和を計算して 変数 s に格納
・リスト lst の要素数と 変数 s の値を表示
するスクリプトです。

実行結果は、
480
114960

となり、正しい値さと分かります。正解は (0+480)×480/2 で簡単に検算できます。
従って、要素数 480 個の整数リスト自体は問題無く使えそうです。


12.3 探索数を拡大した15桁対応高速素因数分解のスクリプト

2, 3, 5, 7, 11 のいずれの倍数でもない数を探索数とし、探索数を 480 個に拡大したスクリプトは以下のようになります。

※ 高速素因数分解:15桁入力対応、探索数拡張版 - FactorG5.py のダウンロード

fx-CG50 Pythonモード:高速素因数分解 - FactorG5.py
"""Sample script

 Exercise;
 ported from Casio Basic
 "Prime Factor 15 digits"
  factorG.py
   ver 5.0

 by Krtyski/e-Gadget
"""

from u import *
digit=
15
search=0

def disp():
 global a,e,f,z
 clear_screen()
 locate(00f3'm'0)
 locate(160': ' str(len(inp)) + ' digits'3'm'0)
 locate(16, 11, 'search:'+str(search), 2, 'm', 0)
 line(0,15,383,15,1,0)
 for i in range(115):
  if i<=e:
   dx=int(i/12)*16
   dy=int(i/12)*11
   locate(0+dxi-dyz[i], 1'm'0)
   locate(10+dxi-dy'^('2'm'0)
   locate(12+dxi-dyz[i+21], 1'm'0)
   locate(15+dxi-dy')'2'm'0)
 locate
(00''0'm'1)


while
1:
 try:
  inp=str(eval(input('Number:')))
 except (SyntaxError,TypeError,NameError) as e:
  print(e)
  print('*must be number or\n expression')
  continue
 if '.' in inp:
  print('*must be integer')
  continue
 elif inp.isdigit():
  if len(inp)>digit:
   print('*must be '+str(digit)+' digit\n or less')
   continue
  else:
   f=int(inp)
   break
 else:
  continue

z=list(range(23))
for e in range(1,23):
 z[e]=0
e=0
a=f
c=int(sqrt(a))

prime_list=[2,3,5,7,11]
for b in prime_list:
 search+=1
 d=a/b
 if frac(d)==0:
  e+=1
  z[e]=b
  while 1:
   a=int(d)
   z[e+21]+=1
   d=a/b
   if frac(d):
    break
  c=int(sqrt(a))
 if b>c:break


increment=\
[4,2,4,6,2,6,4,2,
 4,6,6,2,6,4,2,6,
 4,6,8,4,2,4,2,4,
 14,4,6,2,10,2,6,6,
 4,2,4,6,2,10,2,4,
 2,12,10,2,4,2,4,6,
 2,6,4,6,6,6,2,6,
 4,2,6,4,6,8,4,2,
 4,6,8,6,10,2,4,6,
 2,6,6,4,2,4,6,2,
 6,4,2,6,10,2,10,2,
 4,2,4,6,8,4,2,4,
 12,2,6,4,2,6,4,6,
 12,2,4,2,4,8,6,4,
 6,2,4,6,2,6,10,2,
 4,6,2,6,4,2,4,2,
 10,2,10,2,4,6,6,2,
 6,6,4,6,6,2,6,4,
 2,6,4,6,8,4,2,6,
 4,8,6,4,6,2,4,6,
 8,6,4,2,10,2,6,4,
 2,4,2,10,2,10,2,4,
 2,4,8,6,4,2,4,6,
 6,2,6,4,8,4,6,8,
 4,2,4,2,4,8,6,4,
 6,6,6,2,6,6,4,2,
 4,6,2,6,4,2,4,2,
 10,2,10,2,6,4,6,2,
 6,4,2,4,6,6,8,4,
 2,6,10,8,4,2,4,2,
 4,8,10,6,2,4,8,6,
 6,4,2,4,6,2,6,4,
 6,2,10,2,10,2,4,2,
 4,6,2,6,4,2,4,6,
 6,2,6,6,6,4,6,8,
 4,2,4,2,4,8,6,4,
 8,4,6,2,6,6,4,2,
 4,6,8,4,2,4,2,10,
 2,10,2,4,2,4,6,2,
 10,2,4,6,8,6,4,2,
 6,4,6,8,4,6,2,4,
 8,6,4,6,2,4,6,2,
 6,6,4,6,6,2,6,6,
 4,2,10,2,10,2,4,2,
 4,6,2,6,4,2,10,6,
 2,6,4,2,6,4,6,8,
 4,2,4,2,12,6,4,6,
 2,4,6,2,12,4,2,4,
 8,6,4,2,4,2,10,2,
 10,6,2,4,6,2,6,4,
 2,4,6,6,2,6,4,2,
 10,6,8,6,4,2,4,8,
 6,4,6,2,4,6,2,6,
 6,6,4,6,2,6,4,2,
 4,2,10,12,2,4,2,10,
 2,6,4,2,4,6,6,2,
 10,2,6,4,14,4,2,4,
 2,4,8,6,4,6,2,4,
 6,2,6,6,4,2,4,6,
 2,6,4,2,4,12,2,12
]

while 1:
 for i in increment:
  search+=1
  b+=id=a/b
  if frac(d)==0:
   e+=1
   z[e]=b
   while 1:
    a=int(d)
    z[e+21]+=1
    d=a/b
    if frac(d):
     break
   c=int(sqrt(a))
  if b>cbreak
 if b>c
break

if a>1:
 e+=1
 z[e]=a
 a=1
 z[e+11]=
1

disp
()



12.4 探索数拡大による高速化
前回作成した Ver 4.0 と今回作成した Ver 5.0 の実行速度を比較しました。

比較対象は、前回と同じく以下の10個のケースを用います。

search_30445_f Search_39969_f seach_47824_f 
Case1_14digit search_90872_f search_189426_f.png 
search_263027_f.png search_343013_f.png search_2025804_f.png 
search_4349444_f.png 


表2- 探索数拡大による実行時間の違い - Ver 4.0 と Ver 5.0 の比較
Ver 4.0Ver 5.0
入力値serach実行時間
[秒]
search実行時間
[秒]
高速化
[秒]
search
減少率[%]
547,896,321,054,789 30,445 9.627,679 8.70.99.1
7,845,162,037,849 39,969 12.536,337 11.41.19.1
748,159,026,374,815 47,824 15.043,478 13.71.39.1
36,209,518,473,620 55,241 17.150,221 15.51.69.1
986,753,421,098,675 90,872 28.682,612 26.02.69.1
96,835,724,130,261 189,426 58.1172,207 52.75.49.1
748,159,026,396,835 263,027 80.5239,116 73.17.49.1
96,835,724,136,209 343,013 104.5311,832 95.39.29.1
748,159,026,336,209 2,025,804 644.0
(10分44秒)
1,841,642 585.0
(9分45秒)
59.09.1
362,095,184,736,209 4,349,444 1,361.0
(22分41秒)
3,954,042 1,235.6
(20分35.6秒)
125.49.1


search回数は、どの入力値でも一律に 9.1% 減少して、高速化していることが分かります。実行速度は 9~10%程度の高速化となりました。


12.5 増分リストをさらに拡張する 

ところで、さらに探索数を拡大して、2, 3, 5, 7, 11, 13 のいずれかの倍数でない探索数を得るための増分リストに拡張してみました。

要素数5760個の探索数増分リストを用いる方法
A-2) 素数 2, 3, 5, 7, 11, 13, 17 を探索数として除算を繰り返し、
B-2) 1930048 の整数で 2, 3, 5, 7, 11, 13 のいずえかの倍数でない探索数で除算を繰り返し、
エラストテレスの篩いで素因数を調べる。

この場合は、取りこぼしを防ぐためには、2, 3, 5, 7, 11, 13 のいずれかの倍数でない整数は 5750 個あります。この個数の求め方は、上と同様に計算して得られます。

Casio Python のスクリプトファイルは、以前の記事で 300行が上限だと確認しています。
リスト increment[ ] の定義以外に103行使っているので、リスト定義を 196行以内に納める必要があります。
そこで、1行あたり30個の要素を並べることにすれば、要素の記述に192行必要となり、スクリプト全体で 295 行とぎりぎり収まります。

2, 3, 5, 7, 11, 13 のいずれかの倍数でない探索数の増分リストを出力するたツール SearchNum13.exe も作りました。アルゴリズムは SearchNum11.exe と同じで、要素数を増やしているだけです。
要素数 5760 の探索数増分リストの要素を出力するWindowsデスクトップアプリ
 - SearchNum13 のダウンロード


これを起動したところ;
SearchNum13_1

右上の [Calculate] ボタンをクリックすると、求める要素とコンマ , が出力されます。
SearchNum13_result

1行30要素で192行となるように出力されます。コピー&ペーストでエディタで追加すると楽です、というか唯一の現実的な方法ですね!

さて、5760個の整数リストはかなりメモリを使うので、Casio Python で使えるかどうかを調べます。

要素数 5760 個のリスト
n=5760; s=0
lst = list(range(n))
for i in range(n):
 s+=lst[i]
print(len(lst))
print(s)

を実行すると、
5760
16585920
と出力され、0 + 1 + 2 + ・・・ + 5758 + 5769 = 16585920 と、正しい計算結果になります。正解は、(0+5760)×5760/2 で簡単に検算できます。これにより、整数の要素数 5760 個に拡張しても、整数リストは問題無く動作することは確認できました。

5760個の整数リストが使えることが分かったので、実際にコピー&ペーストしてスクリプトを作りました。

高速素因数分解:15桁入力対応、さらに探索数拡張版 - FactorG6.py のダウンロード

これを実行すると、以下のようなエラーが表示されます。
Stack_Error 

エラーメッセージ:RuntimeError: pystack exhausted

Casio Python が動作する際に確保するスタックを使い果たした、という意味だと考えられます。

制御構造は、FactorG5.py と同じなので、構造制御のために使うスタック数は同じです。すると、スタックを使い果たすのは、長大なリストが原因になっている筈です。

スタックがどのように使われているのかは不明ですが、リスト increment[ ] の定義で使っている改行がスタックを増やしているかも知れないと考え、1行の文字数を長くして行数を減らし、何通りか試してみました。

すると、実行すると Invalid Data size エラー発生して実行出来ないケースと RuntimeError: pystack exhausted エラーが発生して実行できないケースの両方があることが分かりました。

Invalid Data size エラーが発生する時のスクリプトファイルサイズは、pystack exhausted エラーの時のファイルサイズよりも大きくなっています。Invalid Data size エラーが発生する条件が、必ずしもファイルサイズが大きいだけでもないことも分かりました。

今回は、アルゴリズムの要請から極端に大きな要素数のリストを使う事例となり、その結果エラーに阻まれて、探索数をさらに拡張できませんでした。Casio Python では、スクリプトファイルサイズの制限が厳しいことも判りました。


何かお気づきの方は、コメント欄に情報をお寄せください。



目 次

前の記事 - 11. 関数のオーバーヘッド

次の記事 - 13. 10進数除算の出力と精度





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


 


keywords: fx-CG50Pythonfx-9750GIIIfx-9860GIIIプログラム関数電卓

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

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

Casio Python - 大きな数の計算:高速素因数分解(3)

Python Casio Python
 Casioグラフ関数電卓の Python を使ってみる
     - 大きな数の計算:高速素因数分解(3) 
目次


初版:2020/07/28
追記修正:202011/14

前の記事 - 9. Python らしい反復処理 |  次の記事 - 11. 関数呼出オーバーヘッド


10. 大きな数の計算:高速素因数分解(3)

今回は、Casio Python では、より大きな桁数の整数で精度を確保できることを紹介し、15桁入力に対応した高速素因数分解スクリプトに改造します。

前回までに作った高速素因数分解スクリプトは、オリジナルの Casio Basic プログラムから移植したものなので、入力値の桁数はオリジナルと同じように10桁が上限になっています。

Casio Basic は仕様上10進数10桁を超えると計算精度の保証がないので、入力値は最大10桁に制限されます。一方、Casio Python では10進数10桁を超えても精度が確保されます。


例えば、15桁の入力を2で除算してみます。
999,999,999,999,999,999 / 2 = 49,999,999,999,999.8
15digit 

入力15桁に対して、1桁多い16桁で出力されます。
正解は 499999999999999.5 なので、16桁の最下位に誤差が発生しています。


次に、16桁の入力を2で除算してみます。
9,999,999,999,999,999,999 / 2 = 50,000,000,000,000.0
16digit 

16桁の入力に対して、出力は1桁多い17桁になっています。
奇数を2で除算して整数になることから、少なくとも16桁の入力では、計算精度に問題があることが分かります。

続いて、1/3 の計算結果は、出力16 桁になります。
digit_one_third_shell 

円周率 pi も 16桁出力になります。
digit_pi_shell 

Casio Python での浮動小数点計算は、10進数15桁以内の入力なら、計算結果は15桁の精度が確保できるようです。

そこで、高速素因数分解の入力値の桁数を 10 桁から 15 桁に拡張することにします。


10.1 変更箇所の洗い出し

前回作った高速素因数分解 - 10桁対応版:FactorG2.py のダウンロード

15桁対応にするために、前回作った下記のスクリプトに対して、下記の2項目を変更します。

(1) 増加する素因数に合わせて表示行数を拡張する - disp() の変更
(2) 入力桁数の制限を拡張し、それに合わせてエラー表示を変更する


これら2つの項目に対応して変更箇所を以下に赤文字で示します。

fx-CG50 Pythonモード:高速素因数分解 - FactorG2.py
"""Sample script

 Exercise;
 ported from Casio Basic
 "Prime Factor 10 digits"
  FactorG.py
   ver 2.0

 by Krtyski/e-Gadget
"""

from u import *

def ckpwr():
 global a,b,c,d,e,z
 e+=1
 z[e]=b
 while 1:
  a=int(d)
  z[e+11]+=1
  d=a/b
  if frac(d):
   break
 c=int(sqrt(a))

def
disp():
 global a,e,f,z
 clear_screen()
 locate(00f3'm'0)
 locate(160': ' str(len(inp)) + ' digits'3'm'0)
 line(0,15,383,15,1,0)
 for i in range(112):  ◀ (1) 増加する素因数に対応して、表示行数を拡張する
  if i<=e:
   locate(,,z[i], 1'm'0)
   locate(10i'^('2'm'0)
   locate(12iz[i+21], 1'm'0)
   locate(15i')'2'm'0)
 locate
(00''0'm'1)


while
1:
 try:
  inp=str(eval(input('Number:')))
 except (SyntaxError,TypeError,NameError) as e:
  print(e)
  print('*must be number or\n expression')
  continue
 if '.' in inp:
  print('*must be integer')
  continue
 elif inp.isdigit():
  if len(inp)>10:    ◀ (2) 桁数制限を拡張する
   print('*must be 10 or less') ◀ (2) 拡張した桁数制限に合わせて変更
   continue
  else:
   f=int(inp)
   break
 else:
  continue

z=list(range(23))
for e in range(1,23):
 z[e]=0
e=0
a=f
c=int(sqrt(a))

prime_list=[2,3,5,7,11]
for b in prime_list:
 d=a/b
 if frac(d)==0ck_pwr()
 if b>c: break


increment=\
[2,4,2,4,6,2,6,4,
 2,4,6,6,2,6,4,2,
 6,4,6,8,4,2,4,2,
 4,8,6,4,6,2,4,6,
 2,6,6,4,2,4,6,2,
 6,4,2,4,2,10,2,10]

while 1:
 for i in increment:
  b+=id=a/b
  if frac(d)==0ck_pwr()
  if b>cbreak
 if b>c
break

if a>1:
 e+=1
 z[e]=a
 a=1
 z[e+11]=
1

disp
()



10.2 増加する素因数に合わせて表示行数を拡張する - disp() の変更

素数の積を調べてみます。

2から41までの素数の積;
2*3*5*7*11*13*17*19*23*29*31*37*41 = 304,250,263,527,210
15桁になります。

2から43までの素数の積;
2*3*5*7*11*17*19*23*29*31*37*41*43 = 21,306,211,311,576,906
17桁になります。

これらから、素数13個で15桁になることが確認でき、乗数を含めて出力には最大 13行必要になります。

前回作った disp() を示します。

def disp():
 global a,e,f,z
 clear_screen()
 locate(00f3'm'0)
 locate(160': ' str(len(inp)) + ' digits'3'm'0)
 line(0,15,383,15,1,0)
 for i in range(112):  ◀ (1) 増加する素因数に対応して、表示行数を拡張する
  if i<=e:
   locate(,,z[i], 1'm'0)
   locate(10i'^('2'm'0)
   locate(12iz[i+21], 1'm'0)
   locate(15i')'2'm'0)
 locate
(00''0'm'1)


Ver2_10lines1 

1画面あたり、素因数は11個まで表示できるので、for i in range(12): としました。
これを13行まで拡張するためには、以下のように2列にして13行まで表示できるように変更します。

13lines 

従って、反復処理の for 文は、for i in range(14): で良いですが、1行余裕をみて

for i in range(15):

としておきます。しかし、これだけでは、12行目 と 13行目 は、右側に表示されないので、4行ある locate() の引数を適切に変更してゆきます。
 
i の値が 12 未満では左側に表示、12 以上の場合は右側に表示すれば良いですね。
そこで、if i <12: / else: と場合分けをする方法もあるでしょうが、もう少しスッキリと簡潔に記述するために、locate() で指定する 桁数と行数の増分 dxdyi の値に応じて計算で求める方式を考えました。
 dx=int(i/12)*16  i<12 のとき dx=0i≧12 のとき dx=16
 dy=int(i/12)*11
  i<12 のとき dy=0i≧12 のとき dy=11

これを使って、スクリプトを以下のように変更しました。

def disp():
 global a,e,f,z
 clear_screen()
 locate(00f3'm'0)
 locate(160': ' str(len(inp)) + ' digits'3'm'0)
 line(0153831510)
 for i in range(115):  ◀ 変更部分
  if i<=e:
   dx=int(i/12)*16  ◀ 追加部分: i < 12 のとき dx=0、i ≧ 12 のとき dx=16
   dy=int(i/12)*11    ◀ 追加部分: i < 12 のとき dy=0、i ≧ 12 のとき dy=11
   locate(0+dxi-dyz[i], 1'm'0)    ◀ 第1引数に +dx を、第2引数に -dy を追加 
   locate(10+dxi-dy'^('2'm'0)    ◀ 第1引数に +dx を、第2引数に -dy を追加
   locate(12+dxi-dyz[i+21], 1'm'0) ◀ 第1引数に +dx を、第2引数に -dy を追加
   locate(15+dxi-dy')'2'm'0)    ◀ 第1引数に +dx を、第2引数に -dy を追加 
 locate
(00''0'm'1)


他にもスッキリと記述する方法があると思いますが、これで進めます。


10.3 入力桁数の制限を拡張し、それに合わせてエラー表示を変更する

前回までに作った "入力と入力チェックの記述" を以下に示し、今回変更する部分を赤文字で示します。

while 1:
 try:
  inp str(eval(input('Number:')))
 except (SyntaxErrorTypeErrorNameError) as e:
  print(e)
  print('*must be number or\n expression')
  continue
 if '.' in inp:
  print('*must be integer')
  continue
 elif inp.isdigit():
  if len(inp)>10:    ◀ (2) 桁数制限を拡張する
   print('*must be 10 or less') ◀ (2) 拡張した桁数制限に合わせて変更
   continue
  else:
   f int(inp)
   break
 else:
  continue

ここで、赤文字で追記している2箇所は、10 を 15 に変更すればOKです。

今回は、変数 digit を使って、これに 15 を代入して使うことにします。

digit=15

をスクリプトの冒頭に書いておけば、代入する数値を書き換えるだけで入力桁数の制限を簡単に変更できます。

そこで、上記2箇所は、以下のように変更します。

if ken(inp) > digit:
 print('*must be '+str(digit)+' digit\n or less')

 continue

出力文字列に エスケープシーケンス \n (バックスラッシn) による改行を入れているので、狭い画面の電卓で以下のように見やすくなります。
*must be 15
 or less



入力と入力チェック部分は、まとめると以下のようになります。

digit=15

・・・
・・・

while
1:
 try:
  inp str(eval(input('Number:')))
 except (SyntaxErrorTypeErrorNameError) as e:
  print(e)
  print('*must be number or\n expression')
  continue
 if '.' in inp:
  print('*must be integer')
  continue
 elif inp.isdigit():
  if len(inp)>digit:
   print('*must be '+str(digit)+' digit\n or less')
   continue
  else:
   f int(inp)
   break
 else:
  continue


10.4 素因数探索回数の表示を追加する

ここまで作ったスクリプトを実際に以下の2通りの入力値で走らせてみると、実行時間が大きく異なります。

NoSearch_ver3_fast_14digits NoSearch_ver3_slow_13digits 

左の14桁に比べて、右の13桁は、桁数が1つ少ないにもかかわらず、かなり時間がかかります。
素因数の桁数が大きいほど時間がかかると考えれば、素因数探索の while ループを回る回数が大きいほど時間がかかると理解できます。

そこで、実際に素因数探索の回数をカウントして、以下のように表示しようと思います。

Search_ver3_fast_14digits Search_ver3_slow_13digits 

search は探索回数です。

変数 search の初期化
スクリプト冒頭の digit=15 の直後に search=0 を追加し、変数 search を探索回数とします。

from u import *
digit=
15
search=0


 変数 search のカウントアップ
変数 search をカウントアップ (serch+=1) するのは、以下の赤文字で示した 2 箇所になります。

prime_list=[2,3,5,7,11]
for b in prime_list:
 search+=1    ◀ ここで search をカウントアップ
 d=a/b
 if frac(d)==0ck_pwr()
 if b>c: break


increment=\
[2,4,2,4,6,2,6,4,
 2,4,6,6,2,6,4,2,
 6,4,6,8,4,2,4,2,
 4,8,6,4,6,2,4,6,
 2,6,6,4,2,4,6,2,
 6,4,2,4,2,10,2,10]

while 1:
 for i in increment:
  search+=1   ◀ ここで search をカウントアップ
  b+=id=a/b
  if frac(d)==0ck_pwr()
  if b>cbreak
 if b>c
break



変数 search の表示
カウントアップした search の表示は、disp() 関数の内で、以下の赤文字で示したようにします。

def disp():
 global a,e,f,z
 clear_screen()
 locate(00f3'm'0)
 locate(160': ' str(len(inp)) + ' digits'3'm'0)
 locate(16, 11, 'search:'+str(search), 2, 'm', 0)   ◀ search の表示
 line(0,15,383,15,1,0)
 for i in range(115):
  if i<=e:
   dx=int(i/12)*16
   dy=int(i/12)*11
   locate(0+dxi-dyz[i], 1'm'0)
   locate(10+dxi-dy'^('2'm'0)
   locate(12+dxi-dyz[i+21], 1'm'0)
   locate(15+dxi-dy')'2'm'0)
 locate
(00''0'm'1)



10.5 素因数が10桁を超えるときの表示の変更 - disp() の変更

入力桁数を15桁まで拡張したので、見つかった素因数が10桁を超えることがあります。
例えば、以下のようなケースです。

11digit_prime 

4つめの素因数 58402449151 (11桁) が、乗数表示 ^(1 ) の表示と被ってしまっています。
これでは、ちょっと格好悪いので、素因数が10桁を超えた時は、超えた桁数に応じて乗数表示を右に移動して、被らないようにします。

disp() 関数内では、素因数は z[i] なので、素因数の桁数は、len(str(z[i])) で分かります。
この桁数が 10 を超えるとき、その超過分は len(str(z[i])) - 10 で求められます。これを変数 r に代入しておきます。

この r を使えば、乗数表示にかかわる locate() の第1引数に r を加えれば、被らなくなりなります。

この変更を行った disp() 関数は以下のようになります。変更部分は赤文字で示します。

def
disp():
 global a,e,f,z
 clear_screen()
 locate(00f3'm'0)
 locate(160': ' str(len(inp)) + ' digits'3'm'0)
 line(0,15,383,15,1,0)
 for i in range(115):
  if i<=e:
   r=0
   if len(str(z[i]))>10:
    r=len(str(z[i]))-10
   dx=int(i/12)*16
   dy=int(i/12)*11
   locate(0+dxi-dyz[i], 1'm'0)
   locate(10+dx+ri-dy'^('2'm'0)    ◀ 第1引数に r を加算する
   locate(12+dx+ri-dyz[i+21], 1'm'0)   ◀ 第1引数に r を加算する
   locate(15+dx+ri-dy')'2'm'0)     ◀ 第1引数に r を加算する
 locate
(00''0'm'1)



変更したスクリプトで、上記の "被ってしまった" ケースを入力すると、以下のように改善されたことが分かります。
Case1_14digit 


別のケースとして、素因数が15桁になるときは、以下のように乗数表示は17桁めに移動して、被りません。
15digit_prime 

なお、このケースでは、探索回数 search が、なんと434万回を超えています。

==========

以上で、15桁入力への拡張版が完成です。

※ 高速素因数分解 15桁入力対応版 - FactorG3.py のダウンロード

fx-CG50 Pythonモード:高速素因数分解 - FactorG3.py
"""Sample script

Exercise;
ported from Casio Basic
"Prime Factor 10 digits"
factorG.py
ver 3.0

by Krtyski/e-Gadget
"""

from u import *
digit=
15
search=0

def ckpwr():
 global a,b,c,d,e,z
 e+=1
 z[e]=b
 while 1:
  a=int(d)
  z[e+11]+=1
  d=a/b
  if frac(d):
   break
 c=int(sqrt(a))

def
disp():
 global a,e,f,z
 clear_screen()
 locate(00f3'm'0)
 locate(160': ' str(len(inp)) + ' digits'3'm'0)
 locate(16, 11, 'search:'+str(search), 2, 'm', 0)
 line(0,15,383,15,1,0)
 for i in range(115):
  if i<=e:
   dx=int(i/12)*16
   dy=int(i/12)*11
   locate(0+dxi-dyz[i], 1'm'0)
   locate(10+dxi-dy'^('2'm'0)
   locate(12+dxi-dyz[i+21], 1'm'0)
   locate(15+dxi-dy')'2'm'0)
 locate
(00''0'm'1)


while
1:
 try:
  inp=str(eval(input('Number:')))
 except (SyntaxError,TypeError,NameError) as e:
  print(e)
  print('*must be number or\n expression')
  continue
 if '.' in inp:
  print('*must be integer')
  continue
 elif inp.isdigit():
  if len(inp)>digit:
   print('*must be '+str(digit)+' digit\n or less')
   continue
  else:
   f=int(inp)
   break
 else:
  continue

z=list(range(23))
for e in range(1,23):
 z[e]=0
e=0
a=f
c=int(sqrt(a))

prime_list=[2,3,5,7,11]
for b in prime_list:
 search+=1
 d=a/b
 if frac(d)==0ck_pwr()
 if b>c: break


increment=\
[2,4,2,4,6,2,6,4,\
 2,4,6,6,2,6,4,2,\
 6,4,6,8,4,2,4,2,\
 4,8,6,4,6,2,4,6,\
 2,6,6,4,2,4,6,2,\
 6,4,2,4,2,10,2,10]

while 1:
 for i in increment:
  search+=1
  b+=id=a/b
  if frac(d)==0ck_pwr()
  if b>cbreak
 if b>c
break

if a>1:
 e+=1
 z[e]=a
 a=1
 z[e+11]=
1

disp
()






目 次

前の記事 - 9. Python らしい反復処理

次の記事 - 11. 関数呼出オーバーヘッド





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


 


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

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

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

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

やす (Krtyski)

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


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

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

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


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

リンク
月別アーカイブ
Sitemap

全ての記事を表示する

ブロとも申請フォーム

この人とブロともになる

QRコード
QR