[Tutor] cases with single if and an else clause

Dennis Lee Bieber wlfraed at ix.netcom.com
Tue Oct 5 14:39:17 EDT 2021


On Tue, 5 Oct 2021 07:22:24 +0530, Manprit Singh
<manpritsinghece at gmail.com> declaimed the following:

>Dear sir,
>
>Now there is one more problem ,  Kindly loom at below written functions :
>
>def grade(percent):
>    if percent < 0 or percent > 100:
>        ans = "Invalid Input"
>    elif percent >= 90:
>        ans = "A"
>    elif percent >= 70:
>        ans = "B"
>    elif percent >= 60:
>        ans = "C"
>    else:
>        ans =  "Fail"
>    return ans
>

	My biggest concern is that you are using the same "ans" return to
indicate invalid input, letter grades (you have a big gap between A and B
-- at least in US you'd commonly have breakpoints A:90, B:80, C:70, D:60,
and E (or F) at 50). 

	Presuming the numeric grade is being entered by the user of some
program (say a teacher's electronic grade book) the input should have been
validated at the place it was entered, NOT in a function that just
translates number ranges into a letter grade.

	If you really need to validate /in/ this function, you should be
raising an exception... and the caller needs to catch this exception and do
whatever is needed to correct the data before retrying the operation. As
is, the caller is forced to test every return from the function for a
SPECIFIC string...

aGrade = grade(score)
if aGrade == "Invalid Input":
	#do something to correct the input and retry the call to grade()
else:
	#record the returned letter grade



	There are multiple ways to avoid a chain of if/elif/else comparisons...
But for that you need to study /data structures/ and the algorithms using
them rather than just playing around with simple examples that would seldom
be used in actual applications. Especially examples that are mostly
concerned with /coding style/ than on flexibility (algorithm reuse). If the
code runs, it is technically correct -- but may look ugly and locked in to
just the one application. Coding style, these days, tends to be defined by
the company one works at, and one has to follow some guide book that
already exists at that company. If you want to follow the One-In/One-Out of
Structured Programming -- try to lay out your code using
https://en.wikipedia.org/wiki/Nassi%E2%80%93Shneiderman_diagram
(even in OOP, once one gets down to coding class methods, one should be
back to structured programming)

-=-=-=-
C:\Users\Wulfraed\Documents\_Hg-Repositories\Python Progs>letterGrade.py
Enter percentage grade for Abigail: -5
Invalid numeric grade
Please try again
Enter percentage grade for Abigail: 45

Letter grade for Abigail is F


Enter percentage grade for Bertram: 110
Invalid numeric grade
Please try again
Enter percentage grade for Bertram: 99

Letter grade for Bertram is A


Enter percentage grade for Charlie: xyz
invalid literal for int() with base 10: 'xyz'
Please try again
Enter percentage grade for Charlie: 68.5
invalid literal for int() with base 10: '68.5'
Please try again
Enter percentage grade for Charlie: 68

Letter grade for Charlie is D


Enter percentage grade for Edith: 77

Letter grade for Edith is C


Enter percentage grade for Francisca: 81

Letter grade for Francisca is B



C:\Users\Wulfraed\Documents\_Hg-Repositories\Python Progs>
-=-=-=-
STUDENTS = [    "Abigail",
                "Bertram",
                "Charlie",
                "Edith",
                "Francisca" ]

GRADES = [ (60, "F"),
           (70, "D"),
           (80, "C"),
           (90, "B"),
           (100, "A") ]	#ordered list of break points

def grade(percent):
    if percent < 0 or percent > 100:
        raise ValueError("Invalid numeric grade")
    for pc, ltr in GRADES:
        if percent <= pc: return ltr

for st in STUDENTS:
    while True:
        try:
            pcent = input("Enter percentage grade for %s: " % st)
            pcent = int(pcent)
            ltrGrade = grade(pcent)
            print("\nLetter grade for %s is %s\n\n"
                  % (st, ltrGrade))
            break
        except ValueError as ve:
            print(str(ve))
            print("Please try again")
    
-=-=-=-

	For the example, I've left GRADES as a read-only "global". For reuse
purposes, it should be passed as an argument to the grade() function.

	This is easily modifiable for use when grading "by the curve".
Simplified version: "C" is the mean of the scores, and one then works
outwards; all that needs to be changed is the GRADES list; so if the mean
came in at 60 then GRADES would look like:

GRADES = [ (45, "F"),
           (55, "D"),
           (65, "C"),		#allow 5 below to 5 above
           (75, "B"),
           (100, "A") ]	#don't change to catch outliers

If you input the scores per student first, you can have the program
calculate the mean and modify GRADES as needed.. Granted, this simplified
version will have problems if the scores are near the extremes... mean of
85 makes GRADES look like

GRADES = [ (70, "F"),
           (80, "D"),
           (90, "C"),		#allow 5 below to 5 above
           (100, "B"),
           (100, "A") ]	#no one gets a "A"

The more complex version would compute %iles using mean&std.dev. and use
those to set the break points for letter grades.


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/



More information about the Tutor mailing list