見出し画像

Python勉強記(6)- 関数

初めに

高等学校では、もう何年も前に「情報Ⅰ」と科目が教えられ、大学センター共通テストでも出題されているようです。
大学入試センター共通テストの「情報Ⅰ」では、DNCLという共通テスト試験専用言語が出題されるらしいですね。

2番目の記事にコード例があります。
Pythonを無理やり日本語化(+謎のブロック表記)した言語のようで、しかもプログラミングの配点が一番高いそうです。

特定の言語に依存しない出題ならわかりますが、せめて。コンピューターに入力可能な言語にしてほしいわ。

横道にそれましたが、始めます。


Python の関数

Pythonでは他の言語同様、いろいろな関数を利用・定義することができます。
関数はPython文の中で値を渡し、何らかのプログラムを実行し、ユーザーが望む値を返します(引数と値は、必須ではありません)
ここいらはC言語やほかの高級言語と同じです。

今までもそうでしたが、関数を変数と区別するため、名前の次に()を付けてfunc() のように示します。

分類

関数は主に、実装の仕方などについていくつかに分類できます。

分類の仕方はいろいろありそうですが、ざっと検索したところ、
以下記事の分類が、説明したいものに近いためなので、使用させていただくことに。

関数の分類(Python::Hackより引用)

うん。とってもわかりやすい。
続き要らなくね?
・・・

解説書ならその通りですが、これは勉強記ですので
自分なりにかみ砕いたテキストを書き続けます。

組み込み関数

上記「関数の分類」図の2番目です。
Python内に出来合い、すぐに使い始める関数たちです。

今まで何度も出てきたprint()や、入力関数input()、算術関数の中でも絶対値うabs()  などは組み込み関数です。

組み込み関数一覧(公式ドキュメント)

【一部修正】標準ライブラリの関数

組み込み関数ではない関数は、すべてimport文で読み込み、(原則として)ライブラリ名.関数名()で呼び出す必要があります。
そのうち、初めからPythonインストーラに付属し、import文のみで使用できる関数が「標準ライブラリ関数」です。

標準ライブラリ関数(たくさんあります)

典型的なライブラリは数学ライブラリmath です。
以下はπ/4 (=45°)の正弦、余弦、正接関数の値を求めてみます。

>>> import math 
>>> print(math.sin(math.pi/4)) # surt(2)/2
0.7071067811865476
>>> print(math.cos(math.pi/4)) # sqrt(2)/2
0.7071067811865476
print(path.con(PI/4)) # 1
0.9999999999999999

円周率の値ですらmath.piと書かなければならないなんて!と、
めんどくさい輩(私もそうです)のために、2通りの構文があります。

1.import ライブラリ名 as 別名

>>> import math as mt #ライブラリに別の短い名前を付ける。
>>> mt.sin(mt.pi/4.0)
0.7071067811865476

2.from ライブラリ名 import 関数1, 関数2…

>>> from math import pi, sin, con, tan # 関数を指定してライブラリ名を省略する。
>>> sin(pi/4.0)
0.7071067811865476

可読性という観点からは、最後の方法が一番すっきりしていて良いように見えますが、やりすぎると以下の弊害もあるため注意が必要です。

  • 名前の衝突(後述)

  • プログラム移植性を損なう。

  • 使えるはずの関数が使えない。

3番目の弊害の例を以下に示します。
from math import ~では使用する関数をすべて列挙する必要があります。
この例ではasin() 関数も同様に呼べるはず・・・と勘違いしています。

>>> from math import pi,sin,cos,tan
>>> sin(pi/4)
0.7071067811865476
>>> asin(0.7071067811865476) # arcsin((sin(pi/4))を計算してみる。
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'asin' is not defined. Did you mean: 'sin'?
>>> math.asin(0.7071067811865476)
0.7853981633974484

ライブラリ名を知っていないと厄介な例。何が間違っているでしょうか?

1行目で持ってきたつもりのexp() は $${e^x}$$ なのですが実数値関数のため、オイラーの公式が計算できないのです。
この例では複素数用ライブラリcmathを使う必要がありました。

>>> from math import pi, e, exp ♯オイラーの公式でe^(iπ)を計算する
>>> e**(1j*pi)
(-1+1.2246467991473532e-16j) # OK(丸め誤差あり)
>>> exp(1j*pi)         # math.exp() は実数のみ計算できる。
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: must be real number, not complex
>>> import cmath              # 複素数用ライブラリを慌ててインポート
>>> cmath.exp(1j*pi)
(-1+1.2246467991473532e-16j)

【追記あり】外部ライブラリの関数

Pythonインストール時には含まれておらず、別途インストール必要なライブラリです。
有名どころでは進んだ数学ライブラリのNumPyがあります。

>>> import NumPy #そういえばNumPyインストールしていなかった。
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'NumPy'

★公式Pythonでは、pip コマンドを使用してインストールしたら使用できるようになるはずですが、当方の環境でエラーになり調査中です。
調べてみたところ、ライブラリのパス設定が必要でした。

【付記】Numpyのような外部ライブラリを複数インストールするには、公式pythonのpipコマンドではライブラリ間の依存関係が解決できないケースがあります。こういったケースではanaconda系のPythonに付属のcondaコマンドが必要になりますが、追って記事を書きます。

独自関数

標準ライブラリに関数がない場合や、独自関数を自分で作成したい場合があります。

これからいろいろな関数やプログラムを作成していきますが、今回は概要にとどめます。

公式ドキュメントにも掲載されている、フィボナッチ数列のプログラム例を掲載します。
フィボナッチ数列は以下の漸化式で定義される数列です。

$$
a_0 = 0, a_1=1 \\
a_{n+2} = a_{n+1} + a_{n}  ( n > 2)
$$

Pythonプログラムでは以下のようになります。
※プロンプト記号は省略しました。

# Python 3: Fibonacci series up to n
def fib(n): 
    a, b = 0, 1
    while a < n:
       print(a, end=' ')
       a, b = b, a + b
     print()

fib(1000)


独自関数の骨組みはだいたいこんな感じ。

def 関数名( 引数1, …):
      いろいろな処理
      [ return 値 ]
# ここからがメイン処理
なにかの処理
[ 変数 = ] 関数名( 引数1, …)

やっとPythonプログラミングに見え始めたところで、
今日は上の要点だけ確認して次回に続きます。

  • 関数は(変数と同じく)使用する前に定義する。

  • 関数定義の下に実際の処理文を書く(def から実行するわけではありません)

  • ブロックはオフサイドルール(インデント)により記述する。

この記事が気に入ったらサポートをしてみませんか?