Averaging grade scores in python? - python

for some reason when I average the scores, it's not the right answer i.e usually something like 2 percent or 540, even if that's not what the arithmetic answer would be. Sometimes it works, sometimes it doesn't! As well, code runs in VS, but displays syntax error in IDLE. I have no idea if they're related, but in any case, I have no idea how to fix it. Any help is appreciated!
number=1
quiz=1
mini=1
peer=1
sum=0
while number <51:
assignment = int(input("What's your grade for assignment "+ str(number) + "?"))
number = number + 1
sum += assignment
assigns = (sum // 500)*100
assigns2 = round(assigns, 2)
while peer <4:
peers = int(input("What is your grade for peer assignment "+ str(peer) + "?"))
peer = peer + 1
sum += peers
while quiz <11:
quizzes = int(input("What's your grade for quiz "+ str(quiz) + "?"))
quiz = quiz + 1
sum += quizzes
quiznos = (sum // 100)*100
quiznos2 = round(quiznos, 2)
while mini <11:
minisss = int(input("What is your grade for mini-project "+ str(mini) + "?"))
mini = mini + 1
sum += minisss
miniz = (sum // 200)*100
miniz2 = round(miniz, 2)
final = int(input("What was your score on the final? "))
print("CALCULATING YOUR GRADE...")
gradez = (sum/1200)*100
grader = round(gradez, 2)
print("*******")
print("The total possible points was 1100, and your total is",sum,"points! Your grade is", grader, "percent!")
print("*******")
if grader >= 90:
print("You've gotten an A!")
elif grader >= 80:
print("You've gotten a B!")
elif grader >= 70:
print("You've gotten a C!")
elif grader >= 60:
print("That's a D, sorry man!")
elif grader >= 0:
print("You've failed the class...")
print("*******")
print("You got a", assigns2, "percent for assignments!")
print("*******")
print("You got a", quiznos2, "percent for quizzes!")
print("*******")
print("You got a", miniz2, "percent for mini projects!")
print("*******")
examity = (final / 300)*100
examity2 = round(examity, 2)
print("Your final was", final, "out of 300, for a grade of", examity2, end="!")

For calculating the percent score for assignments, quizzes, and mini-projects, you are using the same sum variable. This means that your test scores are still added into the sum variable when you are calculating the quiz score, and the quiz and test scores are added into the sum when calculating the mini-projects score, leading to inflated scores. In short, you are using the sum variable in two conflicting ways - both to count up the total number of points and to store the separate sum values for each specific section. If I were you, I would create a separate total points variable and possibly separate sum variables with different names for each section (or reset the sum variable to 0 for each section). Also, I think you may be missing the final score in your total sum when you calculate the student's overall grade, and when calculating that total grade, you divide by 1200 but you say the total max points is 1100, and I'm not really sure how the peer assignments work into the overall score.
For the syntax error, it could be because of the versions of Python you are running in your different environments. If so, it may have to do with the end parameter in your last print statement. This article could be useful: Python SyntaxError: invalid syntax end=''.

Related

What to do when main() function isn’t calling/executing the other functions?

I created a main() function and also 3 others and I am trying to get the other 3 to be executed into main()
I had it working then I messed it up at the very end, so I commented it out since it is not calling the 3 other functions.
# The program displays the letter grade and associated message for each exam score
# and the average exam score
# The program will not contain any repeated code and have a minimum of two functions besides Main.
def main():
# ask user to enter test scores
score = int(input("Enter your test scores separate by spaces, no commas: "))
# display test score
def showLetters(num, letterGrade):
print(f"{num:.1f} is an {letterGrade}\n")
# display score message
def examScores(num):
if 90 <= num <= 100:
letterGrade = "A"
print("Excellent Work")
elif 80 <= num <= 89:
letterGrade = "B"
print("Nice job")
elif 70 <= num <= 79:
letterGrade = "C"
print("Not bad")
elif 60 <= num <= 69:
letterGrade = "D"
print("Room for improvement")
else:
letterGrade = "F"
print("Go back and review")
return letterGrade
# calculate average of all scores entered by user
def calcAverages(grades):
numbers = scores.split()
for i in range(len(numbers)):
numbers[i] = int(numbers[i])
print("Average exam score: ", sum(numbers) / len(numbers))
# ask user to repeat or quit
answer = str(input('Please enter "y" to run program again or "n" to exit: '))
if answer.lower() == 'n':
print('Thank you for using! Goodbye!')
sys.exit()
elif answer.lower() == 'y':
main()
# ??? = main()
# for n in ????? :
# showLetters(n, examScores(n, calcAverages(????)))
I made minor edits to your program and you now have the average values.
I have highlighted only the lines that need addition.
counter = 0 # tracks the number of times the function is called
#added the below 2 lines after counter
sumCredit = 0 #tracks the sum credit for all the students
sumStudyHrs = 0 #track the sum of the study hours for all the students
def myfunction():
global counter # tracks the number of times the function is called
#added two more global variables to keep track of the averages
global sumCredit #track the sum credit
global sumStudyHrs #track the sum study hours
the rest of the code can stay as is. Immediately after you print the student details, you need to accumulate the values so you can calculate the average.
print("Study hours: " + str(sumHours))
#added the below 2 lines after your print statements
sumCredit += classes
sumStudyHrs += sumHours
# Ask user if they want to end or restart
Now you need to use this information for your calculation.
When you print the average, use the above variables to compute the average.
print("Total Students: " + str(counter)) # tracks the number of times the function is called
#modified your average credits and average study with correct numerator
print("Average Credits: " + str(sumCredit / counter)) #computer average credits
print("Average Study Hours: " + str(sumStudyHrs / counter)) #compute average study hours
print('Thank you for using! Goodbye!')
This should give you the desired results.
Let me know if you need the full code.

Need to find an equation that will not allow user input to exceed 100 if user enters 90 for scoreEarned and 20 for scoreShift output will still be 100

I'm stuck on the elif statement I don't know how I would be able to have the input for example scoreEarned = 90 and scoreShift =20 which equals 110 just be a 100 as a max for the output. Like the max score that can be obtained is 100 but if the user got extra points over the 100, how could it still just return 100 as the maximum score?
#Message display description
print("This program reads exam/homework scores and reports your overall course grade.")
#Space
print()
#Title for Midterm 1
print("Midterm 1:")
#funtion that asks user for input to use
def totalPoint():
#Asking user for weight of assignment
weight = int(input("Weight (0-100)? "))
#Asking user for score earned on assignment, max score is 100
scoreEarned = int(input("Score earned? "))
#variable for bottom half of fraction
outOf = 100
#prompting user to input 1 for yes and 2 for no
yesOrNo = int(input("Were scores shifted (1=yes, 2=no)? "))
#if statement for if there is a score shift
if(yesOrNo == 1):
#prompt user for shift amount
scoreShift = int(input("Shift amount? "))
#if statement that will check user input
if(scoreShift > 0 and scoreShift + scoreEarned <= 100):
#add score earned and score shift
newTotalPoint = scoreEarned + scoreShift
#display new total points
print("Total points = ",newTotalPoint,"/",outOf)
#elif statement if the combined total of the score shift and earned are more than 100
elif(scoreShift > 0 and scoreShift + scoreEarned > 100):
#Need to have a maximum of 100 for total points including the shift
print("This is where I am stuck.")
#else there is no shift score
else:
#Print the score earned out of 100
print("Total points = ",scoreEarned,"/",outOf)
totalPoint()
Just put print(100).
Like this:
elif(scoreShift > 0 and scoreShift + scoreEarned > 100):
#Need to have a maximum of 100 for total points including the shift
print("Total points = 100")
Another more consise/pythonic way to accomplish this is to use the python built-in min() function as follows
scoreEarned = min(100, scoreEarned + scoreShift)
print("Total points = ",scoreEarned,"/",outOf)
min will return the smaller value of the two parameters passed to it. If scoreEarned + scoreShift is greater than your cap value of 100, min will return 100, otherwise it will return the original sum.
Just replace print("This is where I am stuck.") with the logical output at this stage that matters print("You exceeded the maximum score and will receive 100 points ")
This is what I deduced from your question. That's what you want to do, right?

Why is each grade inputted the same no matter what the program defines including the average?

The program is as follows: Write a program that asks the user to input 5 test scores. The program should display a letter grade for each score and the average test score.
I am having issues with my output showing me a letter grade of the first inputted grade for every grade including the average. My numeric average is also being outputted as a letter grade, but it gives the correct average letter for that rather than the correct numeric result for the grade. I am in a low level coding class, therefore the program must be written in this format.
Here is the code:
a=float(input("Enter score 1:"))
b=float(input("Enter score 2:"))
c=float(input("Enter score 3:"))
d=float(input("Enter score 4:"))
e=float(input("Enter score 5:"))
def determine_grade(a,b,c,d,e):
num=a
if(num<=100 and num>=90):
grade='A'
elif(num<=89 and num>=80):
grade='B'
elif(num<=79 and num>=70):
grade='C'
elif(num<=69 and num>=60):
grade='D'
else:
grade='F'
return grade
def calc_average(a,b,c,d,e):
mean=(a+b+c+d+e)//5
if mean<=100 and mean>=90:
avggrade='A'
elif(mean<=89 and mean>=80):
avggrade='B'
elif(mean<=79 and mean>=70):
avggrade='C'
elif(mean<=69 and mean>=60):
avggrade='D'
else:
avggrade='F'
return avggrade
grade=determine_grade(a,b,c,d,e)
avggrade=determine_grade(a,b,c,d,e)
mean=calc_average(a,b,c,d,e)
determine_grade(a,b,c,d,e)
calc_average(a,b,c,d,e)
print("Score Numeric Grade Letter Grade")
print("--------------------------------------------")
print("Score 1: ",a," ",grade)
print("Score 2: ",b," ",grade)
print("Score 3: ",c," ",grade)
print("Score 4: ",d," ",grade)
print("Score 5: ",e," ",grade)
print("--------------------------------------------")
print("Average Score: ",mean," ",avggrade)
Whenever I put in (a):
num=a,b,c,d,e
in place of what is shown in the code, I get a syntax error saying:
TypeError: '<=' not supported between instances of 'tuple' and 'int'
If I don't do what has been shown in (a), my output is this:
Enter score 1:90
Enter score 2:88
Enter score 3:76
Enter score 4:68
Enter score 5:40
Score Numeric Grade Letter Grade
--------------------------------------------
Score 1: 90.0 A
Score 2: 88.0 A
Score 3: 76.0 A
Score 4: 68.0 A
Score 5: 40.0 A
--------------------------------------------
Average Score: C A
Okay, so there's some things to talk about here. First, I suggest that you experiment a bit more with simpler functions to properly get used to them. When you define determine_grade(a,b,c,d,e) your function will expect to find a,b,c,d,e arguments inside the function, but if you read it again, you'll notice that you only mention a. This means when you call grade=determine_grade(a,b,c,d,e) you're only calculating a's grade, and that's why you have the same grade for everyone (if you type grade with your code you'll notice it will output 'A'.
Another way to write a function that does exactly what you're looking for is this:
def determine_grade(score):
num=score
if(num<=100 and num>=90):
grade='A'
elif(num<=89 and num>=80):
grade='B'
elif(num<=79 and num>=70):
grade='C'
elif(num<=69 and num>=60):
grade='D'
else:
grade='F'
return grade
You input a score (that can be a,b,c,d or e) and it calculates a grade. If you want to get everyone's grade, then you can do something like this:
grades=[]
for i in [a,b,c,d,e]:
grades.append(determine_grade(i))
This will bring a list with all grades.
Then, if you want the average grade, it's better to calculate the average score, so you can use your same function to get the grade:
mean_score=np.array([a,b,c]).mean()
mean_grade(determine_grade(mean_score)
Doing this you'll have all the information you need with way less lines of code (And you can make it even more efficient using list comprehensions, but that's a bit more advanced).
To answer your question, your functions should be rewritten to accept a single input and then called several times. Also, your program is a classic case of something that should be DRYed up (Don't Repeat Yourself). Instead of manually typing a = input(), b = input() why not consider just tossing all these inputs into a list (perhaps with some string formatting on your prompt like my code). Below is a program that can easily be adjusted to accept arbitrary amounts of inputs:
input_scores = [] # make our list
scores_input = 5 # tell the program we have 5 scores to record
for input_count in range(1, scores_input + 1):
input_scores.append(float(input("Enter score {}:".format(input_count))))
def determine_grade(percent): # single input
if 90 <= percent <= 100:
grade = 'A'
elif 80 <= percent <= 89:
grade = 'B'
elif 70 <= percent <= 79:
grade = 'C'
elif 60 <= percent <= 69:
grade = 'D'
else:
grade = 'F'
return grade # single output
def calc_average(local_score_list): # expects the list we made earlier (many inputs)
mean = sum(local_score_list) // len(local_score_list)
if 90 <= mean <= 100:
average_grade = 'A'
elif 80 <= mean <= 89:
average_grade = 'B'
elif 70 <= mean <= 79:
average_grade = 'C'
elif 60 <= mean <= 69:
average_grade = 'D'
else:
average_grade = 'F'
return mean, average_grade # have our function return both values, since it calculated them both anyways
compiled_scores = []
for test_score in input_scores:
letter_grade = determine_grade(test_score) # calling our single input/output function many times in a for loop
compiled_scores.append((test_score, letter_grade)) # creating a tuple so each letter and percent is stored together
mean_percent, mean_letter_grade = calc_average(input_scores) # decompile both values from our function
print("Score Numeric Grade Letter Grade")
print("--------------------------------------------")
# now we iterate through all the scores made and print them
for count, result_tuple in enumerate(compiled_scores, 1): # just print the scores in a loop
print("Score {}: ".format(count), result_tuple[0], " ", result_tuple[1])
print("--------------------------------------------")
print("Average Score: ", mean_percent, " ", mean_letter_grade)
You can see that we condensed our input() lines -> a single line, and condensed the print statements as well! Now our program can take, say, 30 scores and work just as well!!! (This is huge)!! And all that is required to change is the number 5 at the top of our script -> 30. No longer will we have to type print('this') or input('that')! Our script will automatically adjust because we made it able to scale with our list.
My test case (using same numbers from your post):
Enter score 1:90
Enter score 2:88
Enter score 3:76
Enter score 4:68
Enter score 5:40
Score Numeric Grade Letter Grade
--------------------------------------------
Score 1: 90.0 A
Score 2: 88.0 B
Score 3: 76.0 C
Score 4: 68.0 D
Score 5: 40.0 F
--------------------------------------------
Average Score: 72.4 C
Let me know if you need further clarification on something I posted!

beginner programmer here..easier ways to program this?

I am a beginner programmer and am self learning python programming at home from a book. I am currently learning about strings. There is a question there which i solved it but I was thinking if there are other easier ways to solve it.
Q. A certain professor gives 100-point exams that are graded on the scale 90-100:A, 80-89:B, 70-79:C, 60-69:D, <60:F. Write a program that accepts an exam score as input and prints out the corresponding grade.
def main():
## making a list from 0-100
num = list(range(0,101))
## asking for the exam points
points = int(input("Enter the exam points 0-100: "))
## iterating num 0-60
for i in num[0:60]:
if i == points:
print("Your corresponding grade is F.")
## iterating num 60-70
for i in num[60:70]:
if i == points:
print("Your corresponding grade is D.")
## iterating num 70-80
for i in num[70:80]:
if i == points:
print("Your corresponding grade is C.")
## iterating num 80-90
for i in num[80:90]:
if i == points:
print("Your corresponding grade is B.")
## iterating num 90-100
for i in num[90:101]:
if i == points:
print("Your corresponding grade is A.")
main()
Yes, there is a much better way of writing that.
Given that you have an int, which is the score, all you have to do is compare it to the boundaries that determine the grade (using < or >).
points = int(input("Enter the exam points 0-100: "))
if points < 60:
grade = 'F'
elif points < 70:
grade = 'D'
elif points < 80:
grade = 'C'
elif points < 90:
grade = 'B'
else:
grade = 'A'
print("Your corresponding grade is", grade)
To make your code clearer, you can put the comparison logic into a function that returns the grade for a given score.
def calculate_grade(score):
if score < 60:
return 'F'
if score < 70:
return 'D'
if score < 80:
return 'C'
if score < 90:
return 'B'
return 'A'
def main():
points = int(input("Enter the exam points 0-100: "))
grade = calculate_grade(points)
print("Your corresponding grade is", grade)
There's still an easier and more concise way to do this. Try this:
points = int(input("Enter the exam points 0-100: "))
if 0 < points <= 60:
print "Your grade is F"
elif 60 < points <= 70:
print "Your grade is E"
elif 70 < points <= 80:
print "Your grade is D"
[and so on...]
Benefits are:
Plain comparisons instead of heavy linear search
No need to define any kind of dictionaries, methods or even classes or the like (especially since you mentioned you're not that experienced in Python by now)
Exits when it has found the right grade and doesn't evaluate further needless ifs
It is correct (gives the expected grade) and terribly inefficient:
you create an array when it could be avoided
you use linear search in arrays where simple comparisons would be enough
In addition you use a pure linear (unstructured) design.
You could:
make a function that converts points to grade
call it from a main that deals with input and output
Code example
def points_to_grade(points):
limits = [90, 80, 70, 60]
grades = ['A', 'B', 'C', 'D']
for i,limit in enumerate(limits):
if points >= limit:
return grade[i]
return 'F'
def main():
## asking for the exam points
points = int(input("Enter the exam points 0-100: "))
## convert to grade
grade = points_to_grade(points)
print("Your corresponding grade is {}.".format(grade))
#Maybe using dictionaries is more fun :)
marks = {'F':60, 'D':70,'C':80,'B':90}
points = int(input("Enter the exam points 0-100: "))
for key,value in marks.items():
if points<=value:
print("Your corresponding grade is ", key)
break
print("Your corresponding grade is A")
I do not code in python so I might not use right syntax but this is pretty much same in all languages. Iterating trough all values is bad practice. You just need few if statements (or switch/case), something like this:
if i<=100 and i>=90:
print("Grade is A")
if i<=89 and i>=80:
print("Grade is B")
etc....
def main():
points = int(input('Enter the exam points:'))
if points >= 90:
print('Your corresponding grade is A')
elif 80 <= points <= 90:
print('Your corresponding grade is B.')
elif 70 <= points <= 80:
print('Your corresponding grade is C.')
elif 60 <= points <= 70:
print('Your corresponding grade is D.')
elif 0 <= points <= 60:
print('Your corresponding grade is F.')
your solution is pretty not optimal and could be solved really nice using some basic logic, like below, which will perform better and would be more readable:
## asking for the exam points
point = int(input("Enter the exam points 0-100: "))
point_set = 'FEDCBA'
if point == 100:
print('A')
else:
print(point_set[point // 10 - 5])
code is using simple logic, once point is less than 60, 59 // 10 evaluates to 5 and 5 - 5 = 0, so grade at index 0 will be used - F. In case point is 100, this is some edge case, and that's why I'm using special if, for other cases there is simple math, which is self explanatory.
Yes there is, I would have used this approach
def main():
points = int(input("Enter the exam points 0-100: "))
if points >= 60:
print("Your corresponding grade is F.")
elif points > 60 and points < 70:
print("Your corresponding grade is D.")
elif points > 70 and points < 80:
print("Your corresponding grade is C.")
elif points > 80 and points < 90:
print("Your corresponding grade is B.")
elif points > 90:
print("Your corresponding grade is A.")
else:
print("Error: invalid value")

Python; calculate the average of three grades for each of a number of students

I have to write code that will calculate the average of three grades for each of a number of students, and display a message depending on the resulting average grades.
The program needs to be able process any number of students; but each student will have only 3 grades. I have to use a method to calculate the average score for each student, and also to determine the appropriate message depending on the average.
This is the code I have so far and I am stuck:
def main():
more = 'y'
while more == 'y' and more == 'Y':
numScore = int(input('How many test score per student: '))
for numtest in range(numScore):
print ("The score for test")
score = int(input(': '))
total += score
total = 0
print ("Student number", students + 1)
print ('-----------------------------------------')
avg = getAvg(numScore)
if avg > 90:
print ("You're doing excellent work")
elif avg > 85 and avg <= 90:
print("You are doing pretty good work")
elif avg > 70 and avg <= 85:
print ("You better get busy")
else:
print ("You need to get some help")
def getAvg (numScore):
avg = total / numScore
print ("The average for student number", student + 1, \ "is:", avg)
more = input('Do you want to enter another student test score and get the average score of the student (Enter y for yes and n for no): ')
main()
You had most of the elements correct in your script, but you need to think more about the order of everything.
Make sure you pass any arguments that are needed to a function. Your getAvg function needed three arguments for it to calculate the average and display it with the student number. Also you forgot to return average.
When calculating the avg ranges, if you first test for >90, then by definition the next elif avg > 85 will be less than or equal to 90 so it is only necessary to then test for >85.
The following has been rearranged a bit to work:
def getAvg(student, total, numScore):
average = total / numScore
print ("The average for student number", student, "is:", average)
return average
def main():
student = 0
more = 'y'
while more == 'y':
student += 1
total = 0
numScore = int(input('How many test scores per student: '))
for test_number in range(numScore):
print ("The score for test", test_number+1)
score = int(input(': '))
total += score
print ("Student number", student)
print ('-----------------------------------------')
avg = getAvg(student, total, numScore)
if avg > 90:
print ("You're doing excellent work")
elif avg > 85:
print("You are doing pretty good work")
elif avg > 70:
print ("You better get busy")
else:
print ("You need to get some help")
print()
print('Do you want to enter another student test score and get the average score of the student?')
more = input('Enter y for yes, and n for no: ').lower()
main()
Giving you the following kind of output:
How many test scores per student: 3
The score for test 1
: 93
The score for test 2
: 89
The score for test 3
: 73
Student number 1
-----------------------------------------
The average for student number 1 is: 85.0
You better get busy
Do you want to enter another student test score and get the average score of the student?
Enter y for yes, and n for no: n

Categories

Resources