【プログラミング】3.9 関数

プログラミング

関数というと数学の授業を思い出すかもしれません。一次関数、二次関数、三角関数など、いろいろありましたね。今回扱うのはプログラミングにおける関数です。数学の関数と似ているところもそうでないところもあります。それでは見ていきましょう。

関数とは

プログラミングをしていると、同じような処理を何回も行うことがよくあります。

ここでは例として、3つのグループに対してテストの合計点や平均点を求めることを考えます。各グループに属するメンバーの点数はリストに入っているものとします。リストに含まれる数値の合計や平均を求める方法は前回にやったとおりです。

これをプログラムにすると以下のようになります。

#coding: utf-8

group_a = [96, 84, 86, 76, 64, 52, 39, 54, 94, 40] # グループAの点数リスト
group_b = [60, 47, 26, 79, 78, 45, 50, 32, 15, 89] # グループBの点数リスト
group_c = [68, 50, 99, 36, 85, 61, 58, 28, 47, 86] # グループCの点数リスト

print( "グループA" )
print( "合計点", sum(group_a) )
print( "平均点", sum(group_a) / len(group_a) )
print( "最高点", max(group_a) )
print( "最低点", min(group_a) )

print( "グループB" )
print( "合計点", sum(group_b) )
print( "平均点", sum(group_b) / len(group_b) )
print( "最高点", max(group_b) )
print( "最低点", min(group_b) )

print( "グループC" )
print( "合計点", sum(group_c) )
print( "平均点", sum(group_c) / len(group_c) )
print( "最高点", max(group_c) )
print( "最低点", min(group_c) )
図 関数を使わない場合のプログラム
これを実行すると、次のようになります。
正しく計算できていますが、同じような処理が3回も続いており、ちょっと冗長な気がしますね。グループが増えたらどんどん同じような処理を追加していくのも面倒です。そこで、関数を用いて整理してみましょう。
#coding: utf-8

group_a = [96, 84, 86, 76, 64, 52, 39, 54, 94, 40]
group_b = [60, 47, 26, 79, 78, 45, 50, 32, 15, 89]
group_c = [68, 50, 99, 36, 85, 61, 58, 28, 47, 86]

def goukei_and_heikin(tensuu):
    print( "合計点", sum(tensuu) )
    print( "平均点", sum(tensuu) / len(tensuu) )
    print( "最高点", max(tensuu) )
    print( "最低点", min(tensuu) )

print( "グループA" )
goukei_and_heikin(group_a)

print( "グループB" )
goukei_and_heikin(group_b)

print( "グループC" )
goukei_and_heikin(group_c)

図 関数を使って書き直したプログラム

もちろん、実行結果は同じになります。

同じような処理が連続しており冗長になっているというのは、決して見た目の話だけでなく、何か変更や修正が必要になった場合には同じような修正を3カ所に対して行う必要があるため見落としや漏れが生じやすく、保守性の低下にもつながります。このため、同じような処理は関数にまとめて実装するということがなされます。

関数の定義と呼び出し
改めて、関数の書式を見てみましょう。
図 関数定義の書き方
この定義でやっていることは、処理のかたまりに名前をつけて、あとから呼び出して実行できるようにしているということです。なお、関数の中で引数(後で説明します)を使用しない場合にはカッコの中は空っぽで構いません。
そして、呼び出す場合の書き方は以下のとおりです。
図 関数の呼び出し方
関数名に続けてカッコを書くことで呼び出すことができます。カッコの中には引数を指定しますが、引数が不要とされている関数を呼び出す場合には、カッコの中は空っぽで構いません。
引数と戻り値

関数定義と呼び出しにおいて出てきた引数(ひきすう)とは何でしょうか。

引数とは、関数を呼び出すときに、呼び出し元から関数にデータを引き渡すための仕組みです。呼び出し元は関数名に続いて値や変数などのデータを記述することで、関数ではそのデータを用いた処理ができるようになります。

関数の定義で引数が必要とされている場合には、呼び出す側も引数を指定した上で関数を呼び出す必要があります。さらに、関数で求めている型のデータを正しく指定する必要があり、ここが間違っていると期待した処理が実行されない原因となります。

一方、関数からは値を返すことができます。これを戻り値や返り値(JIS規格では返却値と言ったりもします)などと言います。関数から値を返すには return を使います。

この引数と戻り値の組み合わせにより、関数に何らかのデータを渡して処理を行い,その結果を受け取るといった一連の流れが可能になります。引数を与えて何らかの値が戻る関数だと、数学の関数をイメージしやすいですね。

図 関数に渡す引数と戻り値のイメージ

関数の例

数値を扱う関数の例として、与えられた数が素数であるかを判定する関数を作ります。

素数とは、2以上の整数のうち、1と自分自身以外の数では割りきれないものでしたね。その考え方に従って、1とその数自身以外に割り切れる数があるかを順番に調べていく処理を関数として実装しましょう。

#coding: utf-8

# 与えられた数が素数であればTrueを返す関数
def sosuu(x):
    # 2からx未満の数について順番に試す
    for i in range(2, x):
        # 2からx未満の数のいずれかで割り切れればxは素数ではない
        if x % i == 0:
            return False
    # 2からx未満のどの数でも割りきれなければxは素数
    return True

# 30未満の数で順番に試してみよう
for i in range(2, 30):
    print(i, sosuu(i))
図 素数を判定する関数
関数で処理している内容はコメントにあるとおりです。
なお、#記号から行末まではコメントと見なされるため、プログラムの実行には影響を与えません。プログラムで何をしようとしたか、どんな意図で処理を実装したのかなど、備忘のためにコメントを残しておくとよいでしょう。
%記号は、整数の割り算における余りを求める演算子です。つまり、x%i==0 という条件式では、xをiで割った余りが0であるかをチェックしています。
これを実行すると以下のようになります。
次は、単語を与えると This is … という文章を作る関数です。単語により、冠詞としてaとするかanとするかを判断する処理があります。
#coding: utf-8

def thisisa(word):
    if word.startswith(("a","e","o","i","u")):
        sentence = "This is an " + word + "."
    else:
        sentence = "This is a " + word + "."
    return sentence

print( thisisa("apple") )
print( thisisa("banana") )
print( thisisa("orange") )
print( thisisa("peach") )

図 文字列を扱う関数の例

関数では、受け取った単語の先頭文字が a,e,o,i,u のいずれであるかどうかを判断し、an か a のいずれかを冠詞とする文章を作り、それを return で返しています。

 

まとめ
  • 処理をまとめて名前をつけて関数を定義することができる
  • 定義した関数はその名前とカッコで呼び出すことができる
  • 関数には引数を渡すことができ、関数内の処理ではその引数を受け取って利用することができる
  • 関数は値を返すことができ、呼び出し元ではその値を参照できる
  • プログラム中で何回も実行する処理は関数にしておくとよい

コメント

タイトルとURLをコピーしました