1Pythonの基礎

Pythonというプログラミング言語には、多種多様な構文、標準ライブラリ、関数、対話的な開発環境の機能がありますが、その大半を使わずにちょっとしたプログラムを書くことができますから、必要なことだけを学びましょう。

とはいえ、ちょっとしたプログラムを書くためにも、プログラミングの基本概念を知っておかなければなりません。小説や映画の主人公が魔法使いになるための訓練で感じるように、基本概念の訓練は退屈だと感じるかもしれません。ですが、少し勉強して練習すれば、魔法のようにコンピュータを動かせるようになります。

この章では、REPL (Read-Evaluate-Print Loop)とも呼ばれる対話型シェルで例を示します。対話型シェルでPythonを実行すると、すぐに結果が表示されます。対話型シェルは基本的なPythonの実行を学習するのに最適ですから、ぜひご自分でも試してみてください。読み流すのではなく実際に実行すると、格段に記憶の定着がよくなります。

対話型シェルに式を入力する

Muエディタを起動すると、対話型シェルを実行できます。本書のはじめにでMuエディタをダウンロードしてインストールする手順を示しました。Windowsをお使いでしたら、スタートメニューからMuと打ち込んで起動してくださいMacをお使いでしたら、Applicationsフォルダを開いてMuをダブルクリックしてください。新規ボタンを押し、空のファイルをblank.pyという名前で保存してください。実行ボタンを押すかF5キーを押すと、Muエディタのウィンドウの下半分の枠に対話型シェルが表示されます。>>>というプロンプトが表示されているはずです。

macOSとLinuxのターミナル、あるいはWindowsのコマンドプロンプトから対話型シェルを実行することもできます。macOSまたはLinuxならターミナルを開いてpython3と入力して実行します。Windowsならコマンドプロンプトを開いてpython と入力して実行します。>>>というプロンプトが表示されます。ファイルに書いたプログラムを実行したい場合は、python blank.pyのように、pythonまたはpython3に続けて.pyファイルのファイル名を指定します。macOSでpythonとしないように気をつけてください。pythonとすると、古くて互換性のないPython 2.7が起動してしまう可能性があります。WARNING: Python 2.7 is not recommendedという警告メッセージが表示されたら、python2.7の対話型シェルを終了し、python3を実行します。

プロンプトに2 + 2 と入力してPythonに計算させてみましょう。Muのウィンドウがこのようになるはずです。

>>> 2 + 2
4
>>>

Pythonで2 + 2は式です。式はプログラミングの最も基本的な要素です。式は2のような値と、+のような演算子から構成されます。式は評価されて一つの値になります。つまり、値を書くべき箇所に式を書くことができます。

先ほどの例では、2 + 2 が評価されて4という一つの値になりました。演算子のない値も式であると考えることができます。評価されても同じ値です。

>>> 2
2

MuエディタでREPLボタンを押すと、In [1]:のようなプロンプトの対話型シェルが表示されます。Jupyter Notebookエディタがこの種の対話型シェルを使っています。>>>プロンプトの通常のPythonの対話型シェルと同じように使えます。REPLはPythonに固有なのではなく、多くのプログラミング言語で採用されており、コードを実験してみることができます。

エラーは友達

コンピュータの長所は、指示を正確に実行することです。これは同時にコンピュータの短所でもあります。コンピュータが常識を働かせて意図を汲み取ってくれることはありません。コンピュータに理解できないコードがあると、プログラムがクラッシュして、エラーメッセージが表示されます。エラーメッセージがコンピュータを壊すことはありませんから、怖がらないでください。クラッシュは、プログラムの実行が予期せず停止したというだけのことです。

エラーメッセージに慣れてください。しょっちゅうエラーメッセージを目にすることになります(何十年のプログラミング経験があったとしても)。エラーメッセージは曖昧で初心者にはすぐに理解できないかもしれません。エラーについてもっと詳しく知りたければ、エラーメッセージで検索すれば情報を得られます。Muエディタを使っているなら、CTRL-SHIFT-Cで対話型シェル枠内の強調表示されているテキストをコピーできます。CTRL-Cでファイルエディタ枠内のテキストをコピーできます。よく見るPythonのエラーメッセージとその意味は、 https://nostarch.com/automate-boring-stuff-python-3rd-edition でまとめてありますので、そちらもご参照ください(英語)。

プログラミングには見慣れない数学演算子がいくつかあります。

  • 累乗はある数を何度もかけ算するという意味です。かけ算がある数を何度も足し算するという意味なのと同じです。例えば、2の4乗は、24 または 2 ** 4と表記され、24 = 2 × 2 × 2 × 2 = 16です。
  • 剰余演算とは、割り算の余りのことです。例えば、14 % 4は2と評価されます。14割る4は3余り2だからです。Pythonの剰余演算子は%ですが、剰余演算とパーセントは何の関係もありません。
  • 整数除算は割り算をして商の小数点以下を切り捨てます。例えば、25 / 8は3.125ですが、25 // 8は3です。29 / 10 は2.9ですが、29 // 10は2です。

Pythonの式ではほかにもいろいろな演算子を使えます。表1-1にPythonの数学演算子を全部まとめました。

表 1-1:数学演算子

演算子

演算

例

値(計算結果)

**

累乗

2 ** 3

8

%

(割り算をしたときの)余り

22 % 8

6

//

整数の割り算(商の整数部分)

22 // 8

2

/

割り算

22 / 8

2.75

*

かけ算

3 * 5

15

-

引き算

5 - 2

3

+

足し算

2 + 2

4

演算の順序(優先順位)は、数学と似ています。**が最初で、*と/と//と%が二番目で、+と-が最後です。優先順位が同じなら左から右という順序です。丸かっこを使うと優先順位を変えられます。行頭のインデントを除き、演算子と値の間のスペースをPythonは無視しますが、スペースを1つ分入れるのが慣例です。対話型シェルに以下の式を入力してみてください。

>>> 2 + 3 * 6
20
>>> (2 + 3) * 6
30
>>> 48565878 * 578453
28093077826734
>>> 2 ** 8
256
>>> 23 / 7
3.2857142857142856
>>> 23 // 7
3
>>> 23 % 7
2
>>> 2    +          2
4
>>> (5 - 1) * ((7 + 1) / (3 - 1))
16.0

プログラマが式を入力すると、Pythonが計算をして値を出してくれます。下図で示されるように、一つの値になるまでPythonが式の評価を行います。

式を形成するこうしたルールが、プログラミング言語Pythonの基礎的な部分です。自然言語の文法のようなものです。次に例を示します。

これは文法的に正しい英語の文です。

これ文法的に文ではない英語正しいは。

2行目の文は文法に則していないので解釈しづらいです。同様に、ルールに則さない命令を入力すると、Pythonは解釈できずにSyntaxErrorというエラーメッセージを表示します。

>>> 5 +
  File "<python-input-0>", line 1
    5 +
      ^
SyntaxError: invalid syntax
>>> 42 + 5 + * 2
  File "<python-input-0>", line 1
    42 + 5 + * 2
            ^
SyntaxError: invalid syntax

対話型シェルで実行してみると動作するかどうかがわかります。コンピュータを壊してしまうのではないかという心配はご無用です。最悪でもPythonがエラーメッセージを表示するだけです。プロのソフトウェア開発者もコードを書いている間にしょっちゅうエラーメッセージに遭遇します。

整数、浮動小数点数、文字列のデータ型

おさらいをすると、式は演算子と値から構成され、評価されて一つの値になります。すべての値は一つのデータ型に属します。Pythonの一般的なデータ型を表1-2にまとめました。-2や30は、整数値です。整数を表すデータ型です。intと表現されることがあります。3.14などは浮動小数点数です。floatと表現されることがあります。42は整数ですが、42.0は浮動小数点数です。プログラマは整数と浮動小数点数をまとめて数値と呼びますが、数値型というPythonのデータ型はありません。

少し細かいことですが、Pythonで整数と浮動小数点数の計算を行うと、その結果は整数ではなく浮動小数点数になります。3 + 4は整数の7と評価されますが、3 + 4.0は浮動小数点数の7.0と評価されます。/で2つの整数の割り算をすると、結果は浮動小数点数になります。例えば、16 / 4は4.0と評価されるのであって、4と評価されるのではありません。ほとんどの場合、これは大した問題ではありませんが、突然小数点が表示される理由はこれです。

表 1-2: 一般的なデータ型

データ型

例

整数(int)

-2, -1, 0, 1, 2, 3, 4, 5

浮動小数点数(float)

-1.25, -1.0, -0.5, 0.0, 0.5, 1.0, 1.25

文字列(str)

'a', 'aa', 'aaa', 'Hello!', '11 cats', '5'

文字列(str)と呼ばれる値もあります。文字列はシングルクォート(')で囲んでください。'Hello'や'Goodbye cruel world!'といった具合にです。そうすると、どこまでが文字列かがわかります。''のように文字を含まない文字列も定義できます。これは空白文字列や空文字列と呼ばれます。文字列については第4章で詳しく説明します。

以下の例のように、SyntaxError: unterminated string literalというエラーメッセージを目にすることがあるかもしれません。

>>> 'Hello, world!
SyntaxError: unterminated string literal (detected at line 1)

このエラーの原因は、シングルクォートの閉じ忘れである可能性が高いです。

文字列の結合と繰り返し

演算子の意味はその隣の値のデータ型に応じて変わることがあります。例えば、+は、整数や浮動小数点数に対しては加算を意味します。他方で、+が文字列に対して用いられると、文字列結合演算子になります。以下の式を対話型シェルに入力してみてください。

>>> 'Alice' + 'Bob'
'AliceBob'

この式は一つの新しい値に評価されました。2つの文字列を結合した文字列です。文字列と整数に対して+演算子を使おうとしたら、エラーになります。

>>> 'Alice' + 42
Traceback (most recent call last):
  File "<python-input-0>", line 1, in <module>
    'Alice' + 42
TypeError: can only concatenate str (not "int") to str

can only concatenate str (not "int") to strというエラーメッセージは、文字列'Alice'に整数を結合しようとしたために表示されました。'Alice42'という文字列を得たければ、整数を文字列に変換してから結合します。Pythonではこうした変換が自動的には行われません。(データ型の変換については、 「最初のプログラムの解説」で説明します。str()、int()、float()関数を使います。)

*演算子は整数または浮動小数点数に対してはかけ算を意味します。しかし、*演算子を文字列と整数の間で使うと、 文字列繰り返し演算子になります。対話型シェルで試してみましょう。

>>> 'Alice' * 5
'AliceAliceAliceAliceAlice'

この式は、元の文字列を5回繰り返した一つの文字列の値に評価されます。文字列の繰り返しが役に立つことがありますが、文字列の結合ほど頻繁には使われません。

*演算子は2つの数値の間(かけ算)か、文字列と整数値の間(文字列の繰り返し)でしか使えません。それ以外の使い方をすると、以下のようなエラーメッセージが表示されます。

>>> 'Alice' * 'Bob'
Traceback (most recent call last):
  File "<python-input-0>", line 1, in <module>
    'Alice' * 'Bob'
TypeError: can't multiply sequence by non-int of type 'str'
>>> 'Alice' * 5.0
Traceback (most recent call last):
  File "<python-input-0>", line 1, in <module>
    'Alice' * 5.0
TypeError: can't multiply sequence by non-int of type 'float'

このような式をPythonは理解できません。2つの単語のかけ算は意味不明ですし、文字列を小数回繰り返すことには無理があります。

式、データ型、演算子は抽象的に感じられるかもしれませんが、これらの概念について詳しくなると、スプレッドシートやウェブサイトや別のプログラムの出力などから得たデータを計算する、洗練されたプログラムを書けるようになります。

変数に値を格納する

変数は、一つの値を格納できる、コンピュータのメモリ内の箱のようなものです。式を評価した結果を変数に格納すると、あとで使えます。

代入文

代入文で値を変数に格納できます。代入文は、変数名と格納する値をイコール記号(代入演算子)で結びます。spam = 42という代入文を入力すると、spamという名前の変数が42という値を持つようになります。

変数はその中に値を入れられるラベル付きの箱だと考えることができますが、値に取り付けられたネームタグのほうがより適切な比喩であることを第6章で説明します。図1-1で両方の比喩を示します。

図 1-1: spam = 42 は、「変数spamは整数値42を持つ」と読みます

対話型シェルで次のように入力してみてください。

❶ >>> spam = 40
>>> spam
40
>>> eggs = 2
❷ >>> spam + eggs
42
>>> spam + eggs + spam
82
❸ >>> spam = spam + 2
>>> spam
42

初めて値が格納されたときに変数が初期化(作成)されます(➊)。ほかの変数や値とともに、式中で変数を使えます(➋)。変数に新しい値が代入されると(➌)、古い値は消えてしまいます。よって、この例の最後では、spamが40ではなく42になります。これを変数の上書きと言います。文字列を上書きする、次の例を対話型シェルで試してみてください。

>>> spam = 'Hello'
>>> spam
'Hello'
>>> spam = 'Goodbye'
>>> spam
'Goodbye'

図 1-2に示すように、変数spamは'Hello'という文字列を格納してから、'Goodbye'を格納するように入れ替えられました。

図 1-2:変数に新しい値が代入されると古い値は消えてしまいます

変数の代入は、ネームタグを新しい値に付け替えるのだと考えられます。

変数名

中に入っているデータがどのようなものであるかがわかるような変数名をつけるようにしてください。引っ越しをして全部のダンボール箱に 「もの」 と書かれていたら困りますよね。これでは何も見つけられません。この本やPythonの公式ドキュメントの例では spam、eggs、baconといった変数名がよく使われます。これはMonty Pythonの“Spam”というスケッチ・コメディーに由来しています。自分が書くプログラムでは、そのような変数名を使わず、わかりやすい変数名にしてください。

変数にはほとんどどのような名前でもつけられますが、Pythonには変数名の制約がいくらかあります。Pythonの変数名の制約は以下の4つです。

  • スペースは入れられません。
  • 文字と数字とアンダースコア (_)しか使えません。
  • 数字で始めることはできません。
  • if、for、returnなど、本書で学習するPythonのキーワードは使えません。

表1-3に有効な変数名の例を示します。

表 1-3: 有効な変数名と無効な変数名

有効な変数名

無効な変数名

current_balance

current-balance(ハイフンは使用不可)

currentBalance

current balance(スペースは使用不可)

account4

4account(数字で始まってはいけない)

_42

42(数字で始まってはいけない)

TOTAL_SUM

TOTAL_$UM($のような特殊文字は使用不可)

hello

'hello'('のような特殊文字は使用不可)

変数名では大文字と小文字を区別します。spam、SPAM、Spam、sPaMは4つの別々の変数です。Spamではなくspamのように、.Pythonの慣習では変数名を小文字で始めます。

コーディング規約への意見とPEP8

本書の前の版では、変数名の単語をアンダースコアで区切るのではなく、キャメルケースで表していました。looking_like_thisではなくlookedLikeThisと表していたということです。変数名の単語をアンダースコアで区切る表記はスネークケースと呼ばれます。 単語と単語の間にアンダースコアがあるのが小さなヘビ(スネーク)のように見えるからです。(単語の境界を大文字にする表記がキャメルケースと呼ばれるのはラクダ(キャメル)のこぶのように見えるからです。)Pythonのコーディング規約であるPEP8ではアンダースコアが推奨されていると指摘する人がいるかもしれません。その指摘に対しては、PEP8に「一貫性にこだわりすぎるのは、狭い心の現れである」とあり、私はキャメルケースを好むと言わせていただきます。

コーディング規約との一貫性は重要です。しかしもっと重要なのは、一貫性を崩すべきときを弁えることです。コーディング規約が当てはまらない場合があります。迷ったらご自身の良識に従ってください。

コンピュータはスネークケースでもキャメルケースでも気にしません。PEP8は絶対遵守の戒律を記した石版ではありません。同じ書き方で統一しさえすれば、どちらを採用しても構いません。そのことを証明するために、私は本書のこの版でコードをスネークケースに書き換えました。本当にどちらの書き方でもいいのです。

最初のプログラム

対話型シェルはPythonの命令を一つずつ実行するのに便利ですが、まとまりのあるPythonのプログラムを書こうとするなら、命令をファイルエディタに書きます。ファイルエディタはメモ帳やTextMateなどのテキストエディタと似ていますが、ソースコードを書くための特別な機能が備わっています。Muで新しいファイルを開くには、画面上部の新規ボタンを押します。

新しく開いたタブにプログラムを書いていきます。 エンターキーを押すと即座に実行される対話型シェルとは異なり、プログラムを続けて入力します。ファイルエディタでは、好きなだけ命令を書き、ファイルを保存して、プログラムを実行できます。対話型シェルとファイルエディタの違いは次のとおりです。

  • 対話型シェルでは常に>>>またはIn [1]: のプロンプトが表示されています。
  • ファイルエディタでは>>>またはIn [1]:のプロンプトがありません。

最初のプログラムを書いてみましょう。ファイルエディタのウィンドウが開いたら、以下の内容を入力してください。

# このプログラムはあいさつをして名前を聞きます

print('Hello, world!')
print('What is your name?')  # 名前を聞く
my_name = input('>')
print('It is good to meet you, ' + my_name)
print('The length of your name is:')
print(len(my_name))
print('What is your age?')  # 年齢を聞く
my_age = input('>')
print('You will be ' + str(int(my_age) + 1) + ' in a year.')

このソースコードを入力したら、再利用できるように保存してください。保存ボタンを押し、ファイル名欄にhello.pyと入力して、保存をクリックします。

プログラムを書く際には適宜保存してください。保存すると、コンピュータがクラッシュしたりMuを終了したりしても、コードが失われることはありません。WindowsとLinuxではCTRL-S、macOSでは-Sのショートカットキーでも保存できます。

プログラムを保存したら実行してみましょう。F5キーを押すか、実行ボタンを押してください。プログラムに入力を求められたら名前と年齢を入力してください。対話型シェルに例えば次のように出力されます。

Hello, world!
What is your name?
>Al
It is good to meet you, Al
The length of your name is:
2
What is your age?
>4
You will be 5 in a year.
>>>

実行するコードの行がなくなるとPythonのプログラムは終了します。Muエディタはプログラムの終了後に>>>の対話型シェルを表示します。Pythonのコードを続けて入力できます。

ウィンドウ上部のX 印をクリックするとファイルエディタを閉じることができます。保存したプログラムをもう一度読み込みたければ、メニューの開くボタンを押します。表示されるウィンドウで hello.pyを選んで開くボタンを押します。以前に保存したhello.pyプログラムがファイルエディタウィンドウで開きます。

http://pythontutor.com で提供されているPython Tutor視覚化ツールを利用すると、プログラムの実行状況を見られます。プログラムの各実行段階を行ったり来たりできます。変数に格納されている値と出力がどのように変化するかを確かめられます。

最初のプログラムの解説

ファイルエディタで作成した最初のプログラムについて、コードを一行ずつ解説します。

コメント

次の行はコメントです。

# このプログラムはあいさつをして名前を聞きます

Pythonはコメントを無視しますから、コードの意図などをメモするのに使えます。各行で#よりあとの部分はコメントになります。

プログラムの動作をテストするときに、特定の行を実行されないようにするために#を行頭につけることがあります。これはコメントアウトと呼ばれます。プログラムがうまく動かない原因を突き止めるときに使えるテクニックです。#を取り除けば、その行が実行されるようになります。

Pythonは空白行も無視します。好きなだけ空白行を入れられます。空白行を適当な箇所に入れて、段落分けをするとコードが読みやすくなります。

print()関数

print()関数はかっこ内の文字列値を画面に表示します。

print('Hello, world!')
print('What is your name?')  # 名前を聞く

print('Hello, world!')行は、文字列'Hello, world!'のテキストを表示するという意味です。この行を実行するときに、Pythonがprint()関数を呼び出し、文字列値がその関数に渡されます。関数に渡される値のことを引数と呼びます。引用符(クォート)は画面に表示されないことに注意してください。クォートは文字列の始まりと終わりを示す記号であり、文字列値には含まれません。

注記

print()とかっこ内に何も入れずに呼び出すと空白行を画面に表示できます。

関数の名前を書くときには、開きかっこと閉じかっこをつけて関数名であることをはっきりさせます。本書でprintではなくprint()と書いているのはそのためです。関数名と開きかっこの間に空白を入れないのが標準的な慣習です。空白を入れても実行はできます。第3章で関数について詳しく説明します。

input()関数

input()関数は、ユーザーがテキストを入力してエンターキーを押すのを待ちます。

my_name = input('>')

この関数を呼び出した結果は、ユーザーが入力したテキストの文字列になります。この行は、変数my_nameにその値を代入しています。'>'という文字列をこの関数に渡しているので、>プロンプトが表示されます。ユーザーに対して何らかの入力を求める目印になります。input()関数に文字列を渡さずに呼び出すこともできます。input()と引数なしで呼び出すと、プロンプトを何も表示せずにユーザーの入力を待ちます。

> と >>> のプロンプト

input()関数に渡した文字列がプログラムの実行時にプロンプトとして表示されます。input('>')を呼び出すと山かっこ >がプロンプトとして画面に表示されます。Pythonの対話型シェルで表示される >>>と区別できます。本書では>>>プロンプトはPython対話型シェルのプロンプトであることを示し、>プロンプトはプログラムの実行時にinput('>')を呼び出していることを示します。私が'>'を選んだことに深い理由はなく、好きなものをプロンプトとして使えますし、プロンプトを表示しなくても構いません。

input()関数は、ユーザーが入力した文字列値に評価される式であると考えることができます。ユーザーが'Al'と入力したとしたら、my_name = 'Al'と評価されます。

input()を呼び出してNameError: name 'Al' is not definedのようなエラーが発生した場合は、Python3ではなくPython2で実行していることがエラーの原因です。

あいさつメッセージ

print()を呼び出している次のコードは、'It is good to meet you, ' + my_name という式がかっこ内にあります。

print('It is good to meet you, ' + my_name)

式は一つの値に評価されることを思い出してください。my_nameに'Al'という値が格納されているとすると、この式は'It is good to meet you, Al'に評価されます。この一つの値がprint()に渡され、画面に表示されます。

len()関数

len()関数に文字列値(または文字列を含む変数)を渡すと、文字数の整数値に評価されます。

print('The length of your name is:')
print(len(my_name))

対話型シェルで試してみましょう。

>>> len('hello')
5
>>> len('My very energetic monster just scarfed nachos.')
46
>>> len('')
0

len(my_name)は整数値に評価されます。len()関数の呼び出しは、その整数値を返し、出力します。この整数値は関数呼び出しの 返り値です。そしてprint()関数に渡されて画面に表示されます。print()関数の引数は整数値でも文字列値でも構いません。ただし、以下のコードはエラーになります。

 >>> print('I am ' + 29 + ' years old.')
Traceback (most recent call last):
  File "<python-input-0>", line 1, in <module>
    print('I am ' + 29 + ' years old.')
TypeError: can only concatenate str (not "int") to str

print()関数がエラーを発生させるのではなく、print()に渡した式がエラーを発生させるのです。この式だけでも同じエラーになります。

>>> 'I am ' + 29 + ' years old.'
Traceback (most recent call last):
  File "<python-input-0>", line 1, in <module>
    'I am ' + 29 + ' years old.'
TypeError: can only concatenate str (not "int") to str

+演算子は、2つの数値を加算するか、または2つの文字列を結合するかです。数値と文字列を足すことはできません。Pythonの文法に反します。数値の代わりに文字列を使うことでこのエラーを回避できます。次の節で説明します。

str()関数、int()関数、float()関数

29のような整数と文字列とを結合してprint()関数に渡したければ、整数29の文字列型である'29'を使う必要があります。次に示すように、str()関数に整数値を渡すと文字列型になります。

>>> str(29)
'29'
>>> print('I am ' + str(29) + ' years old.')
I am 29 years old.

str(29)は'29'に評価されますから、式'I am ' + str(29) + ' years old.'は'I am ' + '29' + ' years old.',に評価され、最終的には'I am 29 years old.'に評価されます。その値がprint()関数に渡されます。

str()関数、int()関数、float()関数は、それぞれ、引数を文字列型、整数型、浮動小数点数型に評価します。対話型シェルでこれらの関数を使って値を変換してどうなるか見てみましょう。

>>> str(0)
'0'
>>> str(-3.14)
'-3.14'
>>> int('42')
42
>>> int('-99')
-99
>>> int(1.25)
1
>>> int(1.99)
1
>>> float('3.14')
3.14
>>> float(10)
10.0

この例では、str()関数、int()関数、float()関数に、異なるデータ型の値を渡して文字列型、整数型、浮動小数点数型に変換しています。

str()関数は整数型あるいは浮動小数点数型の値を文字列と結合したいときに便利です。int()関数は文字列型の数字を使って計算したいときに便利です。例えば、input()関数はユーザーが数字を入力したとしても文字列を返します。対話型シェルに spam = input()と入力して、101と打ち込んでエンターキーを押します。

>>> spam = input()
101
>>> spam
'101'

spamに格納される値は、整数値の101ではなく、文字列値の'101'です。spamの値を使って計算をしたい場合は、int()関数を使って整数に変換し、その値を格納します。spamの値が文字列の'101'だとしたら、int(spam)は整数値の101に評価されます。よって、spam = int(spam)という式は、spam = 101と等しいです。

>>> spam = int(spam)
>>> spam
101

これで変数spamを文字列ではなく整数として扱えます。

>>> spam * 10 / 5
202.0

int()に整数として評価できない値を渡すとエラーが発生します。

>>> int('99.99')
Traceback (most recent call last):
  File "<python-input-0>", line 1, in <module>
    int('99.99')
ValueError: invalid literal for int() with base 10: '99.99'
>>> int('twelve')
Traceback (most recent call last):
  File "<python-input-0>", line 1, in <module>
    int('twelve')
ValueError: invalid literal for int() with base 10: 'twelve'

int()関数は、浮動小数点数値の切り捨てにも使えます。

>>> int(7.7)
7
>>> int(7.7) + 1
8

最初のプログラムの最後の3行でデータ型を適切に変換するために、int()関数とstr()関数を使いました。

print('What is your age?')  # 年齢を聞く
my_age = input('>')
print('You will be ' + str(int(my_age) + 1) + ' in a year.')

変数my_ageにはinput()関数から取得した値が格納されます。input()関数は(ユーザーが数字を入力したとしても)必ず文字列を返すので、int(my_age)でmy_ageの文字列値を整数値に変換します。この整数値にint(my_age) + 1という式で1を足します。

文字列と数値の異同

文字列値と整数値ないし浮動小数点数値は異なるものだとみなされますが、整数値と浮動小数点数値は同じものだとみなされます。

>>> 42 == '42'
False
>>> 42 == 42.0
True
>>> 42.0 == 0042.000
True

文字列はテキストであり、整数と小数は数値なので、このような結果になります。

この足し算をした結果をstr()関数に渡します。str(int(my _age) + 1)です。返される文字列を、'You will be 'と' in a year.'の間に入れて結合し、一つの長い文字列を作ります。この長い文字列をprint()に渡し、画面に表示します。

ユーザーがmy_ageに'4'と入力したとしましょう。この一連の評価を以下に図示しました。

文字列の'4'が整数に変換されるので、1を足せます。その結果は5です。str()関数で計算結果を文字列に戻し、'in a year.'と結合して、メッセージを完成させます。

type()関数

Pythonには、整数、浮動小数点数、文字列以外のデータ型があります。プログラミングの学習を続けると、他のデータ型に出くわすかもしれません。type()関数に渡せばデータ型を判別できます。対話型シェルで次のように入力してみてください。

>>> type(42)
<class 'int'>
>>> type(42.0)
<class 'float'>
>>> type('forty two')
<class 'str'>
>>> name = 'Zophie'
>>> type(name)  # 変数nameの値は文字列型です
<class 'str'>
>>> type(len(name))  # len()関数は整数値を返します
<class 'int'>

type()関数には、値だけでなく、値に評価される変数や式を渡すこともできます(上記の例を参照)。type()関数自体も値を返しますが、山かっこがついていることからわかるように、その値をspam = <class 'str'>のように代入することはできません。

round()関数とabs()関数

len()関数と同様に引数を取って値を返す関数をさらに2つ見てみましょう。round()関数は浮動小数点数を引数に取ってその数に最も近い整数を返します。以下の式を対話型シェルに入力してみてください。

>>> round(3.14)
3
>>> round(7.7)
8
>>> round(-2.2)
-2

round()関数は、小数点以下の桁数を指定する第二引数を取ることができます。以下の式を対話型シェルに入力してみてください。

>>> round(3.14, 1)
3.1
>>> round(7.7777, 3)
7.778

中間の値を渡したときの挙動は少し奇妙です。round(3.5)を呼び出すと4になりますが、round(2.5)は2になります。.5という中間の値は、最も近い偶数に丸められます。これは銀行丸めと呼ばれます。

abs()関数は引数の絶対値を返します。数学的には0からの距離と定義されますが、個人的にはその数の正の数だと簡便に考えています。以下の式を対話型シェルに入力してみてください。

>>> abs(25)
25
>>> abs(-25)
25
>>> abs(-3.14)
3.14
>>> abs(0)
0

Pythonにはまだほかにも関数があり、本書でも登場します。この節では、入力を変えながら関数を対話型シェルで実験してその振る舞いを観察する方法を示しました。新しいコードを学んで練習する際に使えるテクニックです。

コンピュータがどのようにしてデータを2進数で保存しているか

ここまでPythonのコードをたくさん見てきました。プログラミングを魔法のように感じたかもしれません。コンピュータはどのようにして2 + 2を4に変形しているのでしょうか。その答えは本書で扱うにはあまりにも込み入っていますが、答えの一部を説明することはできます。2進数(1と0の数字しかない数値)がコンピュータと大いに関係しています。

映画ではハッカーが画面に1と0の羅列を表示させることがよくあります。その場面は神秘的で印象的ですが、この1と0は何を意味しているのでしょうか。2進法が最も単純な記数法で、コンピュータハードウェアの安価な部品でも実装できるというのがその答えです。2進法(2を基数とする記数法)は、私たちがなじんでいる10を基数とする記数法と同じ数値をすべて表現できます。10進法では0から9の10の数字があります。表1-4は10進数の0から26までの数値を2進数で示しています。

表 1-4: 10進数と2進数の対応表

10進数

2進数

10進数

2進数

10進数

2進数

0

0

9

1001

18

10010

1

1

10

1010

19

10011

2

10

11

1011

20

10100

3

11

12

1100

21

10101

4

100

13

1101

22

10110

5

101

14

1110

23

10111

6

110

15

1111

24

11000

7

111

16

10000

25

11001

8

1000

17

10001

26

11010

記数法は図1-3のような走行距離計を思い浮かべると理解しやすいです。最後の数字に到達したら次の桁に進んでこれまでの桁は0にリセットします。10進法では最後の数字が9で、2進法では最後の数字が1です。10進法では、9の次は10で、999の次は1000です。同様に、2進法では、1の次は10で、111の次は1000です。2進数の10は10進数の十と同じ量ではなく、二と同じ量を示します。2進数の1000は10進数の千と同じ量ではなく、八と同じ量を示します。https://inventwithpython.com/odometer で2進数と10進数の走行距離計の動きを見られます。

図 1-3:10進法(左側)と2進法(右側)の走行距離計

コンピュータのハードウェアで2進数を表現するのは、10進数を表現するよりも単純です。2つの状態を表現できれば事足りるからです。例えば、ブルーレイディスクとDVDは、なめらかなランドと出っ張った ピットが表面にあり、ディスクプレイヤーのレーザーを反射するか反射しないかのどちらかになります。回路では電流が流れているか流れていないかのどちらかです。こうしたさまざまなハードウェア標準は、すべて2つの状態を表現する方法です。他方で、10種類の電圧を信頼できる精度で検出できる高品質の電子部品を作ると高価になってしまいます。単純な部品を使うほうが経済的で、2つの状態を表現するのは単純です。

2進数の数字(binary digits)は略してビット(bits)と呼ばれます。1ビットで2つの数値を表現でき、8ビット(1バイト)で28、つまり256の数値を表現できます。10進数では0から255まで、2進数では0から11111111までです。10進数の一つの数字が10の数値(0から9)を表現でき、8つの10進数で108、つまり100,000,000(0から99,999,999まで)の数値を表現できるのと同様です。コンピュータ上のファイルはバイトでサイズが測られます。

  • 1キロバイト(KB)は、210、つまり1,024バイトです。
  • 1メガバイト(MB)は、220、つまり1,048,576バイト(1,024KB)です。
  • 1ギガバイト(GB)は、230、つまり1,073,741,824 バイト(1,024MB)です。
  • 1テラバイト(TB)は、240、つまり1,099,511,627,776バイト(1,024GB)です。

シェイクスピアの『ロミオとジュリエット』のテキストは約135KBです。高解像度の写真は約2MBから5MBです。映画は画質と長さによりますが、1GBから50GBに収まります。ハードドライブとフラッシュメモリの製造元は、製品のサイズについてうそをついています。例えば、1TBを、1,099,511,627,776 バイトではなく1,000,000,000,000バイトで計算し、9.09TBのハードドライブを10TBと宣伝しています。

2進数の1と0は、整数だけでなく、どのようなデータでも表現できます。0から255までの整数の代わりに、2の補数を用いて–128から127までの数値を表すことができます。浮動小数点数はIEEE-754を用いて表現できます。

テキストもコンピュータでは2進数として保存されています。文字と句読点と記号に一意の数値を対応させます。数値でテキストを表現する体系をエンコーディングと呼びます。UTF-8が最も一般的なエンコーディングです。UTF-8では、大文字のAは10進数の65(8ビットの2進数では01000001)、?(クエスチョンマーク)は63、文字の7は55、文字列'Hello' は72、101、108、108、111で表現されます。コンピュータに保存された“Hello”は0100100001100101011011000110110001101111というビットの並びになっています。

ハッカーの映画と同じですね。

エンジニアは各形式のデータを数値にエンコードする方法を編み出す必要があります。写真や画像は、ピクセルと呼ばれる色の付いた正方形を並べた二次元の格子に分解できます。各ピクセルは、3バイトを使用して、赤、緑、青の度合いを表します。第21章で画像データをもっと詳しく説明しますが、ここで簡単な例を挙げましょう。255, 0, 255は赤と青が最大量で緑はゼロ、つまり紫のピクセルを表します。

音は圧縮された空気の波で構成されており、それが耳に届くと脳が聴覚として解釈します。音波の強度と周波数をグラフ化できます。このグラフの数値を2進数に変換してコンピュータに保存すると、スピーカーを操作して音を再現できます。単純化すると、コンピュータオーディオはこのように機能しています。例えばベートーヴェンの交響曲第5番を、このようにして数値で表現できます。

画像データと音声データを組み合わせると動画になります。どのような形式の情報であっても2進数にエンコードできます。ここではかなり簡略化してお伝えしましたが、1と0で情報時代におけるさまざまなデータを表現する方法をご理解いただけたことと存じます。

まとめ

計算機を使えば式を計算をできますし、ワープロを使えば文字列を結合できます。コピーアンドペーストで文字列を繰り返すのも簡単です。しかし、こうした操作の背後にある式とその構成要素(演算子、変数、関数)は、プログラムを構成する基本的な部品です。これらの構成要素の扱い方を知れば、Pythonで大規模なデータ処理もできるようになります。

本章では、さまざまな演算子(数学演算の+、-、*、/、//、%、**と、文字列操作の+、*)と3つのデータ型(整数型、浮動小数点数型)について説明しました。

関数もいくつか紹介しました。print()関数とinput()関数は、テキストの(画面への)出力と(キーボードからの)入力を処理します。len()関数は文字列を受け取り、その文字数を整数で返します。str()関数、int()関数、float()関数は、それぞれ、渡した値のデータ型を文字列型、整数型、浮動小数点数型に変換します。round()関数は丸めた整数を返し、abs()関数は引数の絶対値を返します。

次章では、どのコードを実行してどのコードを飛ばすか、どのコードを繰り返し実行するかなどを、Pythonに指示する方法を学びます。これはフロー制御と呼ばれ、プログラムに何らかの判断をさせます。

練習問題

  1. 以下のものを演算子と値とに分類してください。

*
'hello'
-88.8
-
/
+
5

  2. 以下のものを変数と文字列とに分類してください。

spam
'spam'

  3. データ型を3つ挙げてください。

  4. 式は何から構成されますか? 式は何を行いますか?

  5. 本章ではspam = 10のような代入文を紹介しました。式と文はどう違いますか?

  6. 以下のコードの実行後に、変数baconの値はどうなりますか?

bacon = 20
bacon + 1

  7. 以下の2つの式は評価されてどのような値になりますか?

'spam' + 'spamspam'
'spam' * 3

  8. eggsは有効な変数名で、100は無効な変数名なのはなぜですか?

  9. 整数型、浮動小数点数型、文字列型の値を取得するために使う3つの関数は何ですか?

10. この式がエラーになるのはなぜですか?また、どのように修正しますか?

'I eat ' + 99 + ' burritos.'

ボーナスポイント:Pythonの公式ドキュメントでlen()関数を調べてください。「組み込み関数」というタイトルのウェブページにあります。Pythonの関数一覧を見て、bin()関数とhex() 関数の機能を調べ、対話型シェルで実験してみてください。