Ik heb een programma geschreven om y = a^x
op te lossen en dan te projecteren op een grafiek. Het probleem is dat wanneer a < 1
ik de foutmelding krijg:
ValueError: ongeldige lettergreep voor int () met basis 10.
Iemand suggesties?
Hier's de traceback:
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'
Het probleem ontstaat telkens als ik een getal zet dat kleiner is dan 1, maar groter dan 0. In dit voorbeeld was dat 0.3 .
Dit is mijn code:
# 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")
Je traceback vertelt je dat int()
gehele getallen neemt, jij probeert een decimaal te geven, dus moet je float()
gebruiken:
a = float(a)
Dit zou moeten werken zoals verwacht:
>>> 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
Computers slaan getallen op verschillende manieren op. Python heeft twee hoofdmanieren. Gehele getallen, die gehele getallen opslaan (ℤ), en drijvende komma getallen, die reële getallen opslaan (ℝ). Je moet de juiste gebruiken, afhankelijk van wat je nodig hebt.
(Als opmerking, Python is vrij goed in het abstraheren van dit voor je weg, de meeste andere talen hebben ook dubbele precisie drijvende komma getallen, bijvoorbeeld, maar je hoeft je daar geen zorgen over te maken. Sinds 3.0 zal Python ook automatisch gehele getallen omzetten naar floats als je ze deelt, dus het'is eigenlijk heel gemakkelijk om mee te werken).
Je probleem is dat wat je typt niet kan'worden omgezet in een getal. Dit kan veroorzaakt worden door een heleboel dingen, bijvoorbeeld:
>>> 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'
Het toevoegen van een spatie tussen de -
en 1
zal ervoor zorgen dat de string niet correct in een getal wordt geparseerd. Dit is natuurlijk maar een voorbeeld, en u zult ons moeten vertellen welke invoer u geeft om ons met zekerheid te kunnen zeggen wat het probleem is.
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)]
Dit is een voorbeeld van een echt slechte codeer gewoonte. Waar je steeds weer iets kopieert klopt er iets niet. Ten eerste gebruik je int(a)
een heleboel keer, overal waar je dit doet, zou je in plaats daarvan de waarde moeten toewijzen aan een variabele, en die in plaats daarvan gebruiken, om te voorkomen dat je de waarde steeds opnieuw typt (en de computer dwingt om de waarde steeds opnieuw te berekenen):
a = int(a)
In dit voorbeeld wijs ik de waarde weer toe aan a
, waarbij ik de oude waarde overschrijf met de nieuwe die we willen gebruiken.
y = [a**i for i in x]
Deze code geeft hetzelfde resultaat als het monster hierboven, zonder de massa's van het steeds weer uitschrijven van hetzelfde. Het'is een eenvoudige [list comprehension][1]. Dit betekent ook dat als je x
bewerkt, je niets aan y
hoeft te doen, het wordt vanzelf aangepast.
Merk ook op dat PEP-8, de Python stijlgids, sterk suggereert dat je geen spaties laat staan tussen een identifier en de haakjes bij het maken van een functie-aanroep.
Zoals Lattyware al zei, is er een verschil tussen Python2 & Python3 dat tot deze fout leidt:
Met Python2, int(str(5/2))
geeft je 2.
Met Python3, hetzelfde geeft je: ValueError: ongeldig letterlijk voor int() met basis 10: '2.5'
Als je een string moet converteren die float kan bevatten in plaats van int, moet je altijd de volgende lelijke formule gebruiken:
int(float(myStr))
Als float('3.0')
en float('3')
geven je 3.0, maar int('3.0')
geeft je de fout.
Het is misschien beter om a
te valideren op het moment dat het wordt ingevoerd.
try:
a = int(input("Enter 'a' "))
except ValueError:
print('PLease input a valid integer')
Dit cast a
naar een int zodat je er zeker van bent dat het een integer is voor later gebruik of het handelt de uitzondering af en waarschuwt de gebruiker