はじめてのPython雑多メモ

はじめてのPython、調べたことはメモっとく。
当方の経験言語は、ActionScript3、C、C++、C#、JS。

# import

## socket
通信周りを扱えるようになる。
[Pythonによる通信処理](http://qiita.com/nadechin/items/28fc8970d93dbf16e81b)
[17.2. socket — 低レベルネットワークインターフェース](https://docs.python.jp/2.7/library/socket.html)
[Man page of SOCKET](https://linuxjm.osdn.jp/html/LDP_man-pages/man2/socket.2.html)

### socket.socket()
ソケットの作成。

### socket.setsockopt()
ソケットのオプションを設定。

### socket.SOL_SOCKET
ソケットレベル？どのソケットの場合でも、とりあえずこれを指定するぽい

### socket.SO_BROADCAST
ブロードキャスト設定。

### socket.AF_INET
IPv4 インターネットプロトコル

### socket.SOCK_DGRAM
データグラム (コネクションレス、信頼性無し、固定最大長メッセージ) をサポートする。
UDP通信ではコレを指定する。

## random
乱数の関数を扱えるようになる。
[数値(ランダムな値)の生成](http://www.python-izm.com/contents/application/random.shtml)

## RPi.PGIO
RasPiでLチカしようとしたときに見つけた文。
as は別名を名付けするためのもの。

```py
import RPi.GPIO as GPIO
```
[Pythonのモジュールインポートのしくみ](http://python.matrix.jp/pages/tips/import.html)
[Raspberry PiでPythonのRPi.GPIOを使ってLチカする](http://qiita.com/masato/items/715e28e0c0c945a54297)


# インデント必須
これはよいかも。

# print
コンソールへの出力。
ダブルクォーテーションとシングルクォーテーションでの文字列の表示には差異はないのか？

```py
print "bufferSize : " + size
```

的な感じで出力しようとすると、
*TypeError: cannot concatenate 'str' and 'int' objects*
と、「型を混ぜるんじゃねぇ」と怒られる。

```py
print "bufferSize : " + str(size)
```
キャストしてあげるとOK。
か、

```py
print "bufferSize : "
print size
```

それぞれ出す。
すこしめんどい。

# セミコロン不要
いれてもよい。

# Terminalでのヴァージョンの確認
```shell-session
$ python --version
```
python 2系と3系ではだいぶ違う感じか？

# 型指定不要
動的型付けしてくれる。

# 文字列に代入
```py
msg = "%s:%s" % (1, 100)  # 1:100
```
[Pythonメモ：文字列に値を代入する際](http://qiita.com/juniskw/items/8e314b5f8f4afe454bfb)

# 関数 def
def文で関数（functino）を定義することが出来る。

```py
def add(x,y):
    ans = x + y
    return ans

n = add(3, 5)
print n    # 8
```

はー、インデントが強制だから中括弧とかは不要になるのか。

# リスト、タプル、ディクショナリ
- リスト
    - **[ ]** (角括弧)
    - いわゆる配列。
- タプル
    - **( )** (括弧)
    - 変更できない配列。
- ディクショナリ
    - **{ }** (中括弧)
    - 連想配列。


[Python入門 - リスト・タプル・辞書](http://www.tohoho-web.com/python/list.html)
[【python】基礎を復習 (リスト, タプル, ディクショナリ)](http://difficultposition.info/blog/2013/10/417/)

# Nullオブジェクトは None

```py
# ↓正解 
A is None
A is not None

# ↓不正解、遅いらしい
A == None
```

[PythonではNoneの比較は==ではなくisを使う](http://monmon.hateblo.jp/entry/20110214/1297710749)
[Pythonでヌルオブジェクトの比較](http://qiita.com/tortuepin/items/44fdb63cc82dfd260575)

# elif
Pythonではelse ifをelifと書くのかｗ

# 日本語エンコード
日本語コメントアウトでもASCII以外のキャラクタがはいっていると怒られるので、ファイルの頭にエンコーディングの指定をしてやると日本語でも言う事聞いてくれる。

```py
# coding=utf-8
```
[Pythonと日本語](http://d.hatena.ne.jp/KNarumi/20070925/1190702792)

# in演算子
指定の値が要素に含まれているかどうかを調べる。

```py
list = ["A", "B", "C"]

print "B" in list        # True
print "D" in list        # False
print "B" not in list    # False
print "D" not in list    # True
```
[要素の確認(in演算子, indexメソッド, countメソッド)](http://www.pythonweb.jp/tutorial/list/index10.html)

# lambda
ラムダ式。Pythonの無名関数。

```py
def func(a, b):
    return a + b

print func(1, 2)    # 3
```
上記をlambdaを使うと、

```py
print (lambda a, b: a + b)(1, 2)    # 3
```
で、変数に格納することもできると。へー。

```py
f = (lambda a, b: a + b)
print f(1, 2)    # 3
```

[lambda式はすごく面白い](http://emoson.hateblo.jp/entry/2014/10/14/022053)

# reduce 関数
複数の要素を1つにまとめたいときに使う。
具体的には，配列の先頭から 2 つの要素を取り出して処理を行い，次はその結果とその次の要素に処理を行う，ということを繰り返す。

```py
print reduce(lambda x, y: x + y, range(1, 5))    # 10
```
Python3だとimportが必要とのこと。

[Python 2 と 3 での高階関数の使い方の比較](http://qiita.com/croissant1028/items/94c4b7fd360cfcdef0e4)

# test.pyはメッ
ちょっと試すのに完全にこれやってたｗ
testていう標準ライブラリがあるから。
[Pythonでtest.pyを作るな！](http://qiita.com/msmhrt/items/7e2a335a4c64bcc6e044)

# [ctrl] + [c] をキャッチする
RapPiでPythonプログラム終了時にGPIOからのLED光りっぱなしとかが気になったので[ctrl] + [c]をキャッチして終了処理を書いた。

```py
try:
    while True:
        # ここに通常処理
except KeyboardInterrupt:
    print("interrupted!")
    # ここに終了処理
```

[Python で Ctrl-C をキャッチする](http://qiita.com/keisuke-nakata/items/e77b123d75d4b52aac77)

# pass 文
何もしない。中身の無い関数やクラスを作成する際に使用されます。
そんなんあんのか。

```py
def func()
    pass
```
[Python入門 - 制御構文](http://www.tohoho-web.com/python/control.html)

# サーバを建てる
「Python、楽しい！」ってなって、何できるかなーと調べてたけどサーバが簡単に立ち上がるのすぎょい。

```shell-session
$ python -m SimpleHTTPServer
```

[Pythonならたった一行でWebサーバを建てられる](http://fixxman.hatenablog.com/entry/2014/12/27/213417)
[PythonでWebアプリをつくる（ApacheもWebフレームワークもなしで）](http://yife.hateblo.jp/entry/2012/01/25/054210)


# for 文
こんな書き方おらはじめてだ。

```py
for 整数 in オブジェクト：
    処理
```
オブジェクトに配列をいれれば順番に実行してくれる。

```py
list = [1,2,3]
for num in list:
    print(num) # 1 2 3
```

オブジェクトにrange関数を指定すればそれに従って実行。

```py
for num in range(5):
    print(num) # 0 1 2 3 4
```
0から始まって5回実行してくれる、って意味っすね。

range関数の引数の数によって挙動も変わる。

- range(5)
    - 出力：0 1 2 3 4
    - 0からインクリメントしながら5回実行
- range(5, 10)
    - 出力：5 6 7 8 9
    - 5からインクリメントしながら10未満まで実行
- range(0, 10, 3)
    - 出力：0 3 6 9
    - 0から10未満まで、3ずつ増加しながら実行

[python for文を初心者向けに解説！for文基礎はこれで完璧](http://udemy.benesse.co.jp/development/python-for.html)

# if 文
こう書くのね。
Pythonは基本的に文中の括弧を極力書かないようにしてんのか。

```py
if 条件式1:
    処理
elif 条件式2:
    処理
else:
    処理
```

[複数の条件分岐(if...elif...else)](http://www.pythonweb.jp/tutorial/if/index8.html)

# ブロックコメントアウト
基本的に # をつけた行コメントしかできないらしい。
クォーテーションでそのかわりとなる役割が可能。
それもシングルとダブルでネストが可能。

```py
"""
print "hello"
'''
print "heyhey"
'''
"""
```

[コメントアウト](http://www.python-izm.com/contents/basis/comment_out.shtml)

# オブジェクトの識別値
Pythonの全てのオブジェクトには、それぞれ固有の「識別値（ID）」を持っている。
で、**immutable**なオブジェクトと**mutable**なオブジェクトがある。
**immutable**なオブジェクトはオブジェクトの値が変更されたときに同時にIDも変更になるオブジェクト。
普通の整数とか文字列とか？

**mutable**なオブジェクトは、反対にIDが固定のオブジェクト。Listとか。

なので以下の状態だとPythonは**IDに変化がないから指すオブジェクトも同一のもの**という認識になるらしい。
ほー、覚えておこ。

```py
a = [1,2,3,4,5]
# aというリストの中身をコピーしたbというリストを作った(つもり)
b = a

# 後からa[2]の値を変更した(つもり)
a[2] = 5
print(a) # [1, 2, 5, 4, 5]
print(b) # [1, 2, 5, 4, 5]
```

[Python のリストの扱いで注意すること](http://qiita.com/utgwkk/items/5ad2527f19150ae33322)

# 多次元配列
Pythonでは多次元配列を実現しようとするとき、
- 多重リスト
- NumPy 配列
の2つがあるらしい。
NumPyが静的で高速なので、こっち使ってみよう。

```py
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6]])
print a
# [[1 2 3]
#  [4 5 6]]
```

[NumPy 配列の基礎](http://www.kamishima.net/mlmpyja/nbayes1/ndarray.html)


# クラス

```py
class Spam:
    val = 100
    def ham(self):
        self.egg('call method')
    def egg(self, msg):
        print("{0}".format(msg))
        print(("{0}".format(self.val))

spam = Spam()
spam.ham()

# --- output ---
# call method
# 100

```
なんじゃい、*self*。

>Pythonではメソッドは最低1つの引数を持ちます。この最初の引数は必ずselfという名前にする慣例があります。

なるほど。

[Python基礎講座(13 クラス)](http://qiita.com/Usek/items/a206b8e49c02f756d636)

# format関数

文字列への変数の埋め込みに使われる。

```py
'任意の文字列{}任意の文字列'.format(変数)
```

**引数で指定**、もできる

```py
apple = 50
orange = 100
total = apple + orange

print('りんご：{0}円 みかん：{1}円 合計：{2}円'.format(apple, orange, total))

# --- output ---
# りんご：50円 みかん：100円 合計：150円
```

[【Python入門】format関数で文字列の書き方](http://qiita.com/Morio/items/b79ead5f881e6551d9e1)

---

# 関数の戻り値が複数の時

タプルでもらって、そのまま要素を呼び出せば値が使える。
あんまりこんな書き方したことないから新鮮だな。

```py
def tasu(x):
    a = x + 1
    str = "data : "
    return (str, a)

(n, m) = tasu(1)
print n
print m

# --- output ---
# data :
# 2
```

[関数で複数の返り値を返す方法](http://oppython.hatenablog.com/entry/2015/09/22/203634)

---

# 数値の末尾の"L"

```py
RECVMSG           = 0x00000021L
```

どっかのサンプルコードを見てたら16進数のあとに"L"がついていてなんじゃこりゃとおもった。

これは「長整数」といって、整数と同じだが扱える桁数の限度がなくなる、とのこと。
つけずに桁数オーバーしても勝手に長進数に変換される。

16進数は先頭に"0x"、8進数は"0"をつけるとそう扱われる。
どちらもprintすると10進数で出力される。

[数値リテラル](https://www.pythonweb.jp/tutorial/num/index1.html)

---

# 【ラズパイ】喋らす

OpenJTalkを入れてみた。
[音声合成をする方法(Open JTalk)](http://www.raspberrypirulo.net/entry/2017/08/29/%E9%9F%B3%E5%A3%B0%E5%90%88%E6%88%90%E3%82%92%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%28Open_JTalk%29)

漢字もいけた。
そこそこ自然な発話だけど、機械がしゃべる分にはSF感が足りないから使わないかも。

---

Python楽しい！！！！！