先日は、
にて、while文によるループについて書きました。while文は指定した条件で動作する仕様になっているので、if文での判定に対してループを行うような仕様になっています。
その為、条件の統合(==)や不等号(!=)などでも判定ができますし、比較演算子などを用いることもできます。それより、条件にあった場合だけループ内の処理を実行し、条件と一致していない場合、whileのループ内の処理が実行されず、その後の処理が実行されます。
whileは 【 反復 】 で、ループ外の処理は上から順番に実行されるので 【 順次 】 二なりますが、これに 【 分岐 】 を加えたものでプログラムは構成されていますが、whileのループ内の処理は順次なので、最初の二つが実装されていることになります。
ループの場合、ループさせるだけでなく、ループから抜ける為の処理も実装する必要がありますが、Pythonでは、break文でループを中断できるので、実行したループを終了する事ができます。
これは、if文で実行するのですが、if節の中に条件を記述してbreak文を実行する事になります。
break文はその条件になると強制的にループを中断できるので、
【 while ture: 】
のように永続したループ処理からの抜け出す事ができます。それとは別に、ループには、continue文があります。これもif文を用いて、if節に条件式を記述して、その後、continue文を実行する事になります。
これは、特定の条件で、continue文以降の処理を行わずにwhile節の先頭に戻るので、入力待ちで誤った入力がある場合に、エラーメッセージを出して戻るような処理を入れる場合に、continue文の判定用のif節に処理を実装して、その後、continue文でwhile節の先頭に戻るような仕様になります。
先日は、ループ処理について書いたのですが、今回は、関数について書こうかなと思います。
関 数
関数については、以前、
■ 判断と動きに使う処理(if文と比較演算子) 【 Python 3.9 】
の中で関数を使っていますが、Pythonでは、def文で関数を定義します。
■ 関数を使う利点
関数の利点ですが、BASICを使う場合にサブルーチンを使った場合に、内部処理が簡素になるので高速に処理が出来るという利点がありますが、もう一つ、
【 処理が構造物単位で存在しているので管理しやすい 】
という利点があります。例えば、BASICインタプリタを使って、サブルーチンに飛んでエラーが出ている場合、その部分と関連する場所を調べればわかりますが、これがコードのOO行目と言う条件だと非常に分かりにくくなります。
そう考えると、
【 構造物で処理がまとまっている方が利便性が高い 】
のですが、関数の場合、BASICのサブルーチンのように、ON GOSUBのコマンドでサブルーチンに飛ぶのではなく、関数単体で呼び出してどこでも使用できるようになります。その為、
【 色々な場所で呼び出す場合に、コードをその都度別の場所に
記述するのではなく、関数呼び出しにしたほうが便利 】
なので、関数を使うことになります。
関数は、高校の数学で出てくる
【 f(x) = 変数xを含む式 】
と全く同じ構造になっています。この数式の場合、xに1が代入された場合だと、f(1)となり、その結果を出しますが、関数も同じような挙動になります。つまり、引数を用意して、処理によって計算を行い、戻り値を算出します。この時の引数は内部で使用されている辺巣になりますが、この引数がf(x)のxと同じ役割を果たします。
つまり、 【 関数名(引数) 】 の形で実行された関数が存在した場合、その引数に値が代入された時に関数が呼び出され、戻り値が出力されるわけです。
この構造を見ると、【 f(x)=変数xを含む式 】の構造の解を導き出すときの処理と、関数の実行は似ており、 【 関数名(引数) 】 の記述で関数を呼び出し、引数の値を変更すれば結果が変化します。
その為、関数名(引数)の記述で関数を実行すれば、登録した関数が実行され戻り値を得る事が出来るので、コンソール上数値の違う計算をする場合でも、関数の呼び出しを行う際に引数に代入する数値を変更するだけで異なる項を持つ数式を生成して実行する事ができます。
その為、関数の呼び出し時に引数の指定をするだけで異なる処理が出来るというのも関数の利点と言えます。
■ 関数を使う
関数を使うメリットはぜじゅつの通りですが、関数を使わない場合と使う場合の違いについてみてみましょう。
■ 例題
次の処理をPythonでプログラミングを行って実行して
みましょう。
【 算数のプログラム 】
リンゴをa個、バナナをb個購入するとします。この時に
■ リンゴ : 100円
■ バナナ : 50円
の固定相場の時に、それぞれの個数を入力して合計
金額を算出して表示できるプログラムを書きなさい。
(*)ループの有無は問いません。
と言う問題があった場合、この問題では、
【 x = 100a + 50b 】
と言う簡単な算数になりますが、これを計算する問題になります。この場合、
■ リンゴの数とバナナの数は定数ではなく変数
■ 合計金額は数式の解
と言う条件が存在しています。そうなると、
■ 変数aと変数bはその都度入力が必要
■ 変数を含めた数式が必要
という事になります。これを表示する必要もあります。そうなると、
■ 変数a,bの宣言
■ input文による入力
■ 変数を含めた数式による演算処理
■ print分による表示
という流れになります。この条件で書いてみると、
■ 関数を使わずに書いたコード
のようなプログラムになります。これを実行すると、
のようになります。これは、完全な 【 順次 】 処理になりますが、まず、初期化をするために、変数を空にします。
今回は、input文を使うのでになるので、""で何も入っていない状態にしています。そして、
のようにprint()関数で値段の説明を表示して、入力に移ります。input()関数で
のように個数を入力しますが、入力した個数が変数に代入されます。ただし、この状態だとstr型なので、これをint型にするためにint()関数で整数にして、変数に代入しています。
整数に変換後に変数cを宣言して、数式に代入します。
これで、変数a,b,cの値の代入が完了するので、それをprint()関数の引数に文字列と変数を入れて、それを結語して代入し、それを表示します。
これが逐次処理を行った場合の処理の流れになります。
これを見てもらうと、計算の処理は変数が揃わないと行えないので、入力よりもかなり後に行われていますが、変数がないと計算ができないので、計算は変数の入力後であり、最終的な表示も変数の代入後になります。この条件は同じですが、変数を使うとコードの作りが変わります。
■ 関数を使って書いたコード
コードの作りが全く違いますが、実行してみると、
のようになります。
■ 関数
■ 処理
と言う二つの構造に分かれています。このコードでは、関数で演算処理を行っています。
の内容ですが、まず、
で関数C1を宣言し、引数としてローカル変数のaとbが入っています。
次が、変数の代入と計算になりますが、ここで、変数がいきなり登場しています。
ta1とtb1はいいとして、aとbは宣言されていませんが、変数として登場しています。この数式として使用されている関数内の変数がローカル変数になります。これを用いて変数の値を指定して代入し、さらに、変数tにta1+tb1を加算して代入しています。そして、この場合、変数tの値が関数内の計算結果になりますから、戻り値になるのですが、これを
のようにreturnで返す事で、tに引数が戻り値として返されます。
つまり、この処理で、ローカル変数を使って変数を定義し、戻り値となるTの計算をします。そして、そのTを返すようにして、関数を宣言しています。
処理の部分ですが、
のようになっていますが、まず、print()関数で価格の表示をします。\nを入れているので、後の表示は改行が入った状態で表示されます。
そして、input()関数で数値の入力を行います。
この状態だと、str型なので、int()関数で整数型にします。
ここからが、前述のコードとは違うのですが、ここで、
のように戻り値tに対して、関数c1を代入します。つまり、戻り値はここで実行される仕様になっており、その値として、前述のinput()関数で入力した値を引数に代入した状態で、関数内で計算した変数tを算出して、戻り値tに代入しています。
そして、
のようにすることで、input()関数で入力された変数a,bは当然のように表示されますが、変数tも関数の戻り値として動作しているので、実行されます。
このように関数を使うと 【 処理の塊を実装して、変数に代入することで、処理を実行できる 】 ようになります。
関 数の定義
関数を使うには関数の定義が必要ですが、前述のように関数はdef文で宣言します。
■ def文
def文ですが、構文は以下のようになります。
■ def文
def 関数名(引数名1, 引数名2 ...):
処理1
処理2
処理3
:
:
と言う構文になります。関数を呼び出すときには、
関数名(引数名1, 引数名2 ...)
で呼び出します。その為、引数に数値を入れた形で実行すると、関数が実行されます。前述の例では、引数をinput()関数で入力した値をを代入していましたが、
のようにしたほうが構造的にわかりやすいかもしれません。ここでは、戻り値のtxに対して関数の実行を代入していますが、この構文にすると、関数が実行されます。
また、関数内の処理の記述はif文などと同様にインデントを入れる必要がありますが、これも4文字の半角スペースを用いる事になります。
■ return文
関数は内部で実行される内容だとそのまま使用できますが、関数の外部で使用する際には戻り値を返さないと実行できません。その時に使用するのがretuen文です。
例えば、
のような構文で記述をすると、戻り値がないので、計算はしていますが、計算した値はそのままなくなってしまいます。
pythonではいろいろな関数がありますが、関数は、関数の呼び出し元に処理の結果になる値を 【 戻り値 】 として返す事ができます。
今回のコードでは、input()関数やprint()関数など複数の組み込み関数を使っていますが、関数には処理が実装されているのでその振る舞いになるわけですが、戻り値が返ってこない場合処理が実行できません。その為、処理を実行す時には、 【 retuan文 】 を用います。
■ return文
return 値
と言う記述になりますが、これを関数の処理の最後に居れます。
のようにすると、retuen文で計算結果が戻り値として出力されるので、関数を呼び出すとそのまま実行されます。このコードのように定数が最初から存在する場合、処理を関数化するとコード自体がかなりコンパクトにできますが、これが関数の利点になります。
ロ ーカル変数とグローバル変数
今回は、
■ 関数を使って書いたコード
■ 関数を使って書いたコード
の二つを作りましたが、この二者では完全に違う物があります。それが、 【 変数 】 です。まず、在所のコードの
と言う変数ですが、これは回数の内外に関係なく呼び出す事が出来る変数になります。この関数の外にある変数の事をグローバル変数と呼びます。
グローバル変数とローカル変数ですが、関数内で組み合わせて使用できるので、
のようなコードを書いて実行すると
のように計算結果が出ます。このコードの変数sは関数の外にありますが、関数内部で呼び出して使用できています。これがグローバル変数の特徴になります。これに対して、変数aは内部にありますから、ローカル変数になります。
この式を見ると何のことかわかりにくいと思いますが、出力はretuenの値なので、関数が実行された時の結果はreturnで何がしていされているのか?になります。
このコードに関しては、 【 c1(b) = a * b 】 という状態でaが先に定数化しているので、 【 c1(b) = b * 3 】 と書き換えることができます。この書式を見ると、 f(x) = 3x だったり、 y = 3x と書き換えると、関数の状態がわかりやすくなると思います。
f(x) = 3x の式の時に、f(5)のの場合、どうなるのか?と言うと、xに5を代入した状態になりますから、3*5なので、15になります。つまり、
【 xの関数 】 = 【 変数xを含む数式 】
と言う図式が、
【 ローカル変数を持つ関数 】 = 【 returnの戻り値 】
という形で実行されるようになっています。この時に、ローカル変数を用いた処理が実行されているので、関数実行時にローカル変数の代入を行う事になります。
その為、
の中を見てみると、
のように引数の中と、
のように演算の中に変数a,bが存在しますが、。この2つがローカル変数になります。
ローカル変数は 【 関数を実行し得る間のみ参照可能 】 となっていて、 【 関数外からの参照ができない 】 仕様になっています。その為、関数の内部処理でしか使えない変数になります。
pythonでは、
■ モジュールスコープ
■ 関数以外の部分
■ ローカルスコープ
■ 関数内の部分
に分けることができますが、前者がグローバル変数で、後者はローカル変数になります。
また、関数の内部では、
【 モジュールスコープ内で定義した関数を呼び出す事が出来る 】
仕様になっています。その為、
のようなコードを書くことができます。これを実行すると、
の様な挙動になりますが、関数内で用意された関数を呼び出して、使用し、その関数を実行する事ができます。
その為、import mathなどでmath関数を呼び出して使用したりtime関数などをインポートして使う事もできます。つまり、行っている内容は、上記の内容と同じですが、標準ライブラリのように組み込み関数とは異なり、外部で読み込んで使用する関数も、こう言った関数の利用が可能なので、使用できるようになっています。
引 数と種類
関数を使う場合には、引数を用います。これは組み込み関数の
■ ptrint()関数
■ input()関数
などでも同様で、()内部に指定した引数を元に戻り値が出力され処理が行われます。この引数ですが、引数には種類があります。
■ 位置引数
これは、
■ 位置引数
関数名(引数名1, 引数名2 ...)
のように表記するもので、引数を順番に並べたかきかたになります。
■ キーワード引数
これは、
■ キーワード引数
関数名(引数名1="値", 引数名2="値 ...)
のように 【 引数名='値' 】 という形式で引数名を指定する方法になります。
引数には、この二つがありますが、キーワード引数は、引数の番号の順序がばらばらでも大丈夫で、
■ 位置引数
a('引数1', '引数2', '引数3')
と
■ キーワード引数
a(b3='引数3', b2='引数2', b1='引数1')
の場合、順番は異なりますが、結果は同じになります。また、引数の中に位置引数とキーワード引数を混在できるので、
a(b, c='c1', d='d1')
のような記述もできます。
デ フォルト引数
関数の引数には、値が指定されなかった場合に使用できる【 デフォルト値 】 を指定できます。デフォルト値ですが、
■ def文
def 関数名(引数名=デフォルト値):
で指定できます。例えば、領収書で、名前の有無が発生しますが、仮にこの名称を 【 name 】 と言う変数にしておいた場合、名称の入力があった場合はその名称になりますが、その都度名称を 【 上 】 と打ち込むのも手間がかかります。その場合、入力なしの場合に 【 上 】 になるようにしておけば無駄な手間がなくなるので、デフォルト値で 【 def 関数名(name = '上') 】 のようにしておけば問題なく処理が行えます。
また、キャラクターネームの指定も名称なしの場合、空白ではなく最初に制作者が指定した名称を指定できるようにする場合にもデフォルト値でその名称を変数に代入できるようにしておくこともできます。
現在のプログラミングでは関数やクラスがフツーに登場するので、これについては、コンパイル型言語を使わなくても、PythonやESを使っても出てきますから、何を使っても出てきます。
関数については、f(x) = 数式 の構造と同じ作りですが、この時に数式の解がf(x)で実行されるのですが、この数式の解の部分がreturnで指定する仕様になっています。つまり、returnで指定した値が出力されているので、これを呼び出して使用する流れになりますが、関数自体を変数に代入してそれを表示することもできます。
また、関数の引数はローカル変数なので、引数を持つ関数と言うのは、 【 ローカル変数を持つ関数 】 なので 【 変数を持つ関数 】と言う子ことになります。そうなると、一変数関数や多変巣関数と同じ仕様のものになります。
その為、 【 呼び出しは関数 】 ですが、出力はreturnの値なので、引数を参照して戻り値を得るような仕様の場合には、returnが必要になります。ただし、
のように最初の関数には引数はありますが、次の関数には参照する引数がありませんからそう言った作りの関数も存在します。
その為、
【 処理にローカル変数を用いるてそれを称して実行する
場合には引数が必要になる 】
わけですが、そのローカル変数を使って、計算を行う場合だと、戻り値を返す必要が出てくるので、この場合、retuenで戻り値を出力する事になります。