見出し画像

Python言語によるプログラミングイントロダクション(4)

 Python言語によるプログラミングイントロダクション第2版ーデータサイエンスとアプリケーション(著者:Jhon V. Guttag 監訳:久保幹雄)を読んだ学習を記録していきます。そのため、詳しい内容を学習したい場合は本を購入していただくことをお勧めいたします。また、解釈や理解が間違えである場合も多々あるかと思います、、、

第4章 関数,スコープ,抽象化(p39~61)

 ここまでで、述べてきたようなコードは一般性に欠けており、値の変更などのために定義を書き直す必要がある。

4.1 関数とスコープ

# 関数の定義
def 関数名(仮引数の並び):
    関数のコード
# 例
def maxVal(x,y):
    if x > y:
        return x
    else:
        return y

 関数名は関数を呼び出す際の宣言に用いられる。仮引数には、関数呼び出しをする際に定義する実引数と紐付けられる。returnが実行されると関数の呼び出しは終了し、指定した値を返す。関数呼び出しは式であるため、何かしらの値を持つ。引数はラムダ抽象と呼ばれるものを提供する?これによって、実引数にどんなオブジェクトでも選択することができる。
 仮引数と実引数をつなげる方法は2通り存在する。1つ目は位置指定引数と呼ばれる。順番通りに、実引数と仮引数をつなげる方法になる。もう1つは、キーワード引数という方法になる。これは、x=2というようにどの仮引数に実引数を紐付けるかを指定する方法になる。注意点としては、キーワード引数で紐付けした後は、位置指定引数を使えない。また、仮引数の時点で、キーワード引数のように定義しておくと、初期値として利用できる。
 実引数と仮引数は同じ名前だが、同じ変数ではなく別で定義されることに注意する必要がある。あくまで、仮引数に実引数を代入しており別の変数であり、関数内では仮引数として処理されている。この範囲をスコープと言う。またスコープ内で引数とは別に定義される変数を局所変数(ローカル変数)と言う。返り値として局所変数を指定しても、スコープの外では利用できない点にも注意が必要になる。
 スコープについて完全に理解するためには、プログラムが内部でどのように処理されているのかを理解していく必要がある。

4.2 仕様
 ドキュメンテーション文字列("""で囲まれた文章)で関数の仕様を明示しておくことが慣例である。仕様として、仮定と保証を記入する必要がある。仮定では関数を実行する際の条件を記入し、保証では仮定通りに実行した際の実行結果はどのようなものかを記入する。
 システム開発において、仕様は重要事項であり、仕様はそのシステムや関数を抽象化したものである。抽象化することは、組織での開発や後の開発時に大きく貢献することになる。

4.3 再帰
 一般的に、再帰的定義は2部で構成される。特別なカースの結果を直接明示する基本ケースが少なくとも1つあり、再帰的なケースが少なくとも1つある。高校などで習ったであろう数学的帰納法を思い出すと理解が早い。自然数の階乗やフィボナッチ数列なども再帰で表すことができる。また、回文の正誤判定なども可能である。

4.4 広域変数
 広域変数(グローバル変数)は局所変数(ローカル変数)とは違い、引数や返り値などで変数の値の受け渡しをせずに、変数の値を利用することができる。しかし、プログラミングにおいて局所性は重要な考え方であり、プログラムを読みやすくすることや、デバッグの容易さなどの点からしばしば広域関数は敬遠するべきものであるとされる。

4.5 モジュール
 1つのファイルでプログラムを完成させるのではなく、複数のファイルでプログラムをしていくために、参照するPythonファイルのことをモジュールと言う。ファイルを参照する場合はimport文で参照でき、ファイルの中の関数の呼び出しが可能になる。また、from M import f でモジュールの中の関数を指定して参照することができ、この場合は余分なモジュール内の関数を参照しないようになっている。しかし、モジュールの参照はimportのみ参照して利用する方がプログラムの可読性は高いとされている。

4.6 ファイル
 pythonではOSに依存しないように、ファイルハンドルと呼ばれるものを通してファイルにアクセスしてファイルの操作を行う。open(),read()などを利用してファイル操作を行う。

最後に、この章の練習問題に1つ挑戦してみる、、、

問題:コード4.6のfibを実装し、fib(5)を求める場合、fib(2)の値が計算される回数は全部でいくつか?

 #コード  4.6
def fib(n):
   """n > 0 を整数と仮定
      n 番目のフィボナッチ数を返す"""
   if n == 0 or n == 1:
       return 1
   else:
       return fib(n-1) + fib(n-2)

def testFib(n):
   for i in range(n+1):
       print('fib of', i, '=', fib(i))
def fib(n):
  """n > 0 を整数と仮定
     n 番目のフィボナッチ数を返す"""
  if n == 2:
      global count
      count = count + 1
      print('fib(2) is ',count,'times.')
  if n == 0 or n == 1:
      return 1
  else:
      return fib(n-1) + fib(n-2)

def testFib(n):
  for i in range(n+1):
      print('fib of', i, '=', fib(i))

count = 0
x = fib(5)
print(x)

 グローバル変数を使わずに簡単にカウントするコーディングわかる人がいたら教えていただきたいです、、、

重要語句
チューリング完全、関数、引数、仮引数、実引数、ラムダ抽象、スコープ、局所変数、スタックフレーム、ドキュメンテーション文字列、再帰、帰納的、帰納的定義、フィボナッチ数列、分割統治、ファイルハンドル、エスケープ

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