Pythonのモジュールを使おう

「数論とPython」シリーズ 2018/12/07

前回, Pythonの基礎的な使い方を学びました。 defを用いてオリジナルの関数を作る方法もみました。 自分が好きなように関数を作れる, それがプログラミンの面白いところです。 でも, すべてを自分ひとりで作るのはとても骨の折れる作業です。 前回扱った「数学の宿題」の例のように, もし誰かがすでに便利な関数を作っていたのであれば, それを使わせてもらえたら効率がいいですよね。 そこで登場するのがモジュールです。

モジュールってなに?

自分で書いた関数, 便利だから色々な人に使ってほしいな, と世界のみんなにシェアするPythonファイルをモジュールといいます。 逆に, 他人が公開しているモジュールを自分のPythonに取り込んで使うこともできます。

Python公式のモジュールもあれば, 一般の方が用意したモジュールもあります。 モジュールは言わば, 「便利な道具箱」や「パワーアップのアイテム」のようなものです。 プログラミングの世界には「車輪の再発明を避ける」という言い方があります。 これは, すでに誰かが車輪を発明していたなら, 1から車輪を再発明するために時間をかけるのではなく, 車輪を使ってもっといいものを作ろうということです。 Pythonでも, もし誰かが便利な機能を実装したコードを公開しているなら, それを使わせてもらい, もっと自分のやりたいことに集中しようということです。

Pythonが近年とても人気な理由の一つに, モジュールの多さが挙げられます。 例えば, 深層学習やデータサイエンスなどの分野ですぐに使えるような機能をまとめたモジュールがあります。

ただ, モジュールはとても便利ですが, 必ずしも自分がほしい機能がすべて備わっている保証はないので, 好きなようにカスタマイズできるようにPythonのプログラミング能力を向上させるのも大切です。

mathモジュールを使ってみよう

では, モジュールの使い方を「mathモジュール」というものを使って説明します。 mathモジュールには数学で使われる関数が多数入っています。 例えば, Pythonに\(\sqrt{2}\)を計算してほしいときには平方根の関数が必要ですが, mathモジュールには平方根を計算してくれる関数sqrtが含まれています。

まず, モジュールを利用するにはインポート(import)して自分の環境で使えるようにします。

とJupyter notebookのセルに書くと「math」というモジュールを自分の環境にインポートしたことになります。

次に, mathモジュールの中に入っている関数sqrtを使って\(\sqrt{2}\)を計算したいのですが, sqrt(2)と書くだけでは不十分なのです。 Pythonにsqrtはmathモジュールに入ってる関数だよと教えてあげる必要があるのでmath.sqrt(2)という風に書きます。 それではコードを見てみましょう。

##(実行結果) 1.4142135623730951

を実行すると1.4142135623730951と表示されます。 「ひとよひとよにひとみごろ」とゴロで覚えていた方もいらっしゃるかもしれませんね。

mathモジュールは, pythonをダウンロードしたときに一緒について来るモジュールです。 毎回数学の関数を使う必要はないかもしれませんが, 使いたいときにすぐ使えるようにモジュールになっています。

このように, インポートするだけですぐに様々な機能が追加で使えるようになるのがモジュールの良さです。 数学の知識を振り絞って, 平方根を計算する関数のコードを書くのもいいですが, 私たちの目標はPythonを使って数論を楽しむことです。 ここではモジュールを使わせてもらい, 時間と労力を節約しましょう。 これが「車輪の再開発を避ける」ということです。

mathモジュールに含まれる他の関数

mathモジュールにはsqrt以外にも数学計算に使えるたくさんの関数や変数が含まれています。

ここでは, その中からいくつか紹介したいと思います。 他にも色々な関数があるので, ぜひ公式のドキュメントを読んでみてください。

math.ceil(x)

関数math.ceil(x)\(x\)以上の最小の整数を返します。 ceilは天井を表す英語ceilingから来ています。

##(実行結果) 3

math.floor(x)

関数math.floor(x)\(x\)以下の最大の整数を返します。 floorは英語で床という意味です。

##(実行結果) 2

math.gcd(a, b)

関数math.gcd(a, b)は整数\(a\)\(b\)最大公約数を返します。 例えば

##(実行結果) 2 1 9

math.log(x)

関数math.log(x)\(x\)の自然対数\(\log(x)=\log_e(x)=\ln(x)\)を返します。 自然対数とは底が\(e\)(ネイピア数)の対数のことです。 2つめの引数を追加すると底を指定することができます。 たとえばmath.log(9, 3)は$\log_3(9)$を意味します。

##(実行結果) 2.0

math.pow(x, y)

関数math.pow(x, y)\(x^y\)を返します。 例えば\(2^{1/3}\)を計算するには

##(実行結果) 1.2599210498948732

定数math.pi, math.e

mathモジュールには数学でよく使われる定数も含まれています。 円周率の\(\pi\)math.pi, 自然対数の底に使われているネイピア数\(e\)math.eで使うことができます。

三角関数math.sin(x), math.cos(x), math.tan(x)

三角関数\(\sin(x), \cos(x), \tan(x)\)はそれぞれmath.sin(x), math.cos(x), math.tan(x)という関数で使えます。

##(実行結果) 0.0 -1.0 0.9999999999999999

実践!

これまで習ったPythonのテクニックを使って「与えられた自然数の最小の素因数を返す関数」を作ってみましょう。

この関数には, 素数が無限個あることについての考察で証明した次の定理を利用します。

定理

与えられた自然数\(n\)が合成数ならば\(n\)\(\sqrt{n}\)以下に少なくとも1つは素因数を持つ。

それでは, 「与えられた自然数の最小の素因数を返す関数」を作ってみましょう。 下の答えを見る前にぜひ挑戦してみてください。 しっかりと動くプログラムを書けなくても大丈夫です。 完璧なコードが書けなくても, こういう動きをPythonにさせたい, などと考えることが大切です。

この定理を使うと, もし与えられた自然数\(n\)が合成数なら最小の素因数は\(\sqrt{n}\)以下で発見できますし, もしそのような素因数がなければ\(n\)自身が素数なので\(n\)を返せばいいことになります。 これをPythonのコードに書くと

このコードを詳しくみていきましょう。 まず平方根\(\sqrt{n}\)を使いたいのでmathモジュールをインポートします。 次に, defを使って min_prime_factorという名前の関数を定義し始めます。

3行目から5行目にかけてforループがあります。 \(i\)を2から\(\sqrt{n}\)までの整数としたいのですが, rangeの使い方に注意です。 まずrange(a,b)\(a, b\)は整数ではなければいけませんが\(\sqrt{n}\)は整数とは限りません。 そこでmath.floorを用いて\(\sqrt{n}\)以下の最大の整数を求めています。 もうひとつ, range(a, b)\(a\)から\(b-1\)までの整数の範囲であることに注意します。 よって, \(\sqrt{n}\)以下にしたい場+1をする必要があります。 これがrangeの部分の説明です。

forループの処理の部分にはif文が使われていますif n % i == 0:\(n\)\(i\)で割り切れるかどうかをチェックしています。 もし割り切れる場合はreturn i\(i\)の値を返します。 ここで注目してほしいことは, もしreturn i\(i\)の値を返した場合には, forループはその時点で終了して関数は役目を終えるということです。 もしも\(i\)\(n\)を割り切らないのであればelifelseもないのでforループで次の\(i\)の値で同様のことを繰り返します。

もしも\(\sqrt{n}\)以下に\(n\)を割り切る整数\(i\)が存在しない場合には, 定理より\(n\)自身が素数だとわかるので最後の行で\(n\)を返しています。

モジュールをインポートする別の方法

先ほどみた例の中に出てくるrange(2, math.floor(math.sqrt(n))の部分ですが, なんだかごちゃごちゃしていませんか。 ここに出てくるfloorsqrtがmathモジュールに入っている関数なので先頭にmath.を付ける必要がありました。 毎回math.を付けるのが面倒だと感じるかもしれません。 この問題を解決する方法をご紹介します。

モジュールから一部の機能だけをimportする方法

これまではmathモジュールを使うためにimport mathと書いていました。 これによりmathモジュールに入っているすべての機能が使えるようになっていました。 ただ, mathモジュールには数多くの関数が含まれていますが, 毎回全部を使うわけではありません。 そこで, 必要なものだけを取り出して使う方法があります。 その書き方が

です。 例を見てみましょう。

##(実行結果) 2

from math import sqrt, floorでmathモジュールからsqrtfloorの2つの関数だけをインポートしています。 このように特定の機能だけをインポートした場合にはmath.のようにモジュール名を指定して関数を使わなくてもよいのです。

新しい名前をつけてimportする方法

モジュールから機能をインポートするときに, 自分で好きな名前をつけてインポートすることもできます。 例えばsqrtという名前がわかりにくい。 もっと日本語らしい名前にしたい, というのであればasを使って

##(実行結果) 1.4142135623730951

のようにすることができます。 (ただしheihoukonと名前をつけるのはおすすめしません。)

次回予告

次回はmathモジュール以外のモジュールを使って素数を扱う関数を使ってみましょう。

前のトピック

はじめてのPython

Pythonの基礎をマスターしよう

今回はプログラミング言語であるPythonの基礎的な使い方を学んでいきましょう。 今まで全くプログラミングに触ったことがない人でも大丈夫なように基礎の基礎から始めます。 続きを読む

次のトピック

Pythonモジュール「SymPy」の数論に関する関数の使い方

前回はPythonでモジュールをインストールして使用する方法を学びました。 例として、mathモジュールを使って平方根などの計算を行いました。 今回は整数論の勉強に役立つモジュールSymPyを使ってみましょう。 これまでに紹介した素数に関するデータをSymPyモジュールに入ってる関数を用いて取得する方法も紹介します。

続きを読む