iOSエンジニアによるPython3入門(文法編)

## イントロ
[前回のiOSエンジニアによるPython3入門(環境整備編)](https://qiita.com/otis/items/d82a4f591dc1fe31ad6a)でmacOSにPython3の環境を整えたので、引き続き簡易的な文法の話をする

## 対象者
* Python初心者
* 他言語経験者 (特にSwift3以降を触ったことある人向け)

## Python3のざっくりとした特徴や説明
* Pythonは動的型付き言語で、変数に対して型宣言することはない。
* Python3では文字エンコードはUTF-8がデフォルトとして固定されている

## 記事の概要や説明
* Swiftと対比的に記載していく
* SwiftやSwift2系でも使用できるコードもあるが、Swift3以降を基準に記載
* `Swift3orLater`とあればSwift3以降で、`Swift4`とあればSwift4でのサンプルコードを表す。

## 文法
#### 定数
```Swift3orLater.swift
// グローバルスコープの時
let MAX_SIZE = 44.0
let MIN_SIZE: Double = 0.0

// ローカルスコープの時
static let MAX_SIZE = 44.0
static let MIN_SIZE: Double = 0.0
```
Pythonでは、定数は存在しない(サポートされていない)
変数名の付け方で定数として扱うよう運用カバーしている模様
主に大文字のスネークケースで記載する

```Python3.py
MAX_SIZE = 44.0
# MAX_SIZE = 60.0 定数をサポートしていないため値を上書きできてしまう
MIN_SIZE = 0.0
```

#### 変数
```Swift3orLater.swift
// 2値
let bool1 = true                    // true
let bool2 = false                   // false

// 2進数
let bit1 = 0b0000_1010              // 10
let bit2 = 0b01_01_01_01            // 85

// 16進数
let hex1 = 0xFFFFFF                 // 16777215
let hex2 = 0x08_08_08               // 526344

// 整数
let integer1 = 256                  // 256
let integer2: Int = -128            // -128
let integer3 = 1_000_000            // 1000000

// 小数
let double1 = 3.14                  // 3.14
let double2: Double = -1.414213     // -1.414213
let double3 = 3.14_15_92            // 3.141592
```

Swiftと割と同じ…というかSwiftがPythonから輸入してきたと思うが、`_`で桁区切りの書き方ができる。桁が多い時は`_`区切り使うと可読性もあがるので個人的には好き。

```Python3.py
# 2値
bool1 = True                    # True
bool2 = False                   # False

# 2進数
bit1 = 0b0000_1010              # 10
bit2 = 0b01_01_01_01            # 85

# 16進数
hex1 = 0xFFFFFF                 # 16777215
hex2 = 0x08_08_08               # 526344

# 整数
integer1 = 256                  # 256
integer2 = -128                 # -128
integer3 = 1_000_000            # 1000000

# 小数
double1 = 3.14                  # 3.14
double2 = -1.414213             # -1.414213
double3 = 3.14_15_92            # 3.141592
```

#### 文字列
```Swift3orLater.swift
let string1: String = "Hello World"     // Hello World
let string2 = "Hello" + " " + "World"   // Hello World
```

Pythonでは、`”`または`’`で括ることで文字列になる。(Pythonのコードを見ていると`’`で括ることが多い印象)
Swift同様`+`で文字列を連結させれる他、括ったものを並べても連結される。
下記のstring3がその例で、`'Hello'`と`’ ‘(半角スペース)`と`"World"`を並べることで`Hello World`の文字列になっている。
可読性考えると、`+`での連結が1番わかりやすいと思う。

```Python3.py
string1 = "Hello World"             # Hello World
string2 = 'Hello' + ' ' + "World"   # Hello World
string3 = 'Hello' ' ' "World"       # Hello World
```

#### 複数行文字列
```Swift4.swift
// ダブルコンパイル\nメテオリック・スリーシスターズ
let multiString1 = """
ダブルコンパイル
メテオリック・スリーシスターズ
"""

let multiString2 =
"""
ダブルコンパイル
メテオリック・スリーシスターズ
"""
```

Swiftでは、Swift4からサポートされた複数行文字列(multi-line-string)がPythonでも使える。というかこれも輸入されたみたい。

Swiftと異なりPythonでは、`=`と同じ行に`"""(または''')`がある必要がある。

```Python3.py
# ダブルコンパイル\nメテオリック・スリーシスターズ
multiString1 = """
ダブルコンパイル
メテオリック・スリーシスターズ
"""

multiString2 = '''
ダブルコンパイル
メテオリック・スリーシスターズ
'''
```

#### コメント
```Swift3orLater.swift
// 1行コメント

/// Doc用に3つ並べた書き方することもある

/*
 複数行コメント
 */
```

SwiftとPythonは似ているところも多いが、コメントは似つかない。
Objective-Cとかの流れから`//`を使うのはSwiftとしては当然なので、`#`にならなかったのは良かった。

Pythonでは、複数行コメント用の正規な方法がなく、複数行文字列を流用する。
変数に代入しないことで、コードとしては無視されるので、特にパフォーマンス等にも問題ないみたい。
(後述するが、複数行文字列の表記を流用しているため、インデント位置がおかしいとエラーになる)

```Python3.py
# 1行コメント

"""
厳密には異なるが
複数行コメント
"""
```

#### ログ
```Swift3orLater.swift
print("hello world")	// 文字列"hello world"を表示
print(someObject)		// someObjectを表示
```

SwiftとPythonで差異はない

```Python3.py
print("hello world")	# 文字列"hello world"を表示
print('hello world')	# 文字列"hello world"を表示
print(someObject)		# someObjectを表示
```

#### 算術演算子
```Swift3orLater.swift
let addition = 5 + 3            // 8
let subtraction = 5 - 3         // 2
let multiplication = 5 * 3      // 15
let divisionInt = 5 / 3         // 1
let divisionDouble = 5.0 / 3.0  // 1.666666666666667
let remainder = 5 % 3           // 2
let power = pow(5, 3)           // 125
let square = sqrt(5)            // 2.23606797749979
```

Pythonの冪乗は、`**`でかけるのが楽で少しいいなーと思う。

```Python3.py
addition = 5 + 3        # 8
subtraction = 5 - 3     # 2
multiplication = 5 * 3  # 15
divisionInt = 5 // 3    # 1
divisionDouble = 5 / 3  # 1.6666666666666667
remainder = 5 % 3       # 2
power = 5 ** 3          # 125
square = math.sqrt(5)   # 2.23606797749979
```

#### 比較演算子
`>`、`>=`、`<`、`<=`、`==`、`!=`これらの使用方法はSwiftとPythonで同じため省略

#### 論理演算
```Swift3orLater.swift
let number1 = 0
let number2 = 1
let number3 = -1
let bool1 = number1 == 0                // true
let bool2 = number2 > 0 && number3 < 0  // true
let bool3 = number2 > 0 || number3 > 0  // true
let bool4 = !(number2 == 0)             // true
// let bool4 = !number2 == 0             // 括弧がないとNG
```

Pythonでは、`&&`が`and`、`||`が`or`、`!`が`not`と文字で表現されている。
ちなみに`xor`は試した限りエラーになったので存在しないと思われる。

```Python3.py
number1 = 0
number2 = 1
number3 = -1
bool1 = number1 == 0                # True
bool2 = number2 > 0 and number3 < 0 # True
bool3 = number2 > 0 or number3 > 0  # True
bool4 = not(number2 == 0)           # True
# bool4 = not number2 == 0           # 括弧がなくてもOK
```

#### 制御文(if)
```Swift3orLater.swift
let number = 4
if number > 0 {
    // number > 0 == true
} else if number < 0 {
    // number < 0 == true
} else {
    // !(number > 0 == true || number < 0 == true)
}
```

大きな違いとして、`{ }`でスコープを表すSwiftに対してPythonは**インデント**でスコープを表す。それ故、Pythonではインデントはかなり重要な要素だったりする。複数行文字列を使用した複数行コメントのところでも軽く触れたが、インデントでスコープを扱っているため、インデント位置がおかしいだけでエラーとなるので、気をつけたい。

また、`else if`の代わりに`elif`といった省略されたようなものを使用したり、制御文の末尾には`:`をつけるようになっている。

```Python3.py
number = 4
if number > 0:
    # number > 0 == True
elif number < 0:
    # number < 0 == True
else:
    # not(number > 0 == True or number < 0 == True)
```

#### 制御文(条件式)
```Swift3orLater.swift
let number5 = 1
let string5 = number5 > 0 ? "foo" : "bar"   // foo
```

Swift等の他言語でいう三項演算子はなく、それに近い条件式というものがPythonにはある。

並び順が特殊で、`真の時の値``if``条件``else``偽の時の値`で書く。

```Python3.py
number5 = 1
string5 = 'foo' if number5 > 0 else 'bar'  # foo
```

#### 制御文(for)
```Swift3orLater.swift
for i in 0..<5 {}                               // 0,1,2,3,4
for i in 5..<10 {}                              // 5,6,7,8,9
for i in (1...3).reversed() {}                  // 3,2,1
for i in stride(from: 0, through: 10, by: 3) {} // 0,3,6,9
```

Swiftは`...`や`..<`といった直感的で範囲を指定できるところは良いが、2以上ずつカウントアップした時とかに`stride(from:through:by:)`がいきなり出てきて微妙な統一感のなさが嫌だったりする。

一方で、Pythonは基本`range()`で表せるのは楽かつ統一的でわかりやすくていいと思う。

```Python3.py
for i in range(5):              # 0,1,2,3,4
for i in range(5, 10):          # 5,6,7,8,9
for i in reversed(range(1, 4)): # 3,2,1
for i in range(0, 10, 3):       # 0,3,6,9
```