0. はじめに

本テキストの目標として「ローカル環境でとりあえずPythonを動かせるようにする」を設定しておく。 ということで、とりあえずPythonについてwikipediaで調べると以下の文章が出てくるであろう。

Python(パイソン)はインタープリタ型高水準汎用プログラミング言語である。 グイド・ヴァン・ロッサムにより創り出され、 1991年に最初にリリースされたPythonの設計哲学は、 有意なホワイトスペース(オフサイドルール)の顕著な使用によってコードの可読性を重視している。 その言語構成とオブジェクト指向のアプローチは、 プログラマが小規模なプロジェクトから大規模なプロジェクトまで、 明確で論理的なコードを書くのを支援することを目的としている。

Pythonは動的に型付けされていて、ガベージコレクションされている。 構造化(特に手続き型)オブジェクト指向関数型プログラミング を含む複数のプログラミングパラダイムをサポートしている。 Pythonは、その包括的な標準ライブラリのため、 しばしば「バッテリーを含む」言語と表現される

この文章を呼んで「あぁなるほど」と思えればこのセクションは読み飛ばしても問題ない。

Pythonの学習において、下線を引いたキーワードの中で特に重要なのは「インタープリタ型」、 「ホワイトスペース(オフサイドルール)」、「動的に型付け」の3つである。 プログラミングについてさらに理解を深めたければ「オブジェクト指向」についても知っておいた方が良い。 「ホワイトスペース(オフサイドルール)」と「動的に型付け」 については後述する(3.2及び4.1節参照)機会があるのでここでは説明しないが、 「インタープリタ型」と「オブジェクト指向」については 説明するタイミングがおそらくここでしかないから、軽く説明を書いておく。 また、知らなくとも何の問題もないが「ガベージコレクション」についても触れておく。

また、私はPythonを真面目に勉強したわけではない。 Pythonの学習書などは一切読んだことはなく、ネットでサンプルコードをみて 動かせるようになっただけのため、用語などの使い方が正しくないかもしれない。 本テキスト作成にあたり、Pythonの公式ドキュメントは参考にしたが、 私が再構築するにあたって不正確な情報が含まれる ことも多々あると思うので本テキストは余り鵜呑みにはしないほうが良い。

本テキストでは、第3章からスクリプトファイルにコードを書いていくことになるが、 テキストで紹介するコードは基本的にすべて資料フォルダ内にいれてある。 そのファイルを実行すれば動くが、 プログラムを学習するのならコピペではなく一度は自身でコードを書いた方が覚えられるので 時間があるのなら、テキストを見ながらカタカタをコードを書くことをおすすめします。

ネット上にある学習に良さそうなサイトを掲示しておく。

PEP8とは、Python Enhancement Proposalsの略で、 それの8番目のバージョンとなるPythonの 標準コーディング規約のことである。 例えば、「コード一行の長さは79文字以下にすべき」や 「代入演算子や比較演算子の前後にはスペースを入れるべき」のような規約がある。 コーディングを行う上で可読性を挙げるために、統一性を出すべきだという理念であり、 統合開発環境でコーディングする際はこのPEP8に基づいて入力補完などが行われる。

本テキストでは時折、米印※で注釈を書いているが、 この注釈の内容は完全に入門の域ではないと思われる。 発展して学習を進める場合のキーワードぐらいの感覚でよいだろう。 (ほぼ私的なメモである。)

※本テキストではローカルなPython開発構築を整えることから説明するが、 ローカル環境にいらない場合は Google Colaboratoryを用いて学習した方がいろいろと楽である。 (学び手だけでなく、教え手からしても楽になる。) しかし、Google Colaboratoryは実用には耐えられないだろう。 サーバーに処理を送信してその結果を待つという時間が必要になるため処理が遅くなる。 また、Google Colaboratoryを使うとライブラリの導入が必要なくなる(多くのライブラリが事前に入っている)が、 逆を言えば導入方法を学ぶ機会がなくなることになる。 その為、本テキストではGoogle Colaboratoryは用いていない。 Jupyter Notebookをローカルに使うという手もあるのだが、 それはいろいろと手順を間違えている気がするので 本テキストでは使わない。急がば回れということで。
※本テキストはWindows OSを対象にして書いている。 本テキストではMac OS(iOS)はサポートしない(私が分からないため)。

0.1 インタープリタ型(interpreter)

「インタープリタ型」とはプログラムの実行方法を表す言葉である。 これの対義語として「コンパイル型」というのがある。

プログラミングは「コード」を書くことでコンピューターに特定の処理を与えるが、 そのコードの単語や文法は人間が扱いやすいように作られており、コンピューターが直接 コードを読み、いきなり処理を実行するというのは現状不可能である。 よって、人間が読む「コード」をコンピューターが読める「機械語」に変換する 「コンパイル(compile)」という作業が必要になる。

「コンパイル型」というのは、人がコードを書いた後、 手動でコンパイルと行う必要があるプログラミング言語のことを指す。 これに該当するのが「C言語(C/C++/C#)」、「Java」、「Fortran」、 「COBOL」、「LISP」などの言語である。 コンパイル型の言語はコンパイル処理が面倒ではあるが、 一度コンパイルしてしまえば実行時の処理が高速という利点がある。 これはコンパイル時に最適化が行われるためである。

一方の「インタープリタ型」というのは、人がコードを書いた後、 自動でコンパイルを行ってくれるプログラミング言語のことを指す。 これに該当するのが「Python」、「Perl」、「JavaScript」、「Ruby」、「R」などの言語である。 身近な例を挙げればJavaScriptになるであろう。 ウェブページを開いたのなら、そこではJavaScriptが動いていることがほとんどである。 インタープリタ型の言語はコンパイル処理を自動でやってくれるが、 コンパイル型と比較すると実行速度が遅いという欠点がある。

(a)コンパイル型。(b)インタープリンタ型。

※Pythonにおいて速度の遅さはライブラリを使用することで大幅に改善される。 あるいは、「CPython」を用いたり、「Numba」を使うと速くなるらしい。
※「Julia」というインタープリタ型かつ動的型付けでありながら処理が速い言語もある。

0.2 オブジェクト指向

この概念については触れなくてもPythonの中級程度までの学習には問題がない。 しかし、これに触れておかないとPythonのライブラリについての理解が難しくなる (特にmatplotlibでのグラフ作成)ので、説明しとくしかない。

「オブジェクト」というと非常に抽象的で理解に困るのだが、イメージとしては「箱」である。 そして、その箱の中にいろいろなものを入れて管理することを「オブジェクト指向」という。 Pythonでは箱の中には何でも入れることができる。 箱の中には単に何かの値を入れても良いし、箱の中に箱を入れることもできる。 また、箱はPythonが標準で(あらかじめ)作ってくれているものを利用してもよいし、 自作の箱を作ることもできる。 Pythonでは「変数」にこのオブジェクト(箱)を代入して利用できる。 ここでは、Pythonでは箱によって階層的にプログラムを扱えることさえ知っておけばほぼ問題はない。

「オブジェクト」の「箱」イメージ

パッケージ・モジュール等の階層

※オブジェクト指向には「インスタンス」、「コンストラクタ」、「継承」など 他にも重要なキーワードが存在するが、 入門の域ではないのでここでは触れない。

0.3 ガベージコレクション(garbage collection:GC)

FortranやC言語など古いプログラム言語ではメモリ管理が必須であった。 メモリ管理とは、例えば変数に値を代入するという処理はその値をメモリに記憶しておくことに等しいく、 プログラムの処理系がOSに対してそのメモリ領域を確保するような指示のことを言う。 このメモリ管理は古い言語では、手動で行う必要があり常にメモリを気にしながらプログラムミングを 行う必要があった(C言語ではポインタという概念を学ぶ必要がある)。

コンピュータが開発され始めた初期であれば、 扱えるメモリ容量が小さかった為、メモリ管理を丁寧にやる必要があっただろうが、 技術革新が進み、大量のメモリを容易に確保できる現代 においては、もはやメモリを気にする場面は少ない。 (iPhone13のRAMでも4GBありますし。) よって、メモリ領域を確保し、それが必要でなくなったなら解放する処理(ガベージコレクション)は 自動でやってくれた方がありがたい。 最近の言語はこのガベージコレクションを備えたものが多ぐ、JavaやPythonはこれに該当しメモリを 気にせずプログラムを行うことができる。

※大きなファイルを読み込むときなどはメモリを気にする必要がでてくるが、 メモリ制限無視して読み込むという処理を1行書けばだいたいは解決する。

コンピュータの構成要素。

メモリ領域の確保・呼び出し・解放。 使わないメモリ領域は解放しないとメモリを圧迫し、エラーの要因となる。