# 応用プログラミング演習(python)2
### ラムダ式/λ形式
``pythonの中では変数名が関数と呼ばれる。変数名も関数名も名前``
ラムダ式またはλ形式(lambda expression / lambda forms)「lambda arguments: expression」は、構文的に式と同じ位置づけであり、それでいて、関数の定義とみなしても差し支えありません。式が書けるところには、ラムダ式を書くことができて、一時的な関数を定義することができます。それゆえでしょうか、匿名関数や無名関数と呼ばれることも多いようです。事実、ラムダ式は関数オブジェクトになります。
多相的=色々の足し算ができる。
関数プログラミングとは、引数の並び、個数は大事ではない。
**~例~**
``(lambda x=3, y=4: x + y) //3.4はデフォルト値``
``(lambda x=3, y=4: x + y)(5, 6) ``
XとYがデフォルト値 (5と6が新しく引き渡される)
``plus = (lambda x=3, y=4: x + y) //ラムダ式を変数plusで束縛する``
``plus()``
7 //plusで呼び出したものには3と4が入ってる。
``Arguments[] //リストも可能``
アスタリスク1個は、パックアンパック
アスタリスク2個が辞書渡し
<font color="Red">Pythonでは変な型の縛りがなく柔軟な引数の引き渡しが行える。
</font>
***
### 通常渡し・デフォルト値・キーワード指定・パック&アンパック(タプル渡しやリスト渡し)・辞書渡し
print('1st = {}'.format(first))
print('2nd = {}'.format(second))
print('3rd = {}'.format(third))
print('4th = {}'.format(fourth))
**・通常渡し**
func() # デフォルト値が両方とも生きている。
1st = 3
2nd = 4
3rd = ()
4th = {}
**・デフォルト値**
func(5) # 2つ目のデフォルト値だけが生きている。
1st = 5
2nd = 4
3rd = ()
4th = {}
////デフォルト値が死んでる場合
func(5, 6) # デフォルト値が両方とも死んでいる。
1st = 5
2nd = 6
3rd = ()
4th = {}
**・タプル渡し**
func(5, 6, 7, 8, 9) # 余分な(3番目以降の)引数がすべてタプル渡しになっている。
1st = 5
2nd = 6
3rd = (7, 8, 9)
4th = {}
**・リスト渡し**
func(5, 6, *[7, 8, 9], **{'x': 10, 'y': 11, 'z': 12}) # 通常渡し2つにリスト渡しと辞書渡しを併用する。
1st = 5
2nd = 6
3rd = (7, 8, 9)
4th = {'y': 11, 'x': 10, 'z': 12}
**・辞書渡し、キーワード渡し**
func(5, 6, 7, 8, 9, x=10, y=11, z=12) # キーワード指定が辞書渡しになっている。
1st = 5
2nd = 6
3rd = (7, 8, 9)
4th = {'y': 11, 'x': 10, 'z': 12}
***
加算・減算・乗算そして剰余算は(まぁ)いいとしても、除算は何かと問題なはずです。整数の除算では、切り捨て(truncation)が起こりますし、少数(浮動小数点数:実数のバッタもん)の除算では、誤差(計算精度:calculation accuracyの面倒)が発生する上に、有理化(有理式:rational expression)などが困難です。そこで、分数(Fraction)を導入して、有理的な計算の典型例をご覧にいれます。
``from fractions import Fraction //分数(Fraction)を移入(import)します。
2 # (3/4) + (5/4) = (3+5) / 4 = 8/4 = 2。
-1/2 # (3/4) - (5/4) = (3-5) / 4 = -2/4 = -1/2。
15/16 # (3/4) * (5/4) = (3*5) / (4*4) = 15/16。
3/5 # (3/4) / (5/4) = (3/4) * (4/5) = (3*4) / (4*5) = 12/20 = 3/5。
3/4 # (3/4) % (5/4) = (3%5) / 4 = 3/4。``
***
$ (cd ~ ; pwd) //別のターミナルを開いて実行
/Users/Nyanzeu
$ pwd
/Users/kohei/AP/Python/3
$ cd ~ ; pwd //
/Users/horikitabaki
$ pwd
/Users/kezounchi
$ os.sep //世界のどのpcでも使えることが保証される。
'/'
<font color = "Red">大切なことがあります。ディレクトリどうしを結合したり、ディレクトリとファイルを結合したり、それらを陽に行う際には、けっして「/」(Windowsの場合には「\」)を用いてはいけません。必ず「os.sep」を用いてください。OSに適切なセパレータ(separator:区切り記号)が束縛されています。</font>
せっかくパイソンを使っているなら、Javaのようなプログラムは書くな。
うんち。
***
### ファイル「~/Desktop/Example.py」に書き込み(推奨:プログラミング言語「Python3」らしいイディオムでオススメです)
```
import os
home_directory = os.path.expanduser('~')
a_file = os.path.join(home_directory, 'Desktop', 'Example.py')
with open(a_file, 'w', encoding='utf-8') as a_file: # オープン:open(...)を用いて第3引数に文字コード系を指定
a_file.write('#!/usr/bin/env python\n') # シェバンを書き込む
a_file.write('# -*- coding: utf-8 -*-\n') # マジックコメントを書き込む
```
sudo -s //スーパーユーザーに切り替える。
ターミナルはShell Scriptを処理するもの
スクリプト言語のスクリプトは脚本。
a_list = ['AAA','BBB','CCC']
>>> a_list
['AAA', 'BBB', 'CCC']
'zzz'.join(a_list)
'AAAzzzBBBzzzCCC' //結合
***
### 内包表記・イテレータ・ジェネレータ
プログラミングのスタイル(パラダイム:指導規範:模範とする枠組み)を大別すると、『手続きプログラミング』、『オブジェクト指向プログラミング』、『関数プログラミング』、『論理プログラミング』、これら4つが基底になって、その他の多くのスタイルが生み出され(導出され)ます。
最後の論理プログラミングには『宣言プログラミング』や『制約プログラミング』などが関係するのですが、手続きプログラミングとオブジェクト指向プログラミングを学んだだけでは、なかなか入り込めない、敷居が高くて、ある域に達するのも難しいプログラミングのスタイルになります。その橋渡しをするのが、実は関数プログラミングなのです。
Pythonは関数プログラミング言語、Pythonを学ぶことは、もっと他の(CやJavaなどでは味わえない得ることができない)プログラミングのスタイルへの導引(水先案内)になり、プログラミングの広大な地平を垣間見る(大海へ船出する)ことになります。
関数プログラミングには『並行プログラミング』や『分散プログラミング』などが深く関係しており、形式的証明可能性や形式的仕様記述性とも密接に関連しています。自然と副作用やモジュール性や結合性などへの関心(素養)が高まり(養われ)ます。
//内包表記:1以上10未満の整数とその整数の公約数たちを求める。
``a_list = [(x, [y for y in range(1, x) if x % y == 0]) for x in range(1, 10)]
print(a_list)``
#### イテレータ
連続データを表現するオブジェクトになります。一つずつ要素を返(応答)します。Pythonのイテレータは必ず「next(...)」という関数をサポートしています。意味合いとしては「次の要素をください」ということ。次の要素が無く返せない場合には例外「StopIteration」を出します。
#### ジェネレータ
皆さんは標準的な関数コールについて良く知っているはずです。関数を呼び出すと、引数としての変数やローカル変数などのためのプライベートな名前空間が獲得され、その関数の本体(処理)を実行してゆきます。そして、return文まで来ると、プライベートな名前空間を破壊(解放)してから、返り値(戻り値)が呼び出し元に応答されます。