ValueError: ugyldig literal for int () med base 10

Jeg skrev et program for å løse y = a^x og deretter projisere det på en graf. Problemet er at hver gang a < 1 får jeg feilen:

ValueError: ugyldig bokstav for int () med base 10.

Noen forslag?

Her er sporingen:

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' 

Problemet oppstår hver gang jeg setter et tall som er mindre enn en, men større enn 0. For dette eksemplet var det 0,3 .

Dette er koden min:

#  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")
Løsning

Svar:

Tracebacken din forteller deg at int() tar heltall, du prøver å gi et desimaltall, så du må bruke float():

a = float(a)

Dette bør fungere som forventet:

>>> 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

Datamaskiner lagrer tall på en rekke forskjellige måter. Python har to hovedmåter. Heltall, som lagrer hele tall (ℤ), og flyttall, som lagrer reelle tall (ℝ). Du må bruke den riktige basert på hva du trenger.

(Som en merknad er Python ganske flink til å abstrahere dette fra deg, de fleste andre språk har for eksempel også flytende tall med dobbel presisjon, men du trenger ikke å bekymre deg for det. Siden 3.0 vil Python også automatisk konvertere heltall til flyttall hvis du deler dem, så det er faktisk veldig enkelt å jobbe med).

Forrige gjetning på svaret før vi hadde sporingen:

Problemet ditt er at det du skriver ikke kan konverteres til et tall. Dette kan være forårsaket av mange ting, for eksempel:

>>> 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'

Å legge til et mellomrom mellom - og 1 vil føre til at strengen ikke blir analysert riktig til et tall. Dette er selvfølgelig bare et eksempel, og du må fortelle oss hva du skriver inn for at vi skal kunne si med sikkerhet hva problemet er.

Råd om kodestil:

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)]

Dette er et eksempel på en veldig dårlig kodingsvane. Der du kopierer noe igjen og igjen er noe galt. For det første bruker du int(a) massevis av ganger, uansett hvor du gjør dette, bør du i stedet tilordne verdien til en variabel, og bruke den i stedet, og unngå å skrive (og tvinge datamaskinen til å beregne) verdien igjen og igjen:

a = int(a)

I dette eksemplet tilordner jeg verdien tilbake til a, og overskriver den gamle verdien med den nye vi ønsker å bruke.

y = [a**i for i in x]

Denne koden produserer det samme resultatet som monsteret ovenfor, uten massene av å skrive ut det samme igjen og igjen. Det er en enkel [listeforståelse][1]. Dette betyr også at hvis du redigerer x, trenger du ikke å gjøre noe med y, det vil naturligvis oppdatere seg til å passe.

Legg også merke til at PEP-8, Python-stilguiden, anbefaler sterkt at du ikke etterlater mellomrom mellom en identifikator og parentesene når du foretar et funksjonskall.

Kommentarer (4)

Som Lattyware sa, er det en forskjell mellom Python2 og Python3 som fører til denne feilen:

Med Python2 gir int(str(5/2)) deg 2. Med Python3 gir det samme deg: ValueError: ugyldig literal for int() med base 10: '2.5'

Hvis du trenger å konvertere en streng som kan inneholde float i stedet for int, bør du alltid bruke følgende stygge formel:

int(float(myStr))

Ettersom float('3.0') og float('3') gir deg 3.0, men int('3.0') gir deg feilen.

Kommentarer (2)

Det kan være bedre å validere a rett når det legges inn.

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

Dette gjør enten a til en int slik at du kan være sikker på at det er et heltall for all senere bruk, eller det håndterer unntaket og varsler brukeren.

Kommentarer (0)