BLOG

ブログ

新着記事

2019.12.27 Python

Python勉強記初級編 SymPyを使って問題を解く

はじめまして、フェブラリーです。こんな名前ですが2月生まれでもないですしなんなら夏生まれです。

(先日インフルエンザA型にかかりました、皆さんもご自愛ください)

さて7月にFabeeeに入社してはや5ヶ月、仕事納めも間近ですがついにブログを書く順番が回ってきました。

公開時期的にクリスマスとか年末の時事ネタが何か思いつけばよかったんですけど、実は業務で扱っている言語とはまた別で、最近中学~高校数学の範囲でPythonを使った計算をちまちま自分の頭の体操がてらやり始めました。

なぜこんなことをやっているのかというとただの興味本位なんですけど、実践の場の有無は置いといて入試問題の数学がPythonで解けたら楽だよなあという漠然とした思いから始めました。

なので今回は数学問題をPythonで解いてみた際の所感などを解きながら書けていけたらと思います。

(普段からPythonを触っている方々にとっては既知の事実だと思いますのでスクロールしていただいて結構です)

 

 

普段自分はSymPyという代数計算ライブラリを使って問題を解いています。

話を進めていくために兎にも角にもまずはSymPyをインストールしていきます。
$ pip install sympy

 

まずいきなり結論から述べると、「正直手で書いたほうが速い」

この記事を書く前に手始めに簡単な入試問題やセンター試験の問題を実際解いてはみたのですが、自分がまだ不慣れであることも加味しても、正直簡単な式だったらコードを書くよりも手で計算したほうが明らかに速いです。もともと世の中に問題として出回っているものは手で計算することが前提というのもあるかもしれませんが…(将来はコードを書いて計算しなさいという宿題も課される時がくるのかな)
なので、手で計算するよりSymPyを使って楽をした!と思えるような計算≒手計算でやると明らかに面倒そうなものをあえてやっていきます。

 

例題1
x * (x + 1) * (x + 2) * (5 - x) * (4 - x) * (3 - x) を展開せよ

 

現役時代の自分だったら面倒くささから露骨に嫌な顔をしそうな問題ですね、けれどもSymPyなら大丈夫!

import sympy as sy
# 変数を定義
x = sy.symbols('x', real=True)

# 式をAとおく
A = x * (x + 1) * (x + 2) * (5 - x) * (4 - x)

# Aを展開する
ANS_A = sy.expand(A)
print(f'Aの式を展開すると{ANS_A}となる')

上記を実行してみます。結果は以下。

Aの式を展開するとx**5 - 6*x**4 - 5*x**3 + 42*x**2 + 40*xとなる

コードを実行して答えが出るまで1秒もかかりませんでした。手計算だったら途中で放棄してしまいそうです。次の例題はこれ。

 

 

例題2
(x + n) * (n + 5  - x) をxについてまとめよ

 

まずこのままだとまとめられないので式を展開します(変数の定義は省略)

B = (x + n) * (n + 5  - x)
ANS_B = sy.expand(B)

# xについて同類項をまとめる
print('Bの式の同類項をまとめると'  +str(sy.collect_const(ANS_B, x)) + 'となる')

実行結果

Bの式の同類項をまとめるとn**2 + 5*n + x*(5 - x)となる

同類項をきれいにまとめることができました。欲を言えば見栄えの関係上nではなくxが先頭に来てほしかったのですが…

もうちょっと面倒そうな計算をやってみたいので、次は無理数を含む式を代入してみます。

全部SymPyがやってくれる想定ですべて書いているので、実際手計算でやったらどれほど面倒かはわかりません。

 

 

例題3
C = x(x-1)(x-2)(x-3)とおく
x = 3 + √13 / 2 のときのCの値を求めよ

上の例題と式が脈絡があるようでない問題なので手計算だとこれもまた地道に計算していかなければなりません。けれどもSymPyなら大丈夫!

# 変数Xにxを代入
ANS_C = X.subs({x: (3 + sy.sqrt(13))/2})

# 代入した式を展開する
print('Cに入るのは' +str(sy.expand(ANS_C)))

実行結果

Cに入るのは3

今回代入する式が比較的複雑ではないので手計算でもまだ根気強くやれば解ける方だと思いますが(自分はやろうとは思えない)、それでもsubsメソッドはとても心強いですね。

 

■実際やってみて
SymPyはすごい。先述したように簡単な式であれば手で書いたほうが速そうですが、それでもたとえば一見面倒な式の展開もなんなくできるのは魅力的ですね。今回例題を3つ挙げましたが、この季節らしいことを述べますとセンター試験の第一問って(難易度はこれよりかは上ですが)例年こんな感じの問題だったと思うので、ライブラリの中でも今回使っていない微積や三角関数を使って業務の傍ら勉強の一環として他の問題も紐解いていきたい所存です。そしてこれとは別にPythonでやってみたいことはふんわりと頭に浮かんでいるので、次回それを記事としてアウトプットするところまで持っていきたいですね。

 

以上、フェブラリーでした!皆様も良いお年をお過ごしくださいませ。

SES/受託開発のご依頼についてはこちら