動かしながら学ぶPython入門~その２：変数操作と画面入力~

# はじめに

この記事は、連載です。
前回の[動かしながら学ぶPython入門~その１：ソースファイル作成から画面に表示まで~](https://qiita.com/kira4845/items/a9459a56a8f78b97ee05)を
先に読んでからのほうが理解しやすいと思います。

タイトルに`【コラム】`とついているセクションは、動作や書式に直接の関係はありません。
ちゃっちゃと動かしてみたい人は読み飛ばしても問題ありません。
もちろん、せっかく書いたので読んでもらえたほうが嬉しいです。

## 対象
- `Python`の初歩中の初歩を学習したい人

## 執筆時の環境

- OS: Windows10
- Python: 3.7.3
- エディタ：VSCode

## 本文中の用語

| 用語 | 概略 |
|:--|:--|
|ターミナル|コマンドでコンピュータに命令を出すインターフェース<br>Windowsだと"コマンドプロンプト"や"PowerShell"が標準|
|Pythonインタプリタ|Pythonのソースコードの解釈と実行を行うアプリケーション<br>詳しくは[コラム][インタプリタとは]を参照|
|ソースファイル|アプリケーションの元となる、プログラム言語の決まった書式で書かれたファイル|
|パス|ファイルやディレクトリ(フォルダ)のコンピュータ上の場所を表す文字列|
|テキストエディタ|テキストファイルを編集するアプリケーション|

# 変数を使ってみる

## 組み込み型と書式

変数でどのようなデータを扱うかを表すのが"型"だが、ユーザが任意の型を作ることもできるので、区別する意味でプログラム言語仕様上標準で定義されている型を**組み込み型**と呼んでいる。

今回のセクションで扱う組み込み型は次の3つ。

|名称|概略|
|:--:|:--|
|[int]|整数|
|[float]|少数|
|[str]|文字列|

もちろん他にも沢山あって、Pythonの組み込み型については、別でまとめた記事があるので、詳細は[こちらの記事](https://qiita.com/kira4845/items/20e54216f048961eddad)を参照してもらいたい。

[数値型]:https://qiita.com/kira4845/items/20e54216f048961eddad#数値型
[int]:https://qiita.com/kira4845/items/20e54216f048961eddad#int
[float]:https://qiita.com/kira4845/items/20e54216f048961eddad#float
[complex]:https://qiita.com/kira4845/items/20e54216f048961eddad#complex
[文字列型]:https://qiita.com/kira4845/items/20e54216f048961eddad#文字列型
[str]:https://qiita.com/kira4845/items/20e54216f048961eddad#str
[シーケンス型]:https://qiita.com/kira4845/items/20e54216f048961eddad#シーケンス型
[list]:https://qiita.com/kira4845/items/20e54216f048961eddad#list
[tuple]:https://qiita.com/kira4845/items/20e54216f048961eddad#tuple
[range]:https://qiita.com/kira4845/items/20e54216f048961eddad#range
[set]:https://qiita.com/kira4845/items/20e54216f048961eddad#set
[dict]:https://qiita.com/kira4845/items/20e54216f048961eddad#dict
[bool]:https://qiita.com/kira4845/items/20e54216f048961eddad#bool

### 変数を作る

変数を作るのは非常に簡単で、代入演算子`=`を使って、

```:書式
変数名 = 代入したい値
```

と書くだけでいい。

### 変数を読む

変数を読むのも非常に簡単。

```:書式
変数名
```

作成済みの変数名を書くだけで、中身の参照として解釈される。

### 例題

<a name="例題1"></a>

実行したら、自分の名前を表示するソースファイルを作ってみよう。
筆者のHNでやるとこんな感じ。

```text:実行画面
> python .\my_name_is.py
どーも
TAKE
です
```

<details><summary><b>回答例を見る</b></summary><div>

```python:my_name_is.py
name = "TAKE"
print("どーも")
print(name)
print("です")
```
</div></details>

## 文字列に組み込んでみる

[組み込み型と書式](#組み込み型と書式)の[例題](#例題1)では、

```
どーも
TAKE
です
```

のように、それぞれ改行して表示されてしまっているが、このような文面なら`どーもTAKEです`と1行で表示したいところだろう。
かといって、このように書いてみるとエラーが出て実行できない。

```python:my_name_is_oneline_fail.py
name = "TAKE"
print("どーも"name"です")
```
```text:実行結果
> python .\my_name_is_oneline_fail.py
  File "my_name_is_oneline_fail.py", line 2
    print("どーも"name"です")
                  ^
SyntaxError: invalid syntax
```

実は、これを実現する機能が[文字列型][str]に備わっている。

```python:my_name_is_oneline_success.py
name = "TAKE"
print("どーも{}です".format(name))
```
```text:実行結果
> python .\my_name_is_oneline_success.py       
どーもTAKEです
```

ポイントは、文字列中にある`{}`と文字列の後ろについた`.format()`。
実行結果を見れば予想がつくと思うが、`{}`の部分を`.format()`の`()`内に書いた変数値で置換してくれる。

さらに、置換できるのは1つではなく、`{}`を複数埋め込んで、`.format()`の`()`内で`,`で区切って複数の値を与えれば先頭から順番に置換してくれる。
さらにさらに、置換できるの文字列だけではなく、[int]や[float]解いた[数値型]も無変換で置換できる。

```python:my_name_is_oneline_multi.py
name = "TAKE"
age = 17

print("どーも{}です、{}歳です、嘘です".format(name, age))
```
```text:実行結果
> .\my_name_is_oneline_multi.py
どーもTAKEです、17歳です、嘘です
```

かなり出番が多い機能なので覚えておこう。
他にオプション的な機能もあるのだが、追々出番があるタイミングで紹介する予定。

ちなみに、文字列の連結だけならこういう書き方でもいい。

```python:my_name_is_oneline_other.py
name = "TAKE"
print("どーも" + name + "です")
```
```text:実行結果
> .\my_name_is_oneline_other.py
どーもTAKEです
```

個人的には`format()`のほうが、文字列が1つの塊で表現できるので好み。

## 算術演算をやってみる

これまでは、文字列しか扱ってこなかったが、**変数**というくらいなので、やはり**変化する数値**を扱ってこそ真髄だろう。
Pythonでは算術演算を扱うための演算子は次のものがある。

|演算子|計算|使用例|
|:--:|:--|:--|
|`+`|加算(足し算)|`x = a + b`|
|`-`|減算(引き算)|`x = a - b`|
|`*`|乗算(掛け算)|`x = a * b`|
|`/`|除算(割り算)|`x = a / b`|
|`%`|剰余(割り算の余り)|`x = a % b`|
|`**`|べき乗|`x = a ** b`|
|`//`|切り捨て除算|`x = a // b`|

まずは、四則演算を試してみよう。
[対話モード](https://qiita.com/kira4845/items/a9459a56a8f78b97ee05#%E5%AF%BE%E8%A9%B1%E3%83%A2%E3%83%BC%E3%83%89%E3%81%A7%E5%AE%9F%E8%A1%8C)で次のコマンドを実行してみよう。

```python:対話モードで実行
>>> 10 + 3
13
>>> 10 -3
7
>>> 10 * 3
30
>>> 10 / 3
3.3333333333333335
```

注意点としては、整数同士の演算でも**除算だけは[少数(float)][float]が返される**こと。

実際のアプリケーションでは、"人や物の数を算出する"など、整数しか表現できないものを扱うシチュエーションも多い。
だからなのかは知らないが、**切り捨て除算**の演算子が用意されている。

```python:対話モードで実行
>>> 10 // 3
3
```

**切り上げ除算**の演算子は存在しないが、切り捨て除算の演算を工夫することで対応できる。([参考][切り上げ切り捨て])

```python:対話モードで実行
>>> -(-10 // 3)
4
```

少しわかりにくいが、符号を反転して**切り捨て除算**することで、切り捨てによる整数部の変化も逆転する。
![切り上げ切り捨て.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291298/df04defe-c07f-7168-3a0e-8a944d0fcf81.png)
なので、**符号反転した被除数を切り捨て除算してから再度符号反転**することで、切り上げになっている。

また、除算関係でもう一つ**剰余**を求める演算子も用意されていて、ポピュラーな出番としては"偶数/奇数判定"や、切り捨て除算と組み合わせての"各位別の値抽出"などがある。

"偶数/奇数判定"は、判定したい数値を2で割った剰余が**`0`なら偶数、`1`なら奇数**と判断できる。

```python:対話モードで実行
>>> 0 % 2
0
>>> 1 % 2
1
>>> 2 % 2
0
>>> 3 % 2
1
```

"各位別の値抽出"は、抽出元の値を各位の最小値(10の位なら10、100の位なら100といった感じ)で割った商にその位の値が現れるので、同じく各位の最小値で割った剰余にはその位より下位の値が現れる。
この特性を生かして、**求めたい位の一つ上位最小値で剰余を求め、求めたい位の最小値で切り捨て除算する**と、求めたい位の値だけを取り出せる。

```python:対話モードで実行
>>> 123 // 100
1
>>> (123 % 100) // 10
2
>>> 123 % 10
3
```

算術演算最後は**べき乗**で、プログラム中で複数種類の要素を関係式通りに計算してみる時とかに使える。

```python:対話モードで実行
>>> 11 ** 2
121
```

これらの紹介した演算子は、当然変数に対しても使える。
(というか、変数に使えないとほとんど意味がない)

```python:operator.py
a = 10
b = 3

print("{}+{} = {}".format(a, b, a + b))
print("{}-{} = {}".format(a, b, a - b))
print("{}×{} = {}".format(a, b, a * b))
print("{}÷{} = {}".format(a, b, a / b))
print("{}÷{}の剰余 = {}".format(a, b, a % b))
print("{}÷{}(切り捨て) = {}".format(a, b, a // b))
print("{}の{}乗 = {}".format(a, b, a ** b))
```
```text:実行結果
> python .\operator.py
10+3 = 13
10-3 = 7
10x3 = 30
10÷3 = 3.3333333333333335
10÷3の剰余 = 1
10÷3(切り捨て) = 3
10の3乗 = 1000
```

なお、演算子には優先順位があり、複数使ったときに優先順位に基づいて式が評価される[^1]。
今回紹介した演算子だと、`**` -> `*`,`/`,`//`,`%` -> `+`,`-`のような順序。
同じ優先順位の演算子が複数ある時は左に書いてある側から優先となる。
数学上の優先順位と合致しているので、わかりやすいと思う。

```python:対話モードで実行
>>> 1 + 2 * 3 * 4
25
```

上の例だと、次のように解釈された。

1. $\quad 2 \times 3 = 6$
2. $\quad 6 \times 4 = 24$
3. $\quad 24 + 1 = 25$

一々、優先順位を気にしないといけないかというと、書く分には必ずしもそうでもない。
これも数学上の考え方と同じだが、`()`は何よりも優先される。
なので、計算したい順番に`()`で囲っていけば、演算子の順序を覚えていなくても意図した通りの計算ができる。
(実装者の意図を明確にする意味で、優先順位上不要であっても`()`をつけることをコーディングルールで規定する場合もある)

先ほどの例をこのように解釈させたい時は、

1. $\quad 1 + 2 = 3$
2. $\quad 3 \times 4 = 12$
3. $\quad 3 \times 12 = 36$

```python:対話モードで実行
>>> (1 + 2) * (3 * 4)
36
```

こうすればよい。

[^1]: [演算子の優先順位](https://www.javadrive.jp/python/num/index3.html#section1)

### 例題

$2x^2 + 3y - 10$を算出するプログラムを作ってみよう。
$x,y$はソースコード中で決定していいが、出力に表示すること。

```text:画面出力
> python .\operator_example.py
x = 2
y = 3
7
```

<details><summary><b>回答例</b></summary><div>

```python:operator_example.py
x = 2
y = 3

print((2 * (x ** 2)) + (3 * y) - 10)
```

※この回答例では明示的に`()`をつけているが、今回の演算ならなくても正しく評価される。
</div></details>

### 算術代入演算子の存在

ここまで紹介した演算子には、代入演算子も存在する。
代入演算子を使うと、**"左辺の変数に対して右辺の値で各演算子の対応する処理をした後、左辺の変数に代入する"**という流れを簡潔に書ける。

|演算子|計算|使用例|等価の式|
|:--:|:--|:--|:--|
|`+=`|加算(足し算)と代入|`x += a`|`x = x + a`|
|`-=`|減算(引き算)と代入|`x -= a`|`x = x - a`|
|`*=`|乗算(掛け算)と代入|`x *= a`|`x = x * a`|
|`/=`|除算(割り算)と代入|`x /= a`|`x = x / a`|
|`%=`|剰余(割り算の余り)と代入|`x %= a`|`x = x % a`|
|`**=`|べき乗と代入|`x **= a`|`x = x ** a`|
|`//=`|切り捨て除算と代入|`x //= a`|`x = x // a`|

ちなみに、C言語などでは`x++`で`x = x + 1`と等価、`x--`で`x = x - 1`と等価な書き方があるが、Pythonではこれらは使えないため簡略せずに書くか、`x += 1`や`x -= 1`と書く必要がある。

## 定数について

プログラム言語には`変数`のほかに、`定数`を定義できるものがある。
これは、プログラム中で書き換えられることはないが、複数箇所で参照されるようなデータに名前を付けて代数的に使うもので、`変数`と違って**データの書き換えは禁止**されている。

しかし、**Pythonには`定数`の定義が存在しない**。
なので`変数`で代用するしかないのだが、**変数名が大文字英数字と`_`のみで構成されている場合は`定数`とする**という慣例がある(`変数`は小文字英数字と`_`のみで構成)
この慣例は、定数の定義が存在するCなどの他言語でも通ずるもので、可読性の観点でこのようになっている。
もちろん、Pythonの場合は、実体は変数なので書き換えてしまってもエラーも何も出ないので注意は必要。

また、[この記事][const自作]のような自作で定数を扱うモジュールを作っている人もいた。(便利そう...!)
本記事では、まだ外部ライブラリもモジュールインポートも説明していないが、習熟していけばこのようなことも可能になる。

##【コラム】型とPython

<details><summary>読む</summary><div>

プログラムには変数の**"型"**と呼ばれる概念があり、"数値を使える型"や"文字列を使える型"など型に応じて扱えるデータの種類が違う。
これは、コンピュータの中でデータはすべて`0`と`1`の羅列なので、変数を実際にメモリ空間に用意する時に、データの種類によって**メモリをどれくらい確保する必要があるか？**や**確保したメモリ範囲の値をどう解釈するのか？**といった情報を教えてあげる必要があるため。

ところが、Pythonの場合は**変数の型**として意識することはそれほどない。
これは、Pythonにおける変数というのは、あくまで"メモリ上の**オブジェクト[^1] (インスタンス)の場所**を表しているだけ"であるのと同時に、"そのオブジェクト自体に**型の情報も組み込まれている**"ため。

例えば、`a = 10`という単純な代入であっても、"値が`10`の整数型オブジェクト"を作成し、"変数`a`はその整数型オブジェクトの場所を表す"というように解釈する。
そのため、`a = 10`とした後に`a = "abc"`というように、同じ変数に対して違う型のオブジェクトを再代入しても、変数`a`のアクセスする先が変わるだけなので問題なく動作する。

なので、Pythonにおいては"文字列と整数で足し算はできない"など、演算上で型を意識することはあっても、変数を用意する時点で"どういう型を用意するか？"を意識することはない。

ちなみに、廉価の小規模マイコンなんかで、**メモリを節約しながらプログラムを作らないといけない**ような時(今どきほとんどないかもですが…)は、同じデータ種を扱う型でも実際にプログラム中で扱う数値の変動幅を求めて、最低限必要な値が収まる型を選ぶなどの設計をすることもある。

多分、このあたりの型の仕組みも、"プロトタイピング"や"データ分析"などの、比較的流動的に仕様や処理を変える用途でPythonが人気の理由かもしれない。

[^1]: [オブジェクト指向について説明してみる](https://qiita.com/kira4845/items/63d690ff5aeba838b363#%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%81%A8%E3%81%AF)
</div></details>

# ターミナルの入力を受け取ってみる

ここまで学習できると、`変数`を使えるようになっているはず。
[算術演算をやってみる](#算術演算をやってみる)の[例題](#例題-1)では、変数の値をソースコード中で決めている。
一応、変数の値表示と計算の2ヶ所で使ってはいるが、この程度だとせっかく変数を使っている意味がほとんどない。

一方で、[算術演算をやってみる](#算術演算をやってみる)の[例題](#例題-1)の機能に着目すると、**変数の値をソースコードの外から決められたら**、変数を使っている価値がグッと上がる気がする。

このような時に、ターミナルにユーザ入力を促して、入力値を受け取ることができる。

```python:input.py
print(input("xの値は?"))
```
![input.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291298/9ef592a9-522e-58e5-fe7b-812ff72702be.gif)
アニメーションを見ての通り、入力した文字は表示されるので、実際に使うときは`print`に直接渡すようなことは普通しないで、変数に格納する場合がほとんど。

```python:input_valiable.py
x = input("xの値は?")
print(x)
```

注意しないといけないのは、`input`の入力はすべて[文字列][str]だということ。
以下の例は、$x + 10$の計算結果を表示するもので、変数`x`を`input`で受けている。

```python:input_type_fail.py
x = input("x = ")
print(x + 10)
```

これを実行して、試しに3を入力してみると、"文字列と整数は計算できない"という旨のエラーが出る。

```text:実行結果
> .\input_type_fail.py
x = 3
Traceback (most recent call last):
  File "D:\04.pywork\python_tutorial\src\python_examples\section_2\stdin\input_type_fail.py", line 5, in <module>
    print(x + 10)
TypeError: can only concatenate str (not "int") to str
```

これを回避するには、変数`x`の型を受け取ってから変換する。

```python:input_type_success.py
x = input("x = ")
print(int(x) + 10)
```
```text:実行結果
> python .\input_type_success.py
x = 3
13
```

上の例は[整数(int)][int]に変換したが、実際は扱いたい型に合わせて変換する。
もちろん、用途が文字列のままなら変換は不要。

なお、`input()`の`()`内文字列は必ずしも必要ではない。
ただ、`()`内を省略すると入力待ちなのかパッと見判断できないので、対話モードのように`>>>`を表示するなどしておくと、見た目にわかりやすい。

### 例題

[算術演算をやってみる](#算術演算をやってみる)の[例題](#例題-1)の入力をターミナルから受けられるように改造してみよう。
また、元の例題で`x = `と表示していた部分をターミナルの入力待ちにしてみよう。

```text:画面出力
> python .\operator_example_input.py
x = 2
y = 3
7.0
```

<details><summary><b>回答例</b></summary><div>

```python:operator_example_input.py
x = float(input("x = "))
y = float(input("y = "))

print((2 * (x ** 2)) + (3 * y) - 10)
```
</div></details>

# 次回

[動かしながら学ぶPython入門~その３：条件演算と条件分岐~](https://qiita.com/kira4845/items/bfad2b52cd6036654751)

# 参考

[切り上げ切り捨て]:https://python.ms/sub/misc/division/#python-%E3%81%A7%E5%89%B2%E3%82%8A%E7%AE%97%E3%82%92%E3%81%99%E3%82%8B%E3%81%A8%E3%81%8D%E3%81%AE%E5%88%87%E3%82%8A%E4%B8%8A%E3%81%92%E3%81%A8%E5%88%87%E3%82%8A%E6%8D%A8%E3%81%A6
[const自作]:https://qiita.com/simonritchie/items/dd660888fbbb077dfeec

- [Python で割り算をするときの切り上げと切り捨て][切り上げ切り捨て]
- [Pythonでconst的なことができるライブラリを作ってみました。][const自作]