Python入門

# **はじめに**
ドットインストールのPython入門やってみたのでその勉強記録です！

# **環境**
- Python 2.6.6
- CentOS6.7


# **概要**
- Pythonの基本的なお作法
- 変数とデータ型
- 数値
- 文字列
- 文字列操作の命令
- 数値と文字列の相互変換
- リスト
- タプル
- セット
- 辞書
- 文字列にデータを組み込む
- `if`文で条件分岐
- ループ処理
- 関数
- 変数のスコープと`pass`
- オブジェクト
- クラスと継承
- モジュールを使ってみる

# **Pythonの基本的なお作法**
## `coding: UTF-8`をつける
### 付けない場合
```py:hello.py
# コメント
print "hello, world!"
```

```shell-session:定義しないでコードに日本語とか入れてるとこうなる
$ python hello.py
  File "hello.py", line 1
SyntaxError: Non-ASCII character '\xe3' in file hello.py on line 1, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
```

### 付けた場合
```py:hello.py
# coding: UTF-8
# コメント
print "hello, world!"
```

```shell-session:定義していればコードに日本語とか入れていても大丈夫
$ python hello.py
hello, world!
```

## コーディング規約
- [Python コードのスタイルガイド](http://pep8-ja.readthedocs.io/ja/latest/)を参照

## その他
- 文の区切りに`;`が使えるが非推奨
- 拡張子は`.py`
- コメントは`#`
- 字下げ（インデント）が厳格

# **変数とデータ型**
## 変数
- データにつけるラベル
- 大文字小文字を区別する

## Pythonで扱えるデータ型
- 数値
- 文字列
- 真偽値
- リスト（配列）
- タプル
- 辞書（連想配列、ハッシュ）

# **数値**
## Pythonで扱える数値
- 整数
- 小数
- 複素数

## 演算子
| 項目 | 演算子 |
|:-:|:-:|
| 足し算 | + |
| 引き算 | - |
| 掛け算 | * |
| 割り算 | / |
| 商 | // |
| 余り | % |
| べき乗 | ** |

## 演算に関するルール
- 整数と小数の演算をした場合、必ず結果が小数になる
- 整数同士の割り算は切り捨ての整数となる

# **文字列**
## 日本語を扱う場合
### 以下のように`u"こんにちは"`のようにしないと<br>`len`等の文字列を扱う命令が正しく動作しない場合がある
```pycon
>>> print len("こんにちは")
15
>>> print len(u"こんにちは")
5
```

## 文字列の演算
### 連結
```pycon
>>> print "Hello " + "World!"
Hello World!
```

### 繰り返し
```pycon
>>> print "Hello World! " * 3
Hello World! Hello World! Hello World!
```

## 文字列のエスケープ
```pycon:改行、タブ、シングルクォーテーションのエスケープ
>>> print 'hello\n wo\trld\\ it\'s the end'
hello
 wo	rld\ it's the end
```

```pycon:改行付きでのデータの表示
>>> print """<html lang="ja">
... <body>
... </body>
... </html>"""
<html lang="ja">
<body>
</body>
</html>
```


# **文字列操作の命令**
## 文字数のカウント
```pycon
>>> a = "abcdef"
>>> len(a)
6
```

## 文字列の検索
```py
>>> a = "abcdef"
>>> a.find("c")
2
```

## 文字列の切り出し
```pycon
>>> a = "abcdef"
# 2文字目から３文字目までを切り出し
>>> print a[1:3]
bc

# 最初の文字から３文字目までを切り出し
>>> print a[:3]
abc

# 3文字目から最後の文字までを切り出し
>>> print a[2:]
cdef

# 3文字目から最後から2番目の文字までを切り出し
>>> print a[2:-1]
cde
```

# **数値と文字列の相互変換**
| パターン | 命令 |
|:-:|:-:|
| 文字列から整数値 | `int` |
| 文字列から小数値 | `float` |
| 数値から文字列 | `str` |

```pycon:失敗例
>>> age = 20
>>> print "I am  " + age + " years old!"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects
```

```pycon:成功例
>>> age = 20
>>> print "I am  " + str(age) + " years old!"
I am  20 years old!
```


# **リスト**
## リストとは
- 他の言語でいうところの**配列**
- 文字列に使えるいくつかの命令がそのまま使える

## `len` - 要素の数を調べる
```pycon
>>> sales = [255, 100, 353, 400]
>>> print len(sales)
4
```

## `[]` - 切り出しを行う
```pycon
>>> sales = [255, 100, 353, 400]
>>> print sales[2]
353
```

## `in` - 存在チェック
```pycon
>>> sales = [255, 100, 353, 400]
>>> print 100 in sales
True
```

## `range` - 連番のリストを作成
```pycon
>>> print range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> print range(3, 9)
[3, 4, 5, 6, 7, 8]
>>> print range(3, 10, 2)
[3, 5, 7, 9]
```

## **リストで使える便利な命令**
### `sort`
- 小さい順に並び替える

```pycon
>>> sales = [255, 100, 353, 400]
>>> sales.sort()
>>> print sales
[100, 255, 353, 400]
```

### `reverse`
- 要素の順番を逆にする
- 大きい順に並び替えしたい場合、`sort`してから`reverse`する

```pycon
>>> sales = [255, 100, 353, 400]
>>> sales.reverse()
>>> print sales
[400, 353, 100, 255]
```

### `split`
```pycon
>>> d = "2016/07/15"
>>> print d.split("/")
['2016', '07', '15']
```

### `join`
```pycon
>>> a = ["a", "b", "c"]
>>> print "-".join(a)
a-b-c
```

### `map`
- リストの各要素に対して関数の処理を適用させる命令

```py
def power(x)
    return x * x
print map(power, [2, 5, 8])

#=> [4, 25, 64]
```





# **タプル**
- 基本的にリストと同じだが、要素の変更ができないという特徴がある
- 最初から変更できないデータだと示すことによって、計算速度を早くしたり、変な間違いが起きないようにする
- リストで使ったような命令も使える

## タプルからリストへの変更
```pycon
>>> a = (2, 5, 8)
>>> print a
(2, 5, 8)
>>> b = list(a)
>>> print b
[2, 5, 8]
```

## リストからタプルへの変更
```pycon
>>> b = [2, 5, 8]
>>> c = tuple(b)
>>> print c
(2, 5, 8)
```

# **セット**
- 集合型と呼ばれたりする
- 要素が並んだもので、重複を許さないという特徴がある

```pycon
>>> a = set([1, 2, 3, 4])
>>> print a
set([1, 2, 3, 4])
```

```pycon:重複箇所は表示されない
>>> a = set([1, 2, 3, 4, 2, 3])
>>> print a
set([1, 2, 3, 4])
```

## 集合の演算
### 差集合
```pycon:aにあってbにないもの
>>> a = set([1, 2, 3, 4])
>>> b = set([3, 4, 5])
>>> print a - b
set([1, 2])
```

### 和集合
```pycon:aにもbにもあるもの
>>> a = set([1, 2, 3, 4])
>>> b = set([3, 4, 5])
>>> print a | b
set([1, 2, 3, 4, 5])
```

### 積集合
```pycon:aとbで重複するもの
>>> a = set([1, 2, 3, 4])
>>> b = set([3, 4, 5])
>>> print a & b
set([3, 4])
```

### どちらにしかないもの
```pycon
>>> a = set([1, 2, 3, 4])
>>> b = set([3, 4, 5])
>>> print a ^ b
set([1, 2, 5])
```

# **辞書**
- 他の言語で言うところの連想配列やハッシュのようなもの
- 基本は`key`と`value`がペアになったもの

## 基本的な使い方
```pycon
>>> sales = {"hoge":200, "hogehoge":300, "hogeo":500}
>>> print sales
{'hogeo': 500, 'hogehoge': 300, 'hoge': 200}
```

```pycon
>>> sales = {"hoge":200, "hogehoge":300, "hogeo":500}
>>> sales["hogehoge"] = 800
>>> print sales
{'hogeo': 500, 'hogehoge': 800, 'hoge': 200}
```

## キーの存在確認
```pycon
>>> sales = {"hoge":200, "hogehoge":300, "hogeo":500}
>>> print "hoge" in sales
True
```

## キーの一覧を確認
```pycon
>>> sales = {"hoge":200, "hogehoge":300, "hogeo":500}
>>> print sales.keys()
['hogeo', 'hogehoge', 'hoge']
```

## 値の一覧を確認
```pycon
>>> sales = {"hoge":200, "hogehoge":300, "hogeo":500}
>>> print sales.values()
[500, 800, 200]
```

## 両方の一覧を確認
```pycon
>>> sales = {"hoge":200, "hogehoge":300, "hogeo":500}
>>> print sales.items()
[('hogeo', 500), ('hogehoge', 800), ('hoge', 200)]
```

# **文字列にデータを組み込む**
| 項目 | 英語 | 意味 |
|:-:|:-:|:-:|
| %d | decimal | 整数 |
| %f | float | 小数 |
| %s | string | 文字列 |

```pycon
>>> a = 10
>>> b = 1.234234
>>> c = "hoge"
>>> d = {"hoge":200, "hogehoge":500}
>>> print "age: %d" % a
age: 10
>>> print "price: %f" % b
price: 1.234234
>>> print "name: %s" % c
name: hoge
```

```pycon:10桁分表示させる
>>> print "age: %10d" % a
age:         10
```

```pycon:余った桁を0で埋める
>>> print "age: %010d" % a
age: 0000000010
```

```pycon:小数点2桁まで表示させる
>>> print "price: %.2f" % b
price: 1.23
```

```pycon:辞書型の場合特定のキーの値を取り出せる
>>> print "sales: %(hoge)d" % d
sales: 200
```

```pycon:複数の値を同時に指定
>>> print "%d and %f" % (a, b)
10 and 1.234234
```

# **`if`文で条件分岐**
## 基本的な条件分岐
```py
score = 70
if score > 60:
    print "OK!"
#=> OK!
```

```py
score = 70
if score > 60 and score < 80:
    print "OK!"
#=> OK!
```

```py:このようにも書ける
score = 70
if 60 < score < 80:
    print "OK!"
#=> OK!
```

## `else` / `elif` による条件分岐
```py
score = 45
if score > 60:
    print "ok!"
elif score > 40:
    print "soso..."
else:
    print "ng!"
#=> soso...
```

```py:このようにも書ける
score = 45
print "OK!" if socre > 60 else "NG!"
#=> NG!
```

# **ループ処理**
## `for`でループ
```py
sales = [13, 3423, 31, 234]
sum = 0
for sale in sales:
    sum += sale
print sum
#=> 3701
```

```py:このようにも書ける
sales = [13, 3423, 31, 234]
sum = 0
for sale in sales:
    sum += sale
else:
    print sum
#=> 3701
```

```py
for i in range(10):
    print i
#=> 0..9までが表示される
```

```py:continue
for i in range(10):
    if i == 3:
        continue
    print i
#=> 3を除いた0..9までが表示される
```

```py:break
for i in range(10):
    if i == 3:
        break
    print i
#=> 0..2までが表示される
```

## 辞書でループ
- `iter`は`iteration`の略

```py:辞書アイテムを表示させる
users = {"hoge":200, "hogehoge":300, "hogeo":500}
for key, value in users.iteritems():
    print "key: %s value: %d" % (key, value)
#=> key: hogeo value: 500
#=> key: hogehoge value: 300
#=> key: hoge value: 200
```

```py:辞書のキーを表示させる
users = {"hoge":200, "hogehoge":300, "hogeo":500}
for key in users.iterkeys():
    print key
#=> hogeo
#=> hogehoge
#=> hoge
```

```py:辞書の値を表示させる
users = {"hoge":200, "hogehoge":300, "hogeo":500}
for value in users.itervalues():
    print value
#=> 500
#=> 300
#=> 200
```

## `while`でループ
```py
n = 0
while n < 5:
    print n
    n += 1
else:
    print "end"
#=> 0
#=> 1
#=> 2
#=> 3
#=> 4
#=> 5
#=> end
```

```py:endが表示されない
n = 0
while n < 5:
    if n == 3
        break
    print n
    n += 1
else:
    print "end"
#=> 0
#=> 1
#=> 2
```

# **関数**
## 基本的な関数
```py:基本形
def hello():
    print "hello"
hello()
#=> hello
```

```py:引数を使う
def hello(name):
    print "hello %s" % name
hello("tom")
#=> hello tom
```

```py:引数を使う
def hello(name):
    print "hello %s" % name
hello("tom")
hello("bob")
#=> hello tom
#=> hello bob
```

```py:引数を2つ使う
def hello(name, num):
    print "hello %s! " % name * num
hello("tom", 2)
hello("bob", 3)
#=> hello tom! hello tom!
#=> hello bob! hello bob! hello bob!
```

```py:引数にデフォルト値を持たせる
def hello(name, num = 3):
    print "hello %s! " % name * num
hello("tom", 2)
hello("bob")
# このようにも書ける
hello(num = 2, name = "serve")

#=> hello tom! hello tom!
#=> hello bob! hello bob! hello bob!
#=> hello steve! hello steve! hello steve!
```

```py:返り値を持たせる
def hello(name, num = 3):
    return "hello %s! " % name * num
s = hello("bob")
print s

#=> hello bob! hello bob! hello bob!
```

## 無名関数(`lambda`)
```py
def power(x):
    return x * x
print map(power, [2, 5, 8])

#=> [4, 25, 64]
```

```py:このように書ける
print map(lamdba x:x * x, [2, 5, 8])

#=> [4, 25, 64]
```

# **変数のスコープと`pass`**
- 関数内で定義した`name`は関数の外で定義した`name`と別物

```py
name = "hoge"
def hello():
    name = "hogehoge"
print name

#=> hoge
```

- `hello2()`という関数を定義して中身を後で書きた良い場合、コロンのあと字下げして`pass`と書いておくとなにも処理しないという意味になる

```py
def hello2()
    pass
```

# **オブジェクト**
## 用語説明
| 用語 | 説明 |
|:--|:--|
| オブジェクト | 変数と関数をまとめたもの |
| クラス | オブジェクトの設計図 |
| インスタンス | クラスを実体化したもの |

## クラスの作成
```py
class User(object):
    def __init__(self, name):
        self.name = name
    def greet(self):
        print "my name is %s!" % self.name

bob = User("Bob")
tom = User("Tom")
print bob.name
bob.greet()
tom.greet()

#=> Bob
#=> my name is Bob!
#=> my name is Tom!
```

## クラスと継承
- クラスの性質はそのままに、すこし違う性質のオブジェクトを作りたい場合に継承を行う

```py
class User(object):
    def __init__(self, name):
        self.name = name
    def greet(self):
        print "my name is %s!" % self.name
class SuperUser(User)
    def shout(self)
        print "%s is SUPER!"

bob = User("Bob")
tom = SuperUser("Tom")
tom.greet()
tom.shout()

#=> my name is Tom!
#=> Tom is SUPER!
```

# **モジュールを使ってみる**
- モジュールとはPythonが予め用意している便利な命令が詰まったもの
- [公式サイトのモジュール一覧](http://docs.python.jp/2/py-modindex.html)
- 複数のモジュールを呼び出したい場合にはカンマ区切りでOK

```py:mathモジュール
import math
print math.ceil(5.2)
#=> 6.0
```

```py:randomモジュール
import random
for i in range(5):
    print random.random()
#=> 0.761598550441
#=> 0.180484460723
#=> 0.494892311516
#=> 0.672065106987
#=> 0.561810023764
```

```py:モジュール内の一部だけ呼び出す場合
from datetime import date
print date.today()
2016-07-13
```