PythonではTcl/tkをインストールすると
■ Turtle
■ Tkinter
が使用できるようになりますが、この中のturtleがLOGOのように図形を描くモジュールになっています。
どのプログラミング言語も共通して
■ CUIがメイン
■ GUIは追加機能
になっているのでコードをそのまま書くとテキストの表示しかできないターミナル上で動くものしか作れません。
この処理の方法は
【 制御部分の理解をするために必要なこと 】
になりますが、表示とその制御は別のものになりますから、表示とデータの連動を簡素化した状態で動きの部分を作ろうと思うと、コンソールのように簡単に表示が行えて簡単に動くものが必要になります。
そのため、プログラミング言語ではターミナル上で動くものからスタートすることになります。
また、プログラミング言語は、
■ サーバー
■ マイコン
のようにUI部分を必要としない処理でも使用することになりますから、このような事例ではテキスト部分だけが必要なので、テストにおいてもコンソールで確認できるようなものを使用します。
マイコンの場合だとデバイスの挙動で確認することになりますが、この場合、処理によってデバイスの入出力で表示と操作や検知を実装することになるので、GUIを使用した処理を使用する場合には表示の前にLCDやOLEDなどの制御をすることになります。
このように処理によってはターミナルでデータの変化を見るだけになるものも存在するので、基本となるのはCUIになります。
入門用のプログラミング言語にはScratchのようにブロックを使用したものもありますが、こうしたプログラミング言語では、GUIを使用することでタイピングの負荷を少なくした構造になっていますが、こうしたプログラミング言語は処理の上に処理が乗っているので、開発環境というよりもアプリケーションのような作りになっています。そのため、動きを考えて実装するという
【 アルゴリズムの実装の基礎 】
は学習できますが、複雑な処理を行う際に発生する
■ メモリー管理
■ 並列処理
■ 並行処理
■ 非同期処理
などが存在しなかったり、オブジェクト指向の処理の実装ができない使用になっています。
と言っても、Scratch3では、
■ 関数
■ ローカル変数とグローバル変数
■ 処理単位の役割分担
ができるので、設計を行う段階で必要となる考え方は身につくようになっていますが、これに加えてGUIでの制御をする際にどうするればいいのか?という考え方も身につく使用になっています。
Pythonのturtleの場合、tkのインストールがされていなければ動作しないので、事前にインストールをしておく必要があります。
WINDOWS環境では、インストーラーを使用する際に
【 ウィジェット環境の追加 】
■ Tcl/tkのインストール
【 統合開発環境の追加 】
■ IDLEのインストール
【 プログラム名だけで実行する 】
■ 環境変数の設定
があるので、新規にインストールをする場合には、この3つにチェックを入れておく必要があります。
LinuxやMACの場合は、tkのインストールを手動で行う必要がありますが、Linuxの場合だと、ターミナルを開いて
$ wish
のようにwishのインストールの有無の確認をします。wishはシェルの一種でGUIを使用する際にTcl/tkを使用しています。そのため、PCにwishがインストールされている場合だと、wishを呼び出すだけでウィジェットが表示されます。
インストールされていない環境下ではエラーが出るので、Linuxだとapt-insutallを使用してインストールを行うことになります。
tkがインストールされると、ターミナル上で
> python3
と入力してPython 3.x系を立ち上げ、その後
>>> import turtle
の入力してもエラーが出ずにプロンプトが表示されます。これと同様に、tkinterもtk依存のモジュールなので、tkがインストールされている環境下だと、
>>> import tkinter
と入力してもエラーになることはありません。
ウィジェット環境の構築を行う場合、このような依存関係の解消を行う必要がありますが、WIDNOWS環境の場合だと、こうした問題をインストーラーでのインストール段階で解消できるようになっていますが、Linuxのように
■ Pythonは標準実装
■ tkが使えない
という状態になっているものもありますから、この場合には、別途シェルコマンドを使用してインストールを行うことになります。
turtle
turtleは、
import turtle
で読み込めるようになりますが、すべてのメソッドを使用する場合には、【 from 〜 import 〜 】 を使用します。
ただし、条件によってはこの方法を使うと問題がある場合もあるので、個別のものを呼び出して弊害をなくすためには、
import turtle as 略称
のような形で宣言します。プログラミング言語には記述を省略できる便利な機能がありますが、弊害が出る場合もあるので、別の方法を持ちることもあります。例えば、C++のネームスペースを扱う場合もそうですが、C++では
std::cout
std::cin
のような処理がありますが、この処理では、stdというネームスペースが使用されています。これを省略する際にusingを使用しますが、これだと同じ名称のものが登場した際に区別がつかなくなります。その為、別の宣言の方法で略称を使用するという方法を用いる記述を行います。
Pythonでは
■ 組み込み関数
■ 標準ライブラリ
が存在しており、組み込み関数についてはモジュールの呼び出しだけで動作しますが、標準ライブラリを使用する際には、import を使用して呼び出すことになります。
turtleを動かす
turtleを動かす場合、そのまま動きだけを指定しても動作するので、
■ forward()
前に進む
■ back()
後ろに下がる
■ left()
左に旋回
■ right()
右に旋回
の指定ができます。これは英単語と全く同じ挙動をしていますが、
■ 左 : left
■ 右 : right
については、移動ではなく軸回転になっているので注意が必要です。動きだけを記述すると、
のような形になりますが、基本となるのは
【 処理の追加 】
になります。そのため、最初に何を行って、そこからどのように動くのかを指定します。
この場合だと、
■ 移動
■ 角度指定
を繰り返していますが、この処理は、
■ 角度指定
■ 移動
のようにすることもできます。こうすると、
■ 30度回転
■ 100進む
のような指定ができるようになります。最初に移動した場合、最初の辺を基準として移動ルートを決めることになりますが、角度を先に指定すると基準となる辺の角度の指定をすることができます。
これと同じことはScratchでも行えるので
のように部類バージョンでも
のようにブロックを並べて動かすこともできますが、古いバージョンでもペンツールは存在しているので、
のようにペンでラインを引くこともできます。
Scratchでは、ウインドウを部分的に表示するモードと全画面モードがありますが、通常のプログラミング言語にはそういった機能は存在しないので、ウィジェット環境を使用する際には、ウインドウのサイズを指定することになります。
ウインドウサイズ
tkinterを使う場合もウインドウサイズを指定しますが、この場合
■ ウインドウの指定
■ ループ
を一つのセットにして使用します。コンソールアプリを作る際に 【 ターミナルを立ち上げて実行する仕組み 】 にした場合、ループを行わない処理については処理が終わるとターミナルが閉じてしまうので、通常のアプリケーションのように常に表示が継続されるものを作る場合はループを入れることになります。
turtleの場合にも
■ ウインドウの指定
■ ループ
を行うことができるので、
【 ウインドウの指定 】
sc=Screen()
sc.setup(width=720,height=480)
【 ループ 】
sc.mainloop()
で指定することになります。この処理ですが、
最初にScreen()を変数に格納することで、これをオブジェクトにします。こうすることで、メソッドをこの対象物に実装できるようになるので、後に記述している
■ setup()
■ mainloop()
を付与することができます。このあたりは英文法の
■ 基本となる文章+in the 〇〇.
■ 基本となる文章+on the 〇〇.
のような作りと似ていますが、基本となる処理が存在していて、それに対して何を付与するのか?で処理の構造が成立しています。
プログラミング言語では変数に関数を格納して、その関数に対してメソッドを付与することもできるので、このような記述ができます。
また、クラスでは、インスタンスという変数の値を持った実態を構築してそれを元に処理をすることになりますが、クラスを用意してインスタンスを作成するとコンストラクタが実行されて
■ インスタンスの変数がインスタンス
変数に代入される
■ def __init__(self): 以降の処理が
インスタンス生成時に実行される
という処理が行われます。その後、そのインスタンス名を使って
■ インスタンス名.メソッド名()
のようにしてメソッドを呼び出すとクラス内に記述したメソッドを実行することができるようになっています。
クラスの場合、関数と同様に単独での動作を先に覚えたほうがいいのですが、関連付けをして動かすような仕組みもあるので、これを理解した上で設計をすることになります。
そのため、構造で分けて考える作り方で使用するフローチャートだとコードよりも上の部分の作業を表現することはできますが、肝心なクラス同士の関連付けについてはフローチャートを使うと扱いにくくなります。そのため、UMLで枠組みを決めて、その後にUMLのクラス図でコードの部分を考えていくことになります。
ここでもインスタンスに対して処理を付与するという形を使うので、
オブジェクト.メッソッド()
のような表記を扱うことになります。
これを踏まえて上記の内容を見てみると
■ 変数に関数を実装
■ 変数にメソッドを付与
という処理で構成されているわけですが、ウインドウの場合だと、setupが解像度を指定するときに使用するものになるので、
■ 横の解像度 : width
■ 縦の解像度 : heigh
を指定することになります。これらは、setupの引数になるので、()内に記述することになりますが、この時に数値でサイズの指定をすることになります。
ウインドウサイズの指定は 【 ピクセル 】 で指定することになるので、
【 縦横に何ドットのウインドウにするのか? 】
を指定することになります。プログラミング言語では、
【 数字の表記の場合 】
数字をそのまま記述して代入する
【 文字列の表記の場合 】
文字列を引用符で囲んで代入する
という使用になっています。これは変数を扱う場合も同じですが、
【 数字の代入 】
a=1
b=1.11
【 文字列 】
a="Hello,Linux"
b="Hello,Python"
のようになります。これはどのプログラミング言語でも共通していますが、ウィジェットで使用する
■ 幅 : width
■ 高さ : height
の表記も共通しているので、HTMLでサイズの指定をする際にも使用します。
ウインドウのサイズを720x480に指定する場合だと、
setup(width=720,height=480)
のようになりますが、これは要素なので、対象となるスクリーンに適応するので、
sc=Screen()
の記述で変数にScreen()を代入し、
setup(width=720,height=480)
のようなサイズの情報を付与することになるので、
sc.setup(width=720,height=480)
のような記述になります。そして、これをループさせるので、スクリーンに対して、
mainloop()
を追加することになりますから、
sc.mainloop()
をコードの末尾に追加することになります。
このようにturtleでは、
■ モジュールのインポート
■ ウインドウの指定
■ ループの実装
という3つの処理を最初に実装することになるので、
from turtle import *
sc=Screen()
sc.setup(width=720,height=480)
(この部分に処理を書く)
sc.mainloop()
のようなテンプレートを用意してから処理を実装することになります。また、loopとは別にdoneの指定をすることもできます。
先程の処理を実装すると
のようになりますが、これを実行すると
のようになります。処理の基本は、順次なので、工程表のように並べてもいいのですが、これは足し算と同じなので、同じ処理の繰り返しだと掛け算にすることができます。小学校二年生の算数では、
1+1+1+1=1×4
のような計算方法を学習しますが、この応用で
1+2+1+2+1+2+1+2
=4×(1+2)
のようにまとめることもできます。この構造を見ると、
■ ループ回数
■ 処理
の構造と全く同じになっていますが、上記の構造だと
【 実際の実行手順 】
1+2+1+2+1+2+1+2
【 処理の実装 】
4×(1+2)
のように考えることができます。この構造を拡張すると、
【 問題 】
🍎 = 3個
🍊 = 5個
🍌 = 2本
を箱詰めして1つのセット商品を作った時に、4箱の注文が入りました。
この箱詰めをするにはどのような手順で行えばいいでしょうか?
という考え方と同じなので、
🍎×3+🍊×5+🍌×2
という処理を4箱分ですから、
4×(🍎×3+🍊×5+🍌×2)
のようになります。この場合、箱詰めの作業を4回行っているのと同じなので、掛け算はループ処理と考えることができるわけです。というのも
■ 🍎×3 = 🍎+🍎+🍎
■ 🍊×5 = 🍊+🍊+🍊+🍊+🍊
■ 🍌×2 = 🍌+🍌
ですから、追加をループで行っているものになります。ただし、+nという形にした場合だと、
【 0+nを指定回数回分ループする 】
ということになりますから、個数のカウントだと掛け算の数値はそのまま個数ということになりますが、
■ 🍎×3 = 0+🍎+🍎+🍎
■ 🍊×5 = 0+🍊+🍊+🍊+🍊+🍊
■ 🍌×2 = 0+🍌+🍌
とすると、
■ +🍎を3回ループ
■ +🍊を5回ループ
■ +🍌を2回ループ
と考えることができるわけです。また、上記のセットに
1パック15個の🍓を2パック追加する
という状態になると、
🍎×3+🍊×5+🍌×2
(🍓×15)×2
となりますから、これを全て足すことになります。そのため、
🍎×3+🍊×5+🍌×2+(🍓×15)×2
のようなこのが出来上がります。この場合、🍓の数だけ多重に掛け算が行われているので、
🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓
🍓🍓🍓🍓🍓
🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓
🍓🍓🍓🍓🍓
の構造になっているので、これは、他の果物とは別に先に用意しておく必要があります。そのため、掛け算は先に行うことになりますが、上記のものの対象物を除去して数値のみの数式に置き換えると、
3+5+2+15×2
となります。当然、先程のものと構造は同じなので、
3+5+2+(15×2)
になりますから、
10+30=40
となります。これを足し算のように左から順番に計算すると
3+5+2+15×2
25×2=50
となります。20世紀の電卓は、乗除算を優先して計算するような作りになっていないので、四則演算を行うとこのような結果になってしまうので、 【 算数がわかっていない状態で電卓を使うと取り返しのつかない計算間違いをすることになる 】 わけですが、割り算も 【 逆数の乗算処理 】 なので、加減算とは全く異なる仕組みになっています。
そのため、四則演算だと乗除算を先に行うことになりますが、この仕組みは、中学校一年生の項のカリキュラムで多項式ノカタチで処理をする方法を学ぶので必然的に乗除算は加算とは異なるものであり、減算は符号なので、加算のような前後の後の入れ替えができないことについても構造として理解をすることができるようになっています。
先程のコードは、4(1+2)のような構造と同じなので、
のように書き換えることができますが、処理自体は同じなので、
のようになります。コードを書く場合には、処理の流れを考えることになりますが、この際に
■ 確実に意図した処理になること
■ 実行後に必ず完結すること
という2つの条件は満たしておく必要があります。
この条件で動くものを永続的に動かす場合には、無限ループの中にアルゴリズムを実装すればいいだけなので、必要となるのは、 【 挙動に至る工程や処理の流れ 】 になります。
そのため、小学校低学年のカリキュラムで考えると、算数の計算を数字ではなくて処理で考えると、
■ 足し算 : 順番に処理を行う
■ 掛け算 : 繰り返して行う
という考え方になります。小学校の算数だと
■ 足し算 : 増える
■ 掛け算 : 同じ数を足す
(全体の個数を計算する)
時に使用できますが、処理で考えると、
■ 足し算 : 順次や逐次処理
■ 掛け算 : ループ処理
になります。そのため、
■ 処理1
■ 処理2
が存在した場合だと、プログラミング言語では戦闘から末尾に向かって処理が実行されるので、
■ 処理1 + 処理2
のような流れになりますが、この処理を繰り返して行う場合には、
■ ループ回数(処理1+処理2)
のような構造になります。算数では使いませんが、
処理A = 4回(処理1+処理2)
処理B = 2回(処理3+処理4)
のようにして、これを
処理A+処理B
のようにして実行すると、
処理1+処理2
処理1+処理2
処理1+処理2
処理1+処理2
処理3+処理4
処理3+処理4
のような流れを実装することができます。この考え方は、処理を行う部品を事前に作って直列回路にしたような構造なので、上記のような処理になりますが、
■ モジュール1 : 処理A
■ モジュール2 : 処理B
のように処理を行うモジュールを作って、それを直列回路で並べて実行すると上記のような処理になります。
この条件で考えると、処理1〜処理4というのは、モジュールを作るパーツということになりますが、この構造を物体ではなく記号や数字で示して思考を行いやすくしたものが数学の代数学の分野になります。
算数では、
数式 = 答え
という形にできますが、中学校の数学では、
変数項 = 変数を用いた式
という構造を作ることができることを学習します。この構造物が 【 関数 】 になりますが、式の形で先程のモジュールを用いた回路と処理の結果を示すと
結果 = 処理A+処理B
のようになります。この形状は
結果という変数 = 変数化した数式
として考えることができるので、結果と数式が一致すればどのような形にもすることができます。上記の式でも結構複雑な処理になっていますが、これもループに包含することができるので、
結果 = 5(処理A+処理B)
のようなこともできますし、
結果 = 5(処理A)+6(処理B)
のようにモジュールの実装されている処理をループで反復することもできます。この構造にするとループをループで包含しているので三次元配列のような値の変化をしていることになりますが、数式を代数学ではなく解析学の分野で使用するグラフに持ってくると
■ 加算 : 一次元
■ 乗算 : 二次元
■ 累乗 : 三次元
で示すことがでます。数字の値は一次元の距離の変化ですから、データの範囲を不等式で示した場合には線分が発生します。
掛け算はこの値を指定した数分だけ追加するので、データの範囲で示すと二次元のデータを持つ範囲が生じるので、この状態で示すことができるのは面になります。
そして、累乗は
■ X=N(0〜N)
■ Y=N(0〜N)
■ Z=N(0〜N)
という条件での変化ですから、座標データではなく、データの総数を不等式で示すと立方体が完成します。この構造は定数で値を指定した時の多重ループによる処理と考えることができますが、台数がKづえ使用する際には一つの状態として考えるので、 【 位置情報のように一つのデータ 】 として扱うことになります。そのため、
■ 等 式 : 座標が発生する
■ 不等式 : 範囲が発生する
という特徴があるので、この条件でデータの状態を確認することになります。そのため、
■ 座標 : 位置情報(点)
■ 範囲 : 区間(始点〜終点)
を取得する場合にはそれぞれ等式と不等式を使い分けて使用することになります。
判定の方法
これは、【 1つの条件とその結果 】 を求める時のものになりますが、複数の条件から結果を抽出する場合には異なる処理が必要になります。これは、義務教育で仕組みを学ぶことはありませんが、高校の数学Cで学習する集合と論理を用いるとそういった判定を行うことができます。
ただし、小学校の直流と交流のカリキュラムで
■ 直流 : 論理積(∧)
■ 交流 : 論理和(∨)
のような挙動を
■ 電池の有無
■ 豆電球の店頭の有無
の関係性を図示すると上記の論理ゲートの真理値表と全く同じものが出来上がるので、これらは
■ 論理積(∧)
複数の条件が一致しないと成立しない
(全て外一致いないと不成立)
■ 論理和(∨)
どれかが真であれば、成立する
(1つでも真であれば成立)
という条件ですから、これを使うだけでも等式不等式だけでは判断できないものを処理できるようになります。
日常でも 【 〇〇以上、▲▲未満 】 という判定の場合だと、
〇〇以上 ∩ ▲▲未満
という判定になります。この条件は
■ 〇〇以上 ∈ 全体の総数
■ ▲▲未満 ∈ 全体の総数
という条件ですから、全体から条件として存在するものを抽出したものになります。つまり、これらの条件は部分集合ということになります。
この部分集合同士を組み合わせて使用する際には、積集合
をかければいいので、前述のような
〇〇以上 ∩ ▲▲未満
の形になります。論理の場合は、結果が二値で表現できるものに限定されるので、
■ 〇〇の成立 : True
■ ▲▲の成立 : True
のような条件が存在した場合に
〇〇の成立 ∧ ▲▲の成立
のようになります。この組み合わせが
〇〇の不成立 ∧ ▲▲の不成立
〇〇の不成立 ∧ ▲▲の成立
〇〇の成立 ∧ ▲▲の不成立
〇〇の成立 ∧ ▲▲の成立
のような条件が生じますが、この時に、
× 〇〇の不成立 ∧ ▲▲の不成立
× 〇〇の不成立 ∧ ▲▲の成立
× 〇〇の成立 ∧ ▲▲の不成立
◎ 〇〇の成立 ∧ ▲▲の成立
のような条件が成立します。論理和の場合だと、
× 〇〇の不成立 ∨ ▲▲の不成立
◎ 〇〇の不成立 ∨ ▲▲の成立
◎ 〇〇の成立 ∨ ▲▲の不成立
◎ 〇〇の成立 ∨ ▲▲の成立
のようになるので、2入力の場合だと、片方が真であれば、条件が成立することになります。そのため、これは両方も含まれるので、 【 二者択一とは異なる 】 わけですが、二者択一の選択と同じものは排他論理和(XOR)になります。
こうした処理は 【 判定 】 で使用しますが、プログラミング言語では、こうした判定を行う際に if を使用します。その時に、
■ 等式・不等式
■ 論理演算
を使用して、
■ 単数の判定
■ 複数の判定の組み合わせ
を使用することになりますが、この時に変数の値を条件として使用することになります。