[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