Help us understand the problem. What is going on with this article?

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

はじめに

この記事は、連載です。
前回の動かしながら学ぶPython入門~その1:ソースファイル作成から画面に表示まで~
先に読んでからのほうが理解しやすいと思います。

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

対象

  • Pythonの初歩中の初歩を学習したい人

執筆時の環境

  • OS: Windows10
  • Python: 3.7.3
  • エディタ:VSCode

本文中の用語

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

変数を使ってみる

組み込み型と書式

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

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

名称 概略
int 整数
float 少数
str 文字列

もちろん他にも沢山あって、Pythonの組み込み型については、別でまとめた記事があるので、詳細はこちらの記事を参照してもらいたい。

変数を作る

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

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

と書くだけでいい。

変数を読む

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

書式
変数名

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

例題

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

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

回答例を見る
my_name_is.py
name = "TAKE"
print("どーも")
print(name)
print("です")

文字列に組み込んでみる

組み込み型と書式例題では、

どーも
TAKE
です

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

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

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

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

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

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

my_name_is_oneline_multi.py
name = "TAKE"
age = 17

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

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

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

my_name_is_oneline_other.py
name = "TAKE"
print("どーも" + name + "です")
実行結果
> .\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

まずは、四則演算を試してみよう。
対話モードで次のコマンドを実行してみよう。

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

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

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

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

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

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

少しわかりにくいが、符号を反転して切り捨て除算することで、切り捨てによる整数部の変化も逆転する。
切り上げ切り捨て.png
なので、符号反転した被除数を切り捨て除算してから再度符号反転することで、切り上げになっている。

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

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

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

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

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

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

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

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

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))
実行結果
> 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
今回紹介した演算子だと、** -> *,/,//,% -> +,-のような順序。
同じ優先順位の演算子が複数ある時は左に書いてある側から優先となる。
数学上の優先順位と合致しているので、わかりやすいと思う。

対話モードで実行
>>> 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$
対話モードで実行
>>> (1 + 2) * (3 * 4)
36

こうすればよい。

例題

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

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

回答例
operator_example.py
x = 2
y = 3

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

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

算術代入演算子の存在

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

演算子 計算 使用例 等価の式
+= 加算(足し算)と代入 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 += 1x -= 1と書く必要がある。

定数について

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

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

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

【コラム】型とPython

読む

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

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

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

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

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

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

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

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

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

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

input.py
print(input("xの値は?"))

input.gif
アニメーションを見ての通り、入力した文字は表示されるので、実際に使うときはprintに直接渡すようなことは普通しないで、変数に格納する場合がほとんど。

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

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

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

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

実行結果
> .\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の型を受け取ってから変換する。

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

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

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

例題

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

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

回答例
operator_example_input.py
x = float(input("x = "))
y = float(input("y = "))

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

次回

動かしながら学ぶPython入門~その3:条件演算と条件分岐~

参考

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away