私はy = a^x
を解き、それをグラフに投影するプログラムを書きました。問題は a < 1
の時に必ずエラーが出てしまうことです。
ValueError: invalid literal for int () with base 10.
何か提案はありますか?
以下はそのトレースバックです。
Traceback (most recent call last):
File "C:\Users\kasutaja\Desktop\EksponentfunktsioonTEST - koopia.py", line 13, in <module>
if int(a) < 0:
ValueError: invalid literal for int() with base 10: '0.3'
この問題は、1より小さく0より大きい数字を入力するたびに発生します。
これが私のコードです。
# y = a^x
import time
import math
import sys
import os
import subprocess
import matplotlib.pyplot as plt
print ("y = a^x")
print ("")
a = input ("Enter 'a' ")
print ("")
if int(a) < 0:
print ("'a' is negative, no solution")
elif int(a) == 1:
print ("'a' is equal with 1, no solution")
else:
fig = plt.figure ()
x = [-2,-1.75,-1.5,-1.25,-1,-0.75,-0.5,-0.25,0,0.25,0.5,0.75,1,1.25,1.5,1.75,2]
y = [int(a)**(-2),int(a)**(-1.75),int(a)**(-1.5),int(a)**(-1.25),
int(a)**(-1),int(a)**(-0.75),int(a)**(-0.5),int(a)**(-0.25),
int(a)**(0),int(a)**(0.25),int(a)**(0.5),int(a)**(0.75),
int(a)**1,int(a)**(1.25),int(a)**(1.5),int(a)**(1.75), int(a)**(2)]
ax = fig.add_subplot(1,1,1)
ax.set_title('y = a**x')
ax.plot(x,y)
ax.spines['left'].set_position('zero')
ax.spines['right'].set_color('none')
ax.spines['bottom'].set_position('zero')
ax.spines['top'].set_color('none')
ax.spines['left'].set_smart_bounds(True)
ax.spines['bottom'].set_smart_bounds(True)
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
plt.savefig("graph.png")
subprocess.Popen('explorer "C:\\Users\\kasutaja\\desktop\\graph.png"')
def restart_program():
python = sys.executable
os.execl(python, python, * sys.argv)
if __name__ == "__main__":
answer = input("Restart program? ")
if answer.strip() in "YES yes Yes y Y".split():
restart_program()
else:
os.remove("C:\\Users\\kasutaja\\desktop\\graph.png")
トレースバックによると、int()は整数を受け取りますが、あなたは10進数を与えようとしているので、float()を使う必要があります。
a = float(a)
これで期待通りに動作するはずです。
>>> int(input("Type a number: "))
Type a number: 0.3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '0.3'
>>> float(input("Type a number: "))
Type a number: 0.3
0.3
コンピュータは様々な異なる方法で数値を保存します。Pythonには大きく分けて2つの方法があります。整数(ℤ)を格納する整数と、実数(ℝ)を格納する浮動小数点数です。必要なものに応じて使い分ける必要があります。
(他の言語では倍精度の浮動小数点数が使われていますが、これは気にしなくてもよいでしょう。3.0以降のPythonでは、整数を割ると自動的に浮動小数点数に変換してくれるので、実はとても扱いやすいのです)
あなたの問題は、あなたが入力しているものが何であれ、数値に変換できないことです。これには様々な原因が考えられますが、例えば次のようなことが考えられます。
>>> int(input("Type a number: "))
Type a number: -1
-1
>>> int(input("Type a number: "))
Type a number: - 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '- 1'
-と
1`の間にスペースを入れると、文字列が正しく解析されず、数値になりません。もちろん、これは単なる例であり、何が問題なのかをはっきりさせるためには、どのような入力をしているのかを教えていただく必要があります。
y = [int(a)**(-2),int(a)**(-1.75),int(a)**(-1.5),int(a)**(-1.25),
int(a)**(-1),int(a)**(-0.75),int(a)**(-0.5),int(a)**(-0.25),
int(a)**(0),int(a)**(0.25),int(a)**(0.5),int(a)**(0.75),
int(a)**1,int(a)**(1.25),int(a)**(1.5),int(a)**(1.75), int(a)**(2)]
これは、本当に悪いコーディングの癖の例です。何度も何度もコピーしているところは、何かが間違っています。まず、int(a)を何度も使っていますが、このような場合には、代わりに値を変数に代入し、それを使うことで、何度も値を入力する(そしてコンピュータに計算させる)のを避けるべきです。
a = int(a)
この例では、値を a
に戻して、古い値を使いたい新しい値で上書きしています。
y = [a**i for i in x]
このコードは、上のモンスターと同じ結果をもたらしますが、同じことを何度も書き出すという手間はありません。これは単純な[リスト内包][1]です。また、x
を編集した場合、y
に何もしなくても、自然にそれに合わせて更新されるということです。
また、PEP-8, the Python style guideでは、関数呼び出しの際に識別子と大括弧の間にスペースを空けないようにすることを強く推奨していることにも注意してください。
Lattywareさんがおっしゃるように、Python2とPython3の違いがこのエラーにつながっています。
Python2では、int(str(5/2))
で2が得られます。
Python2では、int(str(5/2))
で2が得られますが、Python3ではValueError: invalid literal for int() with base 10: '2.5'
intではなくfloatを含む可能性のある文字列を変換する必要がある場合は、常に以下の醜い式を使用する必要があります。
int(float(myStr))
float('3.0')と
float('3')では3.0になりますが、
int('3.0')`ではエラーになってしまいます。