Python program not accepting decimal raw input - python

I am working on small python payroll project where you enter employee name, wage, and hours worked. When I enter decimals for the wage input, I am getting "invalid entry" because of my exception handling. Why are decimals being returned as invalid? Also, how can I loop this program so that it keeps the same 3 questions until the user types "Done"?
Any help will be greatly appreciated!
Thanks!
import cPickle
def getName():
strName="dummy"
lstNames=[]
strName=raw_input("Enter employee's Name: ")
lstNames.append(strName.title() + " \n")
def getWage():
lstWage=[]
strNum="0"
blnDone=False
while blnDone==False: #loop to stay in program until valid data is entered
try:
intWage=int(raw_input("Enter employee's wage: "))
if intWage >= 6.0 and intWage <=20.0:
lstWage.append(float(strNum)) #convert to float
blnDone=True
else:
print "Wage must be between $6.00 and $20.00"
except(ValueError): #if you have Value Error exception. Explicit on error type
print "Invalid entry"
def getHours():
lstHours=[]
blnDone=False
while blnDone==False: #loop to stay in program until valid data is entered
try:
intHrs=int(raw_input("Enter number of hours worked: "))
if intHrs >= 1.0 and intHrs <=60.0:
blnDone=True
else:
print "Hours worked must be 1 through 60."
except(ValueError): #if you have Value Error exception. Explicit on error type
print "Invalid entry"
def getDone():
strDone=""
blnDone=False
while blnDone==False:
try:
srtDone=raw_input("Type \"DONE\" if you are finished entering names, otherwise press enter: ")
if strDone.lower()=="done":
blnDone=True
else:
print "Type another empolyee name"
except(ValueError): #if you have Value Error exception. Explicit on error type
print "Invalid entry"
##### Mainline ########
strUserName=getName()
strWage=getWage()
strHours=getHours()
srtDone1=getDone()

Here's the core of it:
>>> int("4.3")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '4.3'
You can't convert a string to an integer if it's not an integer. So when you do intWage=int(raw_input("Enter employee's wage: ")) it throws the ValueError. Perhaps you should convert it directly to float.

Because you're converting the input to int:
intWage=int(raw_input("Enter employee's wage: "))

You are assuming that the wage is an integer, which by definition does not have a decimal place. Try this:
intWage=float(raw_input("Enter employee's wage: "))

Try using
intWage=int(float(raw_input("Enter employee's wage: ")))
This will accept a decimal number as input.

Error w/ Floats
As others said before, you are assuming the input will be a float. Either use float() or eval()instead of int():
intWage = float(raw_input("Enter employee's wage: "))
Or use input() instead of int(raw_input()):
intWage = input("Enter employee's wage:")
Both will accomplish the same thing. Oh, and change intWage to floatWage atleast, or even better, don't use Hungarian Notation.
The Code
As for your code, I did a couple of things:
Used break and/or return to terminate loops instead of keeping track of booleans (that's the whole purpose of the break and continue statements)
Changed intWage to floatWage
Rewrote number comparisons in a more concise way (x <= y and x >= z can be written as z >= x >= y)
Added return statements. I don't get why you didn't put them yourself, unless you wanted to assign None to strUserName, strWage and strHours)
Added a loop as you requested when asking for an employee's details.
Modified getDone() to work w/ the loop.
import cPickle
def getName():
strName = "dummy"
lstNames = []
strName = raw_input("Enter employee's Name: ")
lstNames.append(strName.title() + " \n")
return strName
def getWage():
lstWage = []
strNum = "0"
while True: #Loop to stay in program until valid data is entered
try:
floatWage = float(raw_input("Enter employee's wage: "))
if 6.0 <= floatWage <= 20.0:
lstWage.append(floatWage)
return floatWage
else:
print "Wage must be between $6.00 and $20.00"
except ValueError: #Catches ValueErrors from conversion to float
print "Invalid entry"
def getHours():
lstHours = []
while True: #loop to stay in program until valid data is entered
try:
intHrs=int(raw_input("Enter number of hours worked: "))
if 1.0 <= intHrs <= 60.0:
return intHrs
else:
print "Hours worked must be 1 through 60."
except ValueError: #Catches ValueErrors from conversion to int
print "Invalid entry"
def getDone():
strDone = ""
while True:
srtDone = raw_input('Type "DONE" if you are finished entering names, otherwise press enter: ')
if strDone.strip().lower() == "done":
return True
else:
print "Type another empolyee name"
while not getDone():
strUserName = getName()
strWage = getWage()
strHours = getHours()
An Example of break and continue
The break statements inside a loop (for and while) terminate the loop and skip all 'else' clauses (if there are any).
Thecontinue statements skips the rest of the code in the loop and the continues the loop as if nothing happened.
The else clause in a for...else construct, executes its code block when the loop exhausted all the items and exited normally, i.e., when it's not terminated by break or something.
for no in range(2, 10):
for factor in range(2, no):
if no % factor == 0:
if factor == 2:
print "%d is even" % no
continue
# we want to skip the rest of the code in this for loop for now
# as we've already done the printing
print "%d = %d * %d" % (no, factor, n/x)
break
# We've asserted that the no. isn't prime,
# we don't need to test the other factors
else:
# if 'break' wasn't called
# i.e., if the loop fell through w/o finding any factor
print no, 'is a prime number'

Related

Is there a way to go to specific line or command in python?

I am going through book automate boring stuff with python and trying to solve the practical problems.
In this project I need to define collatz() function and print results as seen in code until it gets 1.
So basically i need to input only one number and program should return numbers until it returns 1.
Program works fine but i have one question if i can make it better :D .
My question is after using try: and except: is there a way to not end process when typing string in input function but to get message below 'You must enter number' and get back to inputing new number or string and executing while loop normally. Code works fine just wondering if this is possible and if so how?
def collatz(number):
if number % 2 == 0:
print(number // 2)
return number // 2
else:
print(3 * number + 1)
return 3 * number + 1
try:
yourNumber = int(input('Enter number: '))
while True:
yourNumber = collatz(yourNumber)
if yourNumber == 1:
break
except ValueError:
print('You must enter a number')
Put the try/except inside a loop, such that on the except the loop will continue but on a success it will break:
while True:
try:
yourNumber = int(input('Enter number: '))
except ValueError:
print('You must enter a number')
else:
break
while yourNumber != 1:
yourNumber = collatz(yourNumber)

Check for a string in if-statement

I have a program with some user inputs and I need to check if what the user entered was a string or an integer value between 1 and 10 million.
My code looks like this (simplified):
while True:
inp = raw_input("Enter a value between 1 and 10 million: ")
if inp < 1:
print "Must be higher than 1"
continue
elif inp > 10.000.000:
print "Must be less than 10.000.000"
continue
elif 'inp is a string': #here's my problem
print "Must be an integer value!"
continue
else:
'execute the rest of the code'
I don't know how to solve this. My program always terminates when I enter a string by mistake.
Thank you!
First, you're using Python 2, which will happily compare strings to integers. You don't want to do that. Secondly, raw_input() will always return a string. What you're hoping to do is check if that string could possibly represent a number. Third, 10.000.000 is improper syntax. Don't use separators. Fourth, you only need to continue if you want to go to the top of the loop early. If everything's in an if..elif..else block at the end of the loop, only one of those will be executed, so you don't need to put a continue at the end of each branch. You can use continue statements or restructure your branch. Finally, don't use in as a variable name, because that's a Python keyword.
while True:
inp = raw_input("Enter a value between 1 and 10 million: ")
if not inp.isdigit():
print "Must be an integer value!"
continue # each of these continue statements acts like a "failed, try again"
inp = int(inp)
if inp < 1:
print "Must be higher than 1"
continue # same for this one
if inp > 10000000:
print "Must be less than 10.000.000"
continue # and this one
# execute the rest of the code
You can use .isdigit() to check if string consists of numbers to make sure it can be convertible to integer:
while True:
in = raw_input("Enter a value between 1 and 10 million: ")
if in.isdigit():
number = int(in)
if number < 1:
print "Must be higher than 1"
continue
elif number > 10**6:
print "Must be less than 10.000.000"
continue
else:
'execute the rest of the code'
else:
print "Must be an integer value!"
continue
I have no idea how you came up with your code but here are different suggestions:
Don't use "in" as variable name because it's a python operator.
After the input you can check whether it is an int or a string.
Your program can look like this:
while True:
try:
input_int = int(raw_input("Enter a value between 1 and 10 million: "))
if input_int < 1 :
print "Must be higher than 1"
elif input_int > 10**7:
print "Must be less than 10.000.000"
except:
print "Must be an integer value!"
else: #You can use else with try/except block
#'execute the rest of the code'
VoilĂ 

Python how to only accept numbers as a input

mark= eval(raw_input("What is your mark?"))
try:
int(mark)
except ValueError:
try:
float(mark)
except ValueError:
print "This is not a number"
So I need to make a python program that looks at your mark and gives you varying responses depending on what it is.
However I also need to add a way to stop random text which isn't numbers from being entered into the program.
I thought I had found a solution to this but it won't make it it past the first statement to the failsafe code that is meant to catch it if it was anything but numbers.
So pretty much what happens is if I enter hello instead of a number it fails at the first line and gives me back an error that says exceptions:NameError: name 'happy' is not defined.
How can I change it so that it can make it to the code that gives them the print statement that they need to enter a number?
remove eval and your code is correct:
mark = raw_input("What is your mark?")
try:
int(mark)
except ValueError:
try:
float(mark)
except ValueError:
print("This is not a number")
Just checking for a float will work fine:
try:
float(mark)
except ValueError:
print("This is not a number")
Is it easier to declare a global value than to pass an argument,
In my case it's also gives an error.
def getInput():
global value
value = input()
while not value.isnumeric():
print("enter a number")
value = input("enter again")
return int(value)
getInput()
print(value)
#can't comment :)
You can simply cae to float or int and catch the exception (if any). Youre using eval which is considered poor and you add a lot of redundant statements.
try:
mark= float(raw_input("What is your mark?"))
except ValueError:
print "This is not a number"
"Why not use eval?" you ask, well... Try this input from the user: [1 for i in range (100000000)]
you can use the String object method called isnumeric. it's more efficient than try- except method. see the below code.
def getInput(prompt):
value = input(prompt)
while not value.isnumeric():
print("enter a number")
value = input("enter again")
return int(value)
import re
pattern = re.compile("^[0-9][0-9]\*\\.?[0-9]*")
status = re.search(pattern, raw_input("Enter the Mark : "))
if not status:
print "Invalid Input"
Might be a bit too late but to do this you can do this:
from os import system
from time import sleep
while True:
try:
numb = float(input("Enter number>>>"))
break
except ValueError:
system("cls")
print("Error! Numbers only!")
sleep(1)
system("cls")
but to make it within a number range you can do this:
from os import system
from time import sleep
while True:
try:
numb = float(input("Enter number within 1-5>>>"))
if numb > 5 or numb < 1:
raise ValueError
else:
break
except ValueError:
system("cls")
print("Error! Numbers only!")
sleep(1)
system("cls")
Actually if you going to use eval() you have to define more things.
acceptables=[1,2,3,4,5,6,7,8,9,0,"+","*","/","-"]
try:
mark= eval(int(raw_input("What is your mark?")))
except ValueError:
print ("It's not a number!")
if mark not in acceptables:
print ("You cant do anything but arithmetical operations!")
It's a basically control mechanism for eval().

Flowchart in Python

I need to write a prog in Python that accomplishes the following:
Prompt for and accept the input of a number, either positive or negative.
Using a single alternative "decision" structure print a message only if the number is positive.
It's extremely simply, but I'm new to Python so I have trouble with even the most simple things. The program asks for a user to input a number. If the number is positive it will display a message. If the number is negative it will display nothing.
num = raw_input ("Please enter a number.")
if num >= 0 print "The number you entered is " + num
else:
return num
I'm using Wing IDE
I get the error "if num >= 0 print "The number you entered is " + num"
How do I return to start if the number entered is negative?
What am I doing wrong?
Try this:
def getNumFromUser():
num = input("Please enter a number: ")
if num >= 0:
print "The number you entered is " + str(num)
else:
getNumFromUser()
getNumFromUser()
The reason you received an error is because you omitted a colon after the condition of your if-statement. To be able to return to the start of the process if the number if negative, I put the code inside a function which calls itself if the if condition is not satisfied. You could also easily use a while loop.
while True:
num = input("Please enter a number: ")
if num >= 0:
print "The number you entered is " + str(num)
break
Try this:
inputnum = raw_input ("Please enter a number.")
num = int(inputnum)
if num >= 0:
print("The number you entered is " + str(num))
you don't need the else part just because the code is not inside a method/function.
I agree with the other comment - as a beginner you may want to change your IDE to one that will be of more help to you (especially with such easy to fix syntax related errors)
(I was pretty sure, that print should be on a new line and intended, but... I was wrong.)

Getting an Integer Input in a Range

I'm trying to take a raw input and detect whether it is in a range.
Here's my code.
def gold_room():
print "This room is full of gold. How much do you take?"
next = raw_input("> ")
if next == int in range(50):
how_much = int(next)
else:
dead("Man, learn how to type a number.")
if how_much < 50:
print "Nice, you're not greedy, you win!"
exit(0)
else:
dead("You greedy bastard!")
When I enter a number it gives me the else: "Man, learn how to type a number."
I guess the line that isn't working is "if next == int in range(50):
Could anyone help me out?
Thanks in advance!
Edit:
I'm a noob so that line was just me ballparking.
I thought it would check next to see if it was an integer in the range of numbers 0-50.
If you want to "get an integer input in a range", you'll need two things:
Check if the input is an int
Check if it's in your range
Check if the input is an int
try/except will be perfect here:
n = raw_input('> ')
try:
n = int(n)
except ValueError:
dead() # or what you want
Why this is good?
Because if n is an int you'll have it convert it to an integer and if it's not an exception get raised and you can call your dead() funcion.
Check if it's in your range
If you get to this point it means that the exception before it was not raised and n was converted to an integer.
So you just need to do:
if 0 <= n <= 50:
print 'You win'
else:
print 'You lose'
Don't do:
if n in range(50):
# ...
Beacuse it will build a list of 50 numbers for nothing.
Note: don't use next as a variable, beacuse it'll shadow the built-in next()
Since raw_input returns a string, you need to convert to an int first. Try replacing the line with this:
if int(next) in range(50):
The result of raw_input() will be a string, so first you need to check to see if next is all digits. There are a few ways to do this, the easiest is to use the str.isdigit() function:
next = raw_input("> ")
if next.isdigit():
how_much = int(next)
else:
dead("Man, learn how to type a number.")
Note that you do not need to check to see if the value for next is in the range from 0 to 50, since your next if statement already checks to see if the value is less than 50 and negative numbers will be excluded by next.isdigit().
The test "next == int in range(50)" evaluates to "(next == int) and (int in range(50))" which is fairly meaningless and always equates to false.
Instead you could try
try:
how_much = int(next)
if not (0<=how_much<50):
print 'Too greedy'
except ValueError:
dead("Man, learn how to type a number.")
Using try .. except will allow you to make sure entered value is an int. # raise is a place holder for your handling a non-int contition:
try:
next = int(raw_input("> "))
except ValueError:
# raise
if not 0 <= next <= 50:
print 'Too greedy'

Categories