ValueError: невалиден литерал за int () с основа 10

Написах програма за решаване на 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' 

Проблемът възниква всеки път, когато поставям число, което е по-малко от единица, но по-голямо от 0. За този пример това беше 0.3 .

Това е моят код:

#  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() приема цели числа, а вие се опитвате да дадете десетично число, така че трябва да използвате float():

a = float(a)

Това би трябвало да работи както се очаква:

>>> int(input("Type a number: "))
Type a number: 0.3
Traceback (most recent call last):
  File "", line 1, in 
ValueError: invalid literal for int() with base 10: '0.3'
>>> float(input("Type a number: "))
Type a number: 0.3
0.3

Компютрите съхраняват числата по различни начини. В Python има два основни. Цели числа, в които се съхраняват цели числа (ℤ), и числа с плаваща запетая, в които се съхраняват реални числа (ℝ). Трябва да използвате правилния от тях в зависимост от това, което ви е необходимо.

(Като забележка, Python е доста добър в абстрахирането от това, повечето други езици също имат числа с плаваща запетая с двойна точност, например, но не е необходимо да се притеснявате за това. От версия 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 "", line 1, in 
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, ръководството за стила на Python, силно препоръчва да не оставяте интервали между идентификатора и скобите, когато правите извикване на функция.

Коментари (4)

Както каза Lattyware, има разлика между Python2 & Python3, която води до тази грешка:

В Python2, int(str(5/2)) дава 2. При Python3 същото дава: ValueError: invalid literal for int() with base 10: '2.5'

Ако трябва да преобразувате някакъв низ, който може да съдържа float вместо int, винаги трябва да използвате следната грозна формула:

int(float(myStr))

Тъй като float('3.0') и float('3') ви дават 3.0, но int('3.0') ви дава грешка.

Коментари (2)

Може би е по-добре да се валидира a още при въвеждането му.

try:
  a = int(input("Enter 'a' "))
except ValueError:
  print('PLease input a valid integer')

Това или превръща a в int, за да сте сигурни, че е цяло число за всички следващи употреби, или обработва изключението и предупреждава потребителя

Коментари (0)