3
\$\begingroup\$

Write a program to prompt for a score between 0.0 and 1.0. If the score is out of range, print an error. If the score is between 0.0 and 1.0, print a grade using the following table:

Score  | Grade
-------+------
>= 0.9 | A
>= 0.8 | B
>= 0.7 | C
>= 0.6 | D
 < 0.6 | F

If the user enters a value out of range, print a suitable error message and exit. For the test, enter a score of 0.85.

try:
    inp = raw_input("Enter a number between 0.0 and 1.0: ")
    score = float(inp)
    if (score >= 1.0):
        print("You didn't follow instructions")
        exit()
    elif (score >= 0.9):
        print("A")
    elif (score >= 0.8):
        print("B")
    elif (score >= 0.7):
        print("C")
    elif (score >= 0.6):
        print("D")
    else:
        print("F") 
except:
    print("Please enter numerical numbers")
    exit()
\$\endgroup\$
  • \$\begingroup\$ I tested on my end and executes fine, just needing you'll feedback. \$\endgroup\$ – Jerime McCastle Apr 26 '15 at 21:41
  • \$\begingroup\$ @JerimeMcCastle Are you looking for general feedback? \$\endgroup\$ – Martin Thoma Apr 27 '15 at 11:37
  • \$\begingroup\$ yes, just general feedback \$\endgroup\$ – Jerime McCastle Apr 29 '15 at 15:42
12
\$\begingroup\$

Yes, your code is correct, although I would recommend adding comments, and following the style guidelines of PEP8. Here are a few tips I have.

  • You should specify what type of error you want to except. If you just type except:, other errors could go un-noticed.
  • Typing exit() really isn't needed here. The program will terminate either way.
  • You don't need to put parentheses around conditionals in if statements.
  • It seems also that you're using Python2, so no parentheses are needed for print.
  • You could make this into a function that returns the grade.

Here's my re-factored version of the code.

def return_grade(user_input):
    """
    Return the user's grade based on the following table.
    Score  | Grade
    -------+------
    >= 0.9 | A
    >= 0.8 | B
    >= 0.7 | C
    >= 0.6 | D
    < 0.6 | F
    """
    try:
        user_score = float(user_input)
        if user_score > 1.0:
            return "Please enter a number between 0.0 and 1.0"

        elif user_score >= 0.9:
            return "Grade: A"

        elif user_score >= 0.8:
            return "Grade: B"

        elif user_score >= 0.7:
            return "Grade: C"

        elif user_score >= 0.6:
            return "Grade: D"

        elif user_score < 0.6 and user_score >= 0.0:
            return "Grade F"
    except ValueError:
        print("Please enter a number.")


print return_grade(raw_input("Enter a number between 0.0 and 1.0"))
\$\endgroup\$
6
\$\begingroup\$

I should point out that your code does not conform to the specification in one specific way. An entry of negative values should fail to validate, but your code will happily assign it the grade F.

Additionally, I am uncertain about your top-of-range validation. You fail to validate the value 1.0 which I would expect to be graded as an A. The specification is slightly obscure about that, but, I would expect 100% to be possible.

Note, your 1-value test system of 0.85 is inadequate. You should read up on test strategies, especially on boundary conditions. Your tests should ensure the correct values for at least the following inputs:

0.0
0.1
-0.1
-0.0 (yes, that does exist)
NaN (yes, that does exist - your code gives that an `F`)
1.0
0.99999
1.00001
0.6
0.599999
0.60001
....
5e-10
95e-1 (correctly gives it an 'A')
-inf
+inf

then, also non-numbers:

foo

bar
....
\$\endgroup\$
0
\$\begingroup\$

Building off earlier suggestions, you could check the user input a little more at the first if statement.

if user_score<0.0 or user_score>1.0:
    return "Please enter a number between 0.0 and 1.0"
\$\endgroup\$
  • \$\begingroup\$ I suggest writing it as if not 0.0 <= user_score <= 1.0: …. \$\endgroup\$ – 200_success Apr 27 '15 at 4:49
  • \$\begingroup\$ @200_success: Does that work in Python? \$\endgroup\$ – Nova Apr 27 '15 at 6:02
  • 2
    \$\begingroup\$ @Nova It sure does! (See the first and third paragraphs) \$\endgroup\$ – Leigh Brenecki Apr 27 '15 at 7:18
0
\$\begingroup\$

The points so far are good. A few more:

  1. The only place you are going to encounter an exception is score = float(inp), so that should be the only part wrapped in a try...except block.
  2. Empty except: statements are considered very bad, you should check for a ValueError.

However, the biggest advice I can give is to use a bit of mathematics with a dict to get the results. If you multiply the score by 10, then convert it to an int (which gets you the floor), it will be an integer from 0 to 9, inclusive. Then you take the max of that and 5, which will handle the F case. Then you can set up a dict for the letter values:

def get_score_1():
    inp = input("Enter a number between 0.0 and 1.0: ")
    try:
        score = float(inp)
    except ValueError:
        return "Please enter numerical numbers"
    if score >= 1 or score < 0.:
        return "You didn't follow instructions"

    score = int(score*10)
    score = max(score, 5)

    scoredict = {9: 'A',
                 8: 'B',
                 7: 'C',
                 6: 'D',
                 5: 'F'}

    return scoredict[score]

Or a shorter version

def get_score_2():
    try:
        score = float(input("Enter a number between 0.0 and 1.0: "))
    except ValueError:
        return "Please enter numerical numbers"
    if score >= 1 or score < 0.:
        return "You didn't follow instructions"

    return {9: 'A', 8: 'B', 7: 'C', 6: 'D', 5: 'F'}[max(int(score*10), 5)]

Alternatively, you can use it as an index a str. This is shorter, and avoids the max issue, but I think it is less idiomatic personally:

def get_score_3():
    try:
        score = float(input("Enter a number between 0.0 and 1.0: "))
    except ValueError:
        return "Please enter numerical numbers"
    if score >= 1 or score < 0.:
        return "You didn't follow instructions"

    return 'FFFFFFDCBA'[int(score*10)]
\$\endgroup\$

protected by Jamal Apr 19 '18 at 3:18

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.