-1

I ran the following code as a practice purpose from one of the Python book and I want the output as shown in the URL provided below. So, when I am running the first activity in the question (from book - shown in the photo) to verify if he has done it correctly, it's working but when he ran the second activity, it's not working properly. Ideally, I should get except statement printed if I am entering any string in the first user prompted input but I am being asked for the second user prompted input i.e., rate. Why is that so? And also please tell if it is advisable to put complete code in try portion or ideally we should only put the portion in a try statement for which we are sure that it wouldn't work out and it would jump to except block?

When I enter forty, I am not given the error message which is in the book which means that there can be some changes made in the code. However, it is working fine when I am including all lines of codes under try instead of just 2 lines which are currently there i.e., (fh = float(sh) and fr = float(sr)). How can I correct my existing written code by just writing two statements in a try portion?

Your help would be appreciated.

Issue: Enter Hours: fortyError, please enter numeric input

Image of the required output is below: enter image description here

Following is the code:

sh = input("Enter hours:")
sr = input("Enter Rate:")
try:
    fh = float(sh)
    fr = float(sr)
except:
    print('Error, please enter numeric input')
    quit()
print(fh, fr)
if fh > 40:
    reg = fr  * fh
    otp = (fh - 40.0) * (fr * 0.5)
    xp = reg + otp
else:
    xp = fh * fr
print("Pay:",xp)
Maurice Meyer
  • 17,279
  • 4
  • 30
  • 47
  • Does this answer your question? [Asking the user for input until they give a valid response](https://stackoverflow.com/questions/23294658/asking-the-user-for-input-until-they-give-a-valid-response) – Tomerikoo May 30 '20 at 17:40

6 Answers6

1

Ideally, you put as less code as possible into a try-block and try to not repeat code, this makes it easier to debug/find errors in programs.
A more pythonic version of the 'questioning' would look like this:

# define a dictionary to save the user input
userInput = {
    'hours': None,
    'rate': None
}

# The input lines are identical so you can just 'exchange' the question.
# Dynamically ask for user input and quit immedialy in case of non-float
for question in userInput.keys():
    try:
        userInput[question] = float(input(f"Enter {question}:"))
    except:
        print('Error, please enter numeric input')
        quit()

# continue with the original code
fh, fr = userInput['hours'], userInput['rate']
if fh > 40:
    reg = fr  * fh
    otp = (fh - 40.0) * (fr * 0.5)
    xp = reg + otp
else:
    xp = fh * fr
print("Pay:", xp)
Maurice Meyer
  • 17,279
  • 4
  • 30
  • 47
  • Thank you so much. How is Krishna Srinidhi's code below? What's your take-on on that? It's easy to follow. What do you say? – Fiona Daniel May 30 '20 at 09:20
  • You might want to have a look at the [DRY-Principle](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself). Let's assume there are 25 more questions asked and you would need to change the error message in the future, there would me many lines that need to be changed. – Maurice Meyer May 30 '20 at 09:43
  • Thanks. I have tick marked and I have a question. How can you do this in a function? Like def function? – Fiona Daniel May 31 '20 at 19:48
  • @Fiona Daniel: In case your try/except issue was resolved you should close this question by accepting an answer. For further question ask a new one on SO - asking and answering in comments is quit difficult. But yes `def ...()`is the right way to start with function and probably reading some tutorials about it – Maurice Meyer May 31 '20 at 19:55
  • Yeah, it's difficult in comments. You can edit it in your existing answer, that way, it would be easy. – Fiona Daniel May 31 '20 at 20:04
1

I think the easiest way is this:

while True:  #open a while loop
        try:  #ask your questions here
            sh = input("Enter hours:")
            fh = float(sh)
            sr = input("Enter Rate:")
            fr = float(sr)
        except ValueError:  #if a string is in input instead of a float do this
            print("input is not numeric")
        else:  # if user did all right do this and end the while loop
            print(fh, fr)
            if fh > 40:
                reg = fr  * fh
                otp = (fh - 40.0) * (fr * 0.5)
                xp = reg + otp
            else:
                xp = fh * fr
            print("Pay:",xp)
            break

edit:

def check_for_float(question):
    #define a function to check if it's float
    while True:
        #open a while loop
            try:
                #ask your questions here
                value = float(input(question))
                #return value
                return value
            except ValueError:
                #if a string is in input instead of a float give second chance
                print("input is not numeric, try again:")




#execute function and give argument question
#returned value will be your variable
fr = check_for_float("Enter Rate:")           
fh = check_for_float("Enter hours:")

#do your stuff with the returned variables
print(fh, fr)
if fh > 40:
    reg = fr  * fh
    otp = (fh - 40.0) * (fr * 0.5)
    xp = reg + otp
else:
    xp = fh * fr
print("Pay:",xp)

all in one:

def calculate_userinput ():
    ## function in function
    #this means the function check_for_float isn't available outside of calculate
    def check_for_float(question):
        #define a function to check if it's float
        while True:
            #open a while loop
                try:
                    #ask your questions here
                    value = float(input(question))
                    #return value
                    return value
                except ValueError:
                    #if a string is in input instead of a float give second chance
                    print("input is not numeric, try again:")
    #execute function and give argument question
    #returned value will be your variable
    fr = check_for_float("Enter Rate:")           
    fh = check_for_float("Enter hours:")
    #do your stuff with the returned values
    print(fh, fr)
    if fh > 40:
        reg = fr  * fh
        otp = (fh - 40.0) * (fr * 0.5)
        xp = reg + otp
    else:
        xp = fh * fr
    print("Pay:",xp)

calculate_userinput()

functions for diffrent stuff to use

def check_for_float(question):
    #define a function to check if it's float
    while True:
        #open a while loop
            try:
                #ask your questions here
                value = float(input(question))
                #return value
                return value
            except ValueError:
                #if a string is in input instead of a float give second chance
                print("input is not numeric, try again:")

def calculate():
    fr = check_for_float("Enter Rate:")           
    fh = check_for_float("Enter hours:")
    print(fh, fr)
    if fh > 40:
        reg = fr  * fh
        otp = (fh - 40.0) * (fr * 0.5)
        xp = reg + otp
    else:
        xp = fh * fr
    print("Pay:",xp)
calculate()

programming is like engineering, first you need to know what you want to create then how you get there in the best way. Wich structure you want, are there subsystems what they need to do or to watch et cetera.

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
Thingamabobs
  • 7,274
  • 5
  • 21
  • 54
  • Thanks but when I enter float for hours and after that it ask me the input for rate and if I put any string here in rate then it goes back again to rate and ask me for hours input - why so? What change can be made so that if I enter float in hours I shouldn't be prompted again for entering float again for hours provided that I am entering string for rate. How can you address this in your code? Did you understand what I am trying to say? Please let me know and we can discuss further. – Fiona Daniel May 31 '20 at 19:40
  • Thanks but how can I write complete code in a function like if I don't want to move these conditions (i.e., if fh > 40) out of my def function? Then how can you approach the solution/code? – Fiona Daniel Jun 01 '20 at 09:58
  • make a function again and put all the code in it. At the end of the code you need to call it with func_name() – Thingamabobs Jun 01 '20 at 10:08
  • there are several ways to do so. If you want check_for_float as a local function you put it in your new defined, if you also want to use it elsewhere then you put the check_for_float out of your new defined and just put the rest of the code in a function and call it with func_name(). It depends on what you want to do with it. Ask yourself wich way will be the shortes and cleanest to reach the goal. – Thingamabobs Jun 01 '20 at 10:13
  • BTW: it would be nice to upvote my answer if you like it and if it solves your question in the way you like the most then please accept it. ^^ – Thingamabobs Jun 01 '20 at 10:16
  • Can you kindly edit it again third time in that code if you have time please? I have up-voted it! – Fiona Daniel Jun 01 '20 at 15:19
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/215114/discussion-between-atlas435-and-fiona-daniel). – Thingamabobs Jun 01 '20 at 15:48
0

Updated ans :

import sys
sh = input("Enter hours:")
try:
    fh = float(sh)
except:
    print(f"{sh} is not numeric")
    sys.exit(0)
sr = input("Enter Rate:")
try:
    fr = float(sr)
except:
    print(f"{sr} is not numeric")
    sys.exit(0)

jupyter output

Krishna Srinidhi
  • 370
  • 1
  • 4
  • 12
  • What is f"{ ? Can you further optimize this code? Or is there anything else can be done if you can think of? – Fiona Daniel May 30 '20 at 09:09
  • f"{ is f-string formating, its one of the faster string formating. – Krishna Srinidhi May 30 '20 at 09:20
  • It ( f"{ ) gave me an error in one of the online Python IDE. And your program is still asking me the rate even though my first input is string in hours. It should have stopped if I am entering string in the very first user prompted input. But its still asking me enter rate? Why so? – Fiona Daniel May 30 '20 at 09:34
  • When I tried it did not ask for the rate . f-string is supported only from python3.6+ , which version are you using. – Krishna Srinidhi May 30 '20 at 09:39
  • I am using Jupyter Notebook and it is still giving me an error. Can you run this in Jupyter Notebook and show me the output? And also where are you running it? Which IDE? – Fiona Daniel May 30 '20 at 12:05
  • I was running it locally in my terminal. I thought you were running it locally or so . This doesn't work with jupyter notebooks . In that case you should force exit using sys.exit(0). Just asking why are running this in jupyter notebook . It would be better to run these scripts locally. – Krishna Srinidhi May 30 '20 at 14:17
  • I am new to programming but I am curious about output as how it can be different in different platforms? Because language is the same! What's your take on? You are running it on the command line terminal? And what's the alternate solution then? – Fiona Daniel May 30 '20 at 18:25
  • It is usually not different and I'm not sure why it's like that in jupyter notebook , maybe the way it is rendered in jupyter notebook is why I think. – Krishna Srinidhi May 30 '20 at 20:10
  • On some digging on the issue I found a question in stackoverflow itself. https://stackoverflow.com/questions/53676034/what-does-exit-keyword-do-in-python3-with-jupyter-notebook . just using exit ( without paranthesis) solves it. – Krishna Srinidhi May 30 '20 at 20:18
  • I have tried this code in pycharm, it's working. Can you please send me your earlier code i.e., the code which you wrote initially before you wrote this new updated code. And I am putting a right tick on your solution too. Please send me that earlier code here in the comment section or email me at my email address i.e., fiona.daniel01@gmail.com – Fiona Daniel May 30 '20 at 21:08
  • the only difference was that instead of sys.exit(0) it was quit(). – Krishna Srinidhi May 31 '20 at 09:19
  • Alright what's the difference between this "sys.exit(0)" and "quit()" ? Why have you used both at both places? What was the motto? And did you get any significant result change by using these? – Fiona Daniel May 31 '20 at 19:19
  • I don't know the real differences between them, there are other ways to exit the code too, but sys.exit(0) is considered standard exiting way. If you observed in the notebook sys.exit forced the kernel cell to stop and printed some dirty output, hence the reason for me to use it since quit() did not work in the notebook. Sometimes you just have to try different things to get the correct answer, and correct answer doesn;t always mean it's the right way to do it . – Krishna Srinidhi May 31 '20 at 19:33
  • Thanks. I have tick marked and I have a question. How can you do this in a function? Like def function? – Fiona Daniel May 31 '20 at 19:46
  • Inside the function , it would be same, I don't get what you mean . You define a define a function and inside the definition have this piece of code and call it main() or just directly call it. – Krishna Srinidhi Jun 02 '20 at 07:29
0

You have to put the check if the entered input is a number after every input statement.

try:
    sh = input("Enter hours:")
    fh = float(sh)
    sr = input("Enter Rate:")
    fr = float(sr)
except:
    print('Error, please enter numeric input')

In your example you are getting both inputs and then check both of them. And to your question, I personally would prefer to only put the code that probabla produces errors in the try-statement, like you did.

jonas37
  • 63
  • 7
0

The problem with your code is that you are first taking both the variables sh and sr as input. So, even if you don't enter a numeric value it won't throw an error because the variables sh and sr don't care if it is a numeric value or not. After getting both the values the try block is executed.

So, if you want to receive an error message as soon as the user enters any alphabetic input, follow the below modified code. You can comment any doubts. Also, Tick the answer if it is correct.

try:
    fh = float(input('Enter hours:'))
    fr = float(input('Enter Rate:'))
except:
    print('Error, please enter numeric input')
    quit()
print(fh, fr)
if fh > 40:
    reg = fr  * fh
    otp = (fh - 40.0) * (fr * 0.5)
    xp = reg + otp
else:
    xp = fh * fr
print("Pay:",xp)

The output for the test case forty is

Enter hours:Forty
Error, please enter numeric input
anantdark
  • 387
  • 1
  • 2
  • 12
  • Is this code working on your side perfectly? I am sorry but I am getting the following error: NameError: name 'fh' is not defined – Fiona Daniel May 30 '20 at 09:49
  • Yes, it is working fine on my Pycharm. Also, it is clearly visible that i have defined both the variables `fh` and `fr` under the try block. Kindly try to run the code again. I think there is indentation problem in your code. – anantdark May 30 '20 at 09:53
  • Also, as a general rule, try to name variables that convey some meaning. This makes a code better presentable and helps in case you are debugging a long script. – anantdark May 30 '20 at 09:56
  • Kindly tick the correct answer so that it can be marked as 'answered' or you can ask any doubts you still have. – anantdark May 30 '20 at 14:05
  • I have tick marked and I have a question. How can you do this in a function? Like def function? – Fiona Daniel May 31 '20 at 19:46
  • You haven't ticked it, there is a tick mark below the upvote button, kindly click it so that this question can be marked as answered. – anantdark Jun 05 '20 at 07:35
-2

This python programme is not able to convert string to number so it is throwing a error. So yoy should use numeric in place string

  • The question is exactly about handling the situation where a user inputs a string which is not numeric, so I don't think this answer is very helpful... – Tomerikoo Jun 03 '20 at 07:21