I'm new to python, taking my first class in it right now, only about 4 weeks in.
The assignment is to calculate test average and display the grade for each test inputted.
Part of the assignment is to use a function to calculate the average as well as deciding what letter grade to be assigned to each score.
As I understand it, functions are supposed to help cut down global variables.
My question is this: how do I condense this code?
I don't know how to use a function for deciding letter grade and then displaying that without creating a global variable for each grade that has been inputted.
If you notice any redundancy in my code, I would appreciate a heads up and a little lesson on how to cut that out. I can already smell the mark downs I will get if I turn this in as is...
def main():
grade1=float(input( "Enter score (0-100):"))
while (grade1 <0 or grade1 >100 ):
if grade1 <0 or grade1 >100:
print("Please enter a valid grade")
grade1=float(input( "Enter score (0-100):"))
grade2=float(input( "Enter score (0-100):"))
while (grade2 <0 or grade2 >100 ):
if grade2 <0 or grade2 >100:
print("Please enter a valid grade")
grade2=float(input( "Enter score (0-100):"))
grade3=float(input( "Enter score (0-100):"))
while (grade3 <0 or grade3 >100 ):
if grade3 <0 or grade3 >100:
print("Please enter a valid grade")
grade3=float(input( "Enter score (0-100):"))
grade4=float(input( "Enter score (0-100):"))
while (grade4 <0 or grade4 >100 ):
if grade4 <0 or grade4 >100:
print("Please enter a valid grade")
grade4=float(input( "Enter score (0-100):"))
grade5=float(input( "Enter score (0-100):"))
while (grade5 <0 or grade5 >100 ):
if grade5 <0 or grade5 >100:
print("Please enter a valid grade")
grade5=float(input( "Enter score (0-100):"))
total=grade1+grade2+grade3+grade4+grade5
testAverage=calcAverage(total)
eachGrade1=determineGrade(grade1)
eachGrade2=determineGrade(grade2)
eachGrade3=determineGrade(grade3)
eachGrade4=determineGrade(grade4)
eachGrade5=determineGrade(grade5)
print("\nTest #1 grade:", (eachGrade1))
print("Test #2 grade:", (eachGrade2))
print("Test #3 grade:", (eachGrade3))
print("Test #4 grade:", (eachGrade4))
print("Test #5 grade:", (eachGrade5))
print("\nTest average:", (testAverage),("%"))
def calcAverage(total):
average=total/5
return average
def determineGrade(grade):
if grade >=90:
return "A"
elif grade >=80:
return "B"
elif grade >=70:
return "C"
elif grade >=60:
return "D"
else:
return "F"
-
Rule #1 of coding, NEVER copy and paste. Whenever you copy and paste that's really a function.Kurt– Kurt2016年05月03日 05:24:25 +00:00Commented May 3, 2016 at 5:24
-
I'm afraid I don't follow, what are you referring to?Zachary McCauley– Zachary McCauley2016年05月03日 05:26:31 +00:00Commented May 3, 2016 at 5:26
-
You might want to carefully review the course materials regarding this assignment. It probably discusses topics like functions, return values, and lists.TigerhawkT3– TigerhawkT32016年05月03日 05:28:50 +00:00Commented May 3, 2016 at 5:28
-
2You have 5 identical code blocks with the only difference being the variable gradeX. Did you copy and paste that code and then change the variable name? I suspect you did. Instead of doing that, make a function. Granted that is sort of your question but nobody here is interested in doing your homework for you.Kurt– Kurt2016年05月03日 05:29:17 +00:00Commented May 3, 2016 at 5:29
-
@kurt that is certainly not the intent of this post. Being only weeks into my first ever coding class, there are concepts that are elusive to me and that I feel I cannot devise from the book and simply am looking for help.Zachary McCauley– Zachary McCauley2016年05月03日 05:36:29 +00:00Commented May 3, 2016 at 5:36
2 Answers 2
I won't refactor your whole code, but here's a few pointers:
First of all, you need a function to get the user input, let's call it get_score. I won't go into the details here because there's an excellent resource on how to write a function for that here: Asking the user for input until they give a valid response. That function should return a float or integer, so don't forget that input (assuming you are using Python 3) returns a string which you have to cast to int or float manually.
To get a list of n scores, I propose the function:
def get_n_scores(n):
return [get_score() for _ in range(n)]
The stuff in the square brackets is a list comprehension and equivalent to:
scores = []
for _ in range(n):
scores.append(get_score())
Use this code instead if you are not comfortable with the comprehension (don't forget to return result).
The variable name _ is commonly used to indicate a temporary value that is not used (other than for iteration).
You can avoid declaring grade1 ... grade5 by calling all_scores = get_n_scores(5), which will return a list with the user input. Remember that indexing is zero-based, so you'll be able to access all_scores[0] ... all_scores[4].
Instead of hardcoding total, you can just apply the built in sum function: total = sum(all_scores), assuming all_scores holds integers or floats.
Finally, you can determine the grade for each score by applying your function determineGrade to every score in all_scores. Again, you can use a comprehension:
all_grades = [determineGrade(score) for score in all_scores]
or the traditional:
all_grades = []
for score in all_scores:
all_grades.append(determineGrade(score))
The other stuff looks okay, except that in order to print the grade you can just loop over all_grades and print the items. It's up to you if you want to write further functions that wrap a couple of the individual function calls we're making.
In general, always avoid repeating yourself, write a function instead.
3 Comments
average = sum(my_list) / len(my_list), you don't have to hard-code the length either.calcaverage should take two arguments (if you want a function for that at all). I missed that.I'll write is as below:
def get_grade():
while(True):
grade = float(input("Enter score (0-100):"))
if grade >= 0 and grade <= 100:
return grade
print("Please enter a valid grade!")
def get_average(sum_val, counter):
return sum_val/counter
def determine_grade(grade):
if grade >=90:
return "A"
elif grade >=80:
return "B"
elif grade >=70:
return "C"
elif grade >=60:
return "D"
else:
return "F"
test_num = 5
sum_val = 0
result = {}
for i in range(test_num):
grade = get_grade()
result[i] = determine_grade(grade)
sum_val += grade
for key in result:
print ("Test %d Grade is %s" % (key+1, result[key]))
avg = get_average(sum_val, test_num)
print ("Average is %d" % avg)
Works like this:
>>> ================================ RESTART ================================
>>>
Enter score (0-100):89
Enter score (0-100):34
Enter score (0-100):348
Please enter a valid grade!
Enter score (0-100):34
Enter score (0-100):90
Enter score (0-100):85
Test 1 Grade is B
Test 2 Grade is F
Test 3 Grade is F
Test 4 Grade is A
Test 5 Grade is B
Average is 66
>>>
5 Comments
for loop in Python, dictionary in Python and formatted print in Python. That's all you need for this program. Wish you success.float conversion inside getAverage(...) is superfluous. Also Python naming conventions are snake case (i.e. your function and variable names should look like get_average instead). Additionally, you can omit the counter variable because when you use it, its value is determined to be equal to Test_num.counter with Test_num : get_average(sum_val, counter)