simple python program help! - python

This program is supposed to calculate the number of degrees below 60 on a given day then create a running sum of degrees. count equals the sum of degrees below 60. However, when I run it I get this error:
cool = 60 - temp
TypeError: unsupported operand type(s) for -: 'int' and 'str'
Any ideas on why it's doing this? Thanks!
def cold_days():
temp = eval(input("What is the temperature? "))
count = 0
if temp < 60:
while temp !="quit":
temp = eval(input("What is the temperature? "))
cool = 60 - temp
count = count + heat
print(count)
else:
print("you have no cold days")

You need to turn temp into an int:
...
try:
temp = int(temp)
except TypeError:
# Handle invalid integer
print("%s is not a valid integer." % temp)
sys.exit(1)
...

In Python 3, the input() function always returns a string (this is different from Python 2, and could be the source of the confusion since the Python tutorial you're using might be unaware of Python 3). Since Python is strongly (but dynamically) typed, you can't perform arithmetic calculations using a string and an integer, as your error message shows. You must first convert the temp string into an integer using int():
temp = int(temp)
If temp does not contain something that can be converted to an integer, you will get a ValueError exception. By default, an exception will terminate your program with an informative error message. To handle the exception and take alternative action, your Python tutorial should have a whole chapter on that.

You can just drop the 'eval' since input does return the correct type. Or typecast the temp to int:
temp = int(temp)

I think you need to rethink how you are reading in data. input() returns eval() of whatever text the user types in, so I would expect an error when the user types "quit".
Instead, I suggest using raw_input() which returns text. Then check if it is equal to "quit" before converting to an int.

Related

Calculate Long String Of Input [duplicate]

I am just starting to learn Python and am trying to handle errors a user might input. All the program does is use the math module, asks the user for an integer and returns the factorial of the number.
I am trying to catch errors for negative numbers, floats and text.
If I enter an integer the code runs like it should.
When I enter a wrong value, like -9 or apple, the try/except seems to not catch the error and I get the traceback information. The user shouldn't see this.
Any suggestions or pointers?
import math
from datetime import datetime
import time
num = 0
start = 0
end = 0
# max value is 2147483647
#if __name__ == '__main__':
try:
num = input("Enter a number: ")
except OverflowError:
print("Input cannot exceed 2147483647")
except ValueError:
print("Please enter a non-negative whole number")
except NameError:
print("Must be an integer")
else:
start = datetime.now()
print("The factorial of ", num, " is : ")
print(math.factorial(int(num)))
end = datetime.now()
print(f"Time taken in (hh:mm:ss.ms) is {end - start}")
I am using Python 3.10 on a Windows 10 Pro (64-bit) PC if that matters.
Norman
Your code is missing the operation which can cause the exception: in fact, input('...') returns a string representing whatever user inputs. This means that your num variable is a string (you can check by printing type(num).
You have to try to cast it into an integer:
try:
num = int(input('...'))
except ValueError:
print('invalid input')
Be carefull: if user input the value "-3", it will be accepted: the string will be cast into the integer -3 and this is correct.
If user inputs words like 'apple' or floats like 3.14, the exception raised is ValueError.
My suggest is to do something like this:
try:
num = int(input('...'))
if num >= 0:
# computing factorial
else:
print('error: only positive numbers will be accepted')
return
except ValueError:
print('invalid input')
That is because input() do not raise an error just because you want just a number. You have to check the type of input by yourself and then also raise an error by yourself.
e.g.
if not isinstance("string", int):
raise ValueError
edit: also have a look here for more information about input(): https://www.python-kurs.eu/python3_eingabe.php
It always returns a string, so you have to convert your input actively in the type you want and make your type check during/after the conversion
I took the path yondaime offered and got pretty close to what I wanted. The final result is below.
I thank all of you for your comments. The last time I did anything even slightly like programming was in Fortran on punch cards on an IBM 360.
I apologize for asking such basic questions but really am trying.
The code that works but really doesn't point out exactly which fault happened. I will try to figure out how to convert the string in the input statement to a float and see if there is a remainder (modulo maybe?) so the user gets a better hint what was wrong.
import math
from datetime import datetime
import time
num = 0
start = 0
end = 0
try:
num = int(input('Enter a positive whole number: '))
if (num >= 0 and num <= 2147483647):
start = datetime.now()
print("The factorial of ", num, " is : ")
print(math.factorial(int(num)))
end = datetime.now()
else:
print('Number must be between 0 and 2147483647 are allowed.')
print(f"Time taken in (hh:mm:ss.ms) is {end - start}")
except ValueError:
print('Text or decimal numbers are not allowed. Please enter a whole number between 0 and 2147483647')
I have a lot time to learn because I'm bored in retirement ...
Norman

Python beginner help input error handling

I am just starting to learn Python and am trying to handle errors a user might input. All the program does is use the math module, asks the user for an integer and returns the factorial of the number.
I am trying to catch errors for negative numbers, floats and text.
If I enter an integer the code runs like it should.
When I enter a wrong value, like -9 or apple, the try/except seems to not catch the error and I get the traceback information. The user shouldn't see this.
Any suggestions or pointers?
import math
from datetime import datetime
import time
num = 0
start = 0
end = 0
# max value is 2147483647
#if __name__ == '__main__':
try:
num = input("Enter a number: ")
except OverflowError:
print("Input cannot exceed 2147483647")
except ValueError:
print("Please enter a non-negative whole number")
except NameError:
print("Must be an integer")
else:
start = datetime.now()
print("The factorial of ", num, " is : ")
print(math.factorial(int(num)))
end = datetime.now()
print(f"Time taken in (hh:mm:ss.ms) is {end - start}")
I am using Python 3.10 on a Windows 10 Pro (64-bit) PC if that matters.
Norman
Your code is missing the operation which can cause the exception: in fact, input('...') returns a string representing whatever user inputs. This means that your num variable is a string (you can check by printing type(num).
You have to try to cast it into an integer:
try:
num = int(input('...'))
except ValueError:
print('invalid input')
Be carefull: if user input the value "-3", it will be accepted: the string will be cast into the integer -3 and this is correct.
If user inputs words like 'apple' or floats like 3.14, the exception raised is ValueError.
My suggest is to do something like this:
try:
num = int(input('...'))
if num >= 0:
# computing factorial
else:
print('error: only positive numbers will be accepted')
return
except ValueError:
print('invalid input')
That is because input() do not raise an error just because you want just a number. You have to check the type of input by yourself and then also raise an error by yourself.
e.g.
if not isinstance("string", int):
raise ValueError
edit: also have a look here for more information about input(): https://www.python-kurs.eu/python3_eingabe.php
It always returns a string, so you have to convert your input actively in the type you want and make your type check during/after the conversion
I took the path yondaime offered and got pretty close to what I wanted. The final result is below.
I thank all of you for your comments. The last time I did anything even slightly like programming was in Fortran on punch cards on an IBM 360.
I apologize for asking such basic questions but really am trying.
The code that works but really doesn't point out exactly which fault happened. I will try to figure out how to convert the string in the input statement to a float and see if there is a remainder (modulo maybe?) so the user gets a better hint what was wrong.
import math
from datetime import datetime
import time
num = 0
start = 0
end = 0
try:
num = int(input('Enter a positive whole number: '))
if (num >= 0 and num <= 2147483647):
start = datetime.now()
print("The factorial of ", num, " is : ")
print(math.factorial(int(num)))
end = datetime.now()
else:
print('Number must be between 0 and 2147483647 are allowed.')
print(f"Time taken in (hh:mm:ss.ms) is {end - start}")
except ValueError:
print('Text or decimal numbers are not allowed. Please enter a whole number between 0 and 2147483647')
I have a lot time to learn because I'm bored in retirement ...
Norman

Error "invalid syntax" appears when trying to redirect using input/output in Python shell

I tried to practice input/output redirection in the Python shell. I have a file named SentinelValue.py which is where I have this code to add up the numbers in another file:
data = eval(input("Enter an integer (the input ends " + "if it is 0): "))
sum = 0
while data != 0:
sum += data
data = eval(input("Enter an integer (the input ends " + "if it is 0): "))
print("The sum is", sum)
The other file "Numbers.txt" contains numbers:
1
2
3
4
5
6
7
8
9
0
and my output.txt file is where I want the sum to show.
I tried using:
python SentinelValue.py < Numbers.txt > output.txt
but on shell, it highlights "SentinelValue" & says "invalid syntax".
I don't know why it's not working.
There are several things wrong with your code:
As already suggested in the comments, do not use eval() for a direct user input (or pretty much any time, in 99% cases when you think you need it - you don't!). A simple int() conversion should be more than enough without all the dangers of eval().
Connected with the previous, eval() evaluates the input. Further more, on Python 2.x input() itself does the evaluation (it's an equivalent of eval(raw_input())) so whenever it encounters an invalid input it will pop a SyntaxError.
Even if it doesn't pop a SyntaxError, it will most certainly pop a TypeError as eval() expects a string and it will receive an integer from the inner input().
You're printing the "Enter an integer..." prompt to STDOUT which will result it ending up in your output.txt (where you redirect the STDOUT).
You're shadowing the built-in sum() by using it as one of your variables. That's a bad practice that can lead to many problems and unexpected results down the line.
So, with all that in mind, here's how to rewrite it to address these issues:
# Let's first make sure it works on Python 2.x and 3.x by shadowing the input
try:
input = raw_input # on Python 2.x use raw_input instead of input
except NameError:
pass
result = 0 # tip: use a name that's not already built-in, like result
while True: # loop 'forever'...
data = input() # don't print anything when asking for input
try:
data = int(data) # don't print anything to STDOUT
if not data: # only if the integer is 0
break
result += data # add to the final result
except ValueError: # risen if the input is not an integer...
pass # so just ignore it
print("The sum is: " + str(result)) # finally, print the result

Opening files in pygame error

I just can't figure out the problem. So i'm making a game and im using money to buy things in the game and this doesn't seem to be working. I try to write the new spent money in the .txt file and i just get an error.
with open("money.txt", "r") as rm:
game_money = rm.read()
with open("money.txt", "w") as fm:
fm.write(str(game_money))
def Function():
............
slowdown_price = 20
elif action == "buy_slowdown":
if game_money >= 20:
time.sleep(0.5)
game_money -= slowdown_price
slowdown_powerup += 1
with open("money.txt", "w") as wm:
wm.write(str(game_money))
I get the following error:
TypeError: unsupported operand type(s) for -=: 'str' and 'int'
You are using Python 2, which will happily compare integers with strings, so if game_money >= 20: works fine. However, you can't subtract an integer from a string, so game_money -= slowdown_price fails. Convert that value to an integer (or float) after you read it in:
game_money = int(rm.read())
or
game_money = float(rm.read())
If you use floating-point numbers, keep in mind that they aren't exact, so exact comparisons with == and != aren't reliable.
Reading from a file results in a string. That means that game_money is a string that contains the characters of a number, e.g "30".
You should cast the string to an integer:
game_money = int(rm.read())
Do take note that this could fail if the file does not contain just a number, but other non-numerals.
It seams that you try to substract number slowdown_price from text game_money. You have to convert game_money to number first. ie.
game_money = int(game_money)

How to do the correct casting using a loop in python?

The objective is to write a program that will increase the population every 7 and 35 seconds and decrease every 13 seconds. I am trying to use a loop for this program and I am having some problems with getting the right casting for each variable. Here's the code:
#(1)There is a birth every 7 seconds (2)There is a death every 13 seconds (3)There is a new
immigrant every 35 seconds.
#CURRENT POP: 307,357,870
populationCurrent = input("What is the current population")
x=0
while x!=100:
if (x%7==0):
populationCurrent=populationCurrent+1
x=x+1
elif (x%13==0):
populationCurrent=populationCurrent-1
x=x+1
elif (x%35==0):
populationCurrent+=1
x=x+1
else:
x=x+1
print("The population will be "+int(populationCurrent)+".")
Thank you for your time.
I think you are confused in python2 and python3, there's a difference in input() function of python 2.x and python 3.x, where input() function gives an integer value in python 2 and str in python 3
input() is str by default so, this should be converted to int
populationCurrent = str(input("What is the current population"))
You cannot concatenate string and int
print("The population will be "+str(populationCurrent)+".")
Its easier to do this than iterate through 100 times
populationCurrent += 100//7 + 100//35 - 100//13
You need to convert populationCurrent to an integer immediately after you read the string.
populationCurrent = int(input("What is the current population"))
Note that if you don't enter a string that is a valid integer representation, this will raise a ValueError. You might want to consider how to handle that (catch it and use a default value? catch it and try to read another value? Let the exception propagate?)
With this change, you'll have to convert the integer value back to a string for the output:
print("The population will be "+str(populationCurrent)+".")
or using any of the various string formatting tools available. It's better to have populationCurrent as an integer, since there are more places in your code that assume it to be an integer than assume it to be a string.
The only thing you need to do is convert populationCurrent from string to int:
populationCurrent = int(input("What is the current population?"))
The more concerning stuff is that your code doesn't do what it's supposed to: when x is 35 you will only have one birth, since 35 % 7 is 0, but no immigrant will arrive. Do something like this, removing the elif statements which do not make the code that more efficient anyway:
while x!=100:
if (x%7==0):
populationCurrent=populationCurrent+1
if (x%13==0):
populationCurrent=populationCurrent-1
if (x%35==0):
populationCurrent+=1
x=x+1
print("The population will be ", populationCurrent, ".")
Though still note that the loop will stop after x gets to 100. You could reset it but I don't know for how long you want it to run.
def intInput(prompt):
while 1:
try: return int(input(prompt))
except ValueError: print("Invalid Input!")
def YearToModifier(x):
if x%35 ==0 or x%7 ==0: return 1
if x%13 == 0: return -1
return 0
populationCurrent = intInput("What is the current population?") #ensure you get an int
n_years = intInput("How Many Years?") #ensure you get an int
#in this case populationChange is independent of initial population (this is rarely the case in reality)
populationChange = sum(YearToModifier(x) for x in range(n_years))
#the population in the future is the initialPopulation + population Change ... duh...
populationFuture = populationCurrent + populationChange
print("The Population will be %d!"%populationFuture)
there you go
WRT #martjinpeters comment on OP you could change YearToModifier to
def YearToModifier(x):
return sum([x%35 ==0,x%7 ==0,-1*int(x%13 == 0)])
of coarse as #AshokaLella points out you can calculate the total births/immigrations/deaths for a given number of years without actually visiting each year
births = n_years//7
immigrations = n_years//35
deaths = n_years//13
populationChange = births + immigrations - deaths

Categories

Resources