Having trouble on this Python homework problem - python

Question: Write a program to continuously asks the user an exam score given as integer percentages in the range 0 to 100. If a value not in the range is input except for -1, print out an error and prompt the user to try again. Calculate the average of all valid grades input along with the total number of grades in each letter-grade category as follows: 90 to 100 is an A, 80 to 89 is a B, 70 to 79 is a C, 60 to 69 is a D, and 0 to 59 is an F. Use a negative score as a sentinel value to indicate the end of the input. (The negative value is used only to end the loop, so do not use it in the calculations.) For example, if the input is.
#Enter in the 4 exam scores
g1=int(input("Enter an exam score between 0 and 100 or -1 to end: "))
g2=int(input("Enter an exam score between 0 and 100 or -1 to end: "))
g3=int(input("Enter an exam score between 0 and 100 or -1 to end: "))
g4=int(input("Enter an exam score between 0 and 100 or -1 to end: "))
total =(g1 + g2 + g3 + g4)
while g1 is range(0,100):
continue
else:
print("Sorry",g1,"is not in the range of 0 and 100 or -1. Try again!")
while g2 is range(0,100):
continue
else:
print("Sorry",g2,"is not in the range of 0 and 100 or -1. Try again!")
while g3 is range(0,100):
continue
else:
print("Sorry",g3,"is not in the range of 0 and 100 or -1. Try again!")
while g4 is range(0,100):
continue
else:
print("Sorry",g4,"is not in the range of 0 and 100 or -1. Try again!")
#calculating Average
def calc_average(total):
return total/4
def determine_letter_grade(grade):
if 90 <= grade <= 100:
1 + TotalA
elif 80 <= grade <= 89:
1 + TotalB
elif 70 <= grade <= 79:
1 + TotalC
elif 60 <= grade <= 69:
1 + TotalD
else:
1 + TotalF
grade=total
average=calc_average
#printing the average of the 4 scores
print("You entered four valid exam scores with an average of: " + str(average))
print("------------------------------------------------------------------------")
print("Grade Distribution:")
print("Number of A's: ",TotalA)
print("Number of B's: ",TotalB)
print("Number of C's: ",TotalC)
print("Number of D's: ",TotalD)
print("Number of F's: ",TotalF)
Sample output that I was given:
Enter an exam score between 0 and 100 or -1 to end: 88.64
Enter an exam score between 0 and 100 or -1 to end: 103
Sorry, 103 is not in the range of 0 and 100 or -1. Try Again!
Enter an exam score between 0 and 100 or -1 to end: 99.10
Enter an exam score between 0 and 100 or -1 to end: 71.52
Enter an exam score between 0 and 100 or -1 to end: 73
Enter an exam score between 0 and 100 or -1 to end: -1
You entered 4 valid exam scores with an average of 83.07.
Grade Distribution
Number of A’s = 1
Number of B’s = 1
Number of C’s = 2
Number of D’s = 0
Number of F’s = 0
Note: This is my first computer science class so I'm sure there is an obvious work around that I am missing but id appreciate any help I can get

Here is my walk-through explanation:
So, the program is supposed to ask the user what score they got until they say they got a score of -1, in which after you give them their results. To loop until they give -1, we can use a while loop:
inp = float(input("Enter an exam score between 0 and 100 or -1 to end: ")) # Get input
grades = []
while inp > -1: # Loop until user gives a score of -1
if inp >= 0 and inp <= 100: # Check if valid grade
grades.append(inp) # Add grade to grades list
inp = float(input("Enter an exam score between 0 and 100 or -1 to end: ")) # Ask again
else:
print("Sorry", inp, "is not in the range of 0 and 100 or -1. Try again!") # Invalid grade
# ANALYSIS OF GRADES
# Format first line of output - the first str(len(grades)) give the amount of grades they entered,
# and the str(sum(grades) / len(grades)) gives the average of the grades list.
print("You entered", str(len(grades)), "valid exam scores with an average of", str(sum(grades) / len(grades)))
print("Grade Distribution:")
print("Number of A's =", str(sum(90 <= g <= 100 for g in grades)) # I am using a very short notation
print("Number of B's =", str(sum(80 <= g <= 89 for g in grades)) # here - this is basically counting
print("Number of C's =", str(sum(70 <= g <= 79 for g in grades)) # the number of grades that are
print("Number of D's =", str(sum(60 <= g <= 69 for g in grades)) # a valid value based on the checks
print("Number of F's =", str(sum(0 <= g <= 59 for g in grades)) # I am making.
Hopefully my comments help you figure out what is happening in my code!

here your problem can be devided into few parts,
get number of exam from user
get the valid input from user for those exam
calculate the average of all exam
calculate the grade distribution
exit if user input is -1
below code is following all these steps
#calculating Average
def calc_average(scores):
return sum(scores)/len(scores)
grade_dist = {
(90, 101):'A',
(80,90):'B',
(70, 80):'C',
(59, 70):'D',
(0,59):'F'
}
def get_grade_freq(scores):
grades = {'A':0, 'B':0, 'C':0, 'D':0, 'F':0}
for score in scores:
for k, v in grade_dist.items():
if score in range(k[0], k[1]):
grades[v]+=1
print("Grade distributions")
for grade, number in grades.items():
print("Number of {}’s = {}".format(grade, number))
def get_scores(n):
scores = []
cond = True
while cond and n>0:
score = int(input("Enter an exam score between 0 and 100 or -1 to end : "))
if score==-1:
cond=False
return -1
if score not in range(0,101):
print("Sorry, {} is not in the range of 0 and 100 or -1. Try Again!".format(score))
if score in range(0,101):
scores.append(score)
n-=1
return scores
def main():
n = int(input('total number of exams ' ))
scores = get_scores(n)
if scores == -1:
exit(-1)
average = calc_average(scores)
print("You entered {} valid exam scores with an average of {}.".format(n, average))
get_grade_freq(scores)
if __name__=='__main__':
main()

Whenever you have multiple instances of similar things to manipulate (scoring ranges, total counts) you must try to use multi-value structures rather than individual variables. Python's lists and dictionaries are designed for collecting multiple entries either as a positional list or as a keyed index (dictionary).
This will make your code more generalized. You'll know you're on the right track when you manipulate concepts rather than instances.
For example:
grading = [(None,101),("A",90),("B",80),("C",70),("D",60),("F",0)]
scores = {"A":0, "B":0, "C":0, "D":0, "F":0}
counts = {"A":0, "B":0, "C":0, "D":0, "F":0}
while True:
input_value = input("Enter an exam score between 0 and 100 or -1 to end: ")
value = int(input_value)
if value == -1: break
score = next((s for s,g in grading if value >= g),None)
if score is None:
print("sorry ",input_value," is not -1 or in range of 0...100")
continue
scores[score] += value
counts[score] += 1
inputCount = sum(counts.values())
average = sum(scores.values())//max(1,inputCount)
print("")
print("You entered", inputCount, "valid exam scores with an average of: ", average)
print("------------------------------------------------------------------------")
print("Grade Distribution:")
for grade,total in counts.items():
print(f"Number of {grade}'s: ",total)
The grading list contains pairs of score letter and minimum value (in tuples). such a structure will allow you to convert the grade values in to score letters by finding the first entry that has a value lower or equal to the input value and use the corresponding letter.
The same list is used to validate the input value by strategically placing a None value after 100 and no value below zero. The next() function will perform the search for you and return None when no valid entry is present.
Your main program loop needs to continue until the input value is -1 but it needs to go through the input at least onces (typical of a repeat-until structure but there is only a while in Python). So the while statement will loop forever (i.e. while True) and will need to be arbitrarily broken when the exit condition is met.
To accumulate the scores, a dictionary (scores) is better suited than a list because a dictionary will allow you to access instances using a key (the score letter). This allows you to keep track of multiple scores in a single variable. The same goes for counting how many of each score were entered.
To get the average at the end, you simply need to sum up the values scores of the scores dictionary and divide by the count of of scores you added to the counts dictionary.
Finally to print the summary of score counts, you can leverage the dictionary structure again and only write one generalized printing line for all the score letters and totals.

This may work for you:
scores = {
"A": 0,
"B": 0,
"C": 0,
"D": 0,
"F": 0,
}
total = 0
count = 0
input_value = 0
while (input_value != -1) and (count < 4):
input_value = int(input("Enter an exam score between 0 and 100 or -1 to end: "))
if 0 <= input_value <= 100:
total += input_value
count += 1
if input_value >= 90:
scores["A"] += 1
elif input_value >= 80:
scores["B"] += 1
elif input_value >= 70:
scores["C"] += 1
elif input_value >= 60:
scores["D"] += 1
else:
scores["F"] += 1
else:
print("Sorry", input_value, "is not in the range of 0 and 100 or -1. Try again!")
print("You entered {} valid exam scores with an average of: {}".format(count, total / count))
print("------------------------------------------------------------------------")
print("Grade Distribution:")
print("Number of A's: ", scores['A'])
print("Number of B's: ", scores['B'])
print("Number of C's: ", scores['C'])
print("Number of D's: ", scores['D'])
print("Number of F's: ", scores['F'])

Related

The sentinel value isn't working and the program runs too early

So when I put in the values that I was given the program stops before it is supposed to which is at 123 as opposed to -1. I did replace{while grade_entered >=0 and grade_entered <= 100:} with {while grade_entered != '-1':} ,a sentinel value, but the program doesn't run if I do that. I also added continue as I thought it keeps the program running if I enter a number that isn't In the 0 - 100 range but that didn't help at all. My question is where am I supposed to add the sentinel value{while grade_entered != '-1':} in order for the program to end after I insert -1?
<You need to count how many passing grades are entered. Use a sentinel-controlled while loop that will ask the user to enter student grades until a value of -1 is entered. Use a counter variable to count all the grades that are passing grades, where 50 is the minimum passing grade. If there are any grades that are out of the valid range (0 through 100), present an error message to the user, and do not count that grade as passing (or valid). We also would like to see what percentage of the valid grades are passing.>
# 1st Test Case
# 45
# 90
# 70
# 87
# 123 That is not a valid test grade!
# 100 You have entered 4 passing grades.
# -1 80.0% of the valid grades are passing.
count = 0
total = 0
grade_entered = 0
print('Enter test scores to average. Enter -1 to Quit:')
while grade_entered >= 0 and grade_entered <= 100:
grade_entered = float(input(""))
if grade_entered >= 0 and grade_entered <= 100:
total += grade_entered
count += 1
continue
else:
print('This is not a valid grade!')
print("You have entered " + str(count) + " passing grades.")
average = total / count
print("{:.2f}% of the valid grades are passing".format(average))
This is the result that I get
Enter test scores to average. Enter -1 to Quit:
45
90
70
87
123
This is not a valid grade!
You have entered 4 passing grades.
73.00% of the valid grades are passing
it is important to do correct indentations when using python, your else clause is not part of the while loop anymore because it is too far left.
The whole thing should look somewhat like this:
grade_entered = float(input(""))
while grade_entered != -1:
if grade_entered >= 0 and grade_entered <= 100:
total += grade_entered
count += 1
#continue this is unnecesarry
else:
print('This is not a valid grade!')
grade_entered = float(input(""))

How to calculate total students passed and failed the test

I'm doing this exercise:
Write a program that will ask the user to key in N, that is the size
of a class. Given that the passing mark for a subject test is 50,
count how many of the students passed and failed the test. Calculate
the average mark obtained by the students. Make sure all marks
entered are valid (between 0 and 100). If user enters an invalid mark,
prompt a message “Invalid Marks !!!” and the program continue outside
the loop.
This is my solution:
n = int(input('Enter Any Size of Class You Want: '))
intList = []
for i in range(1, n + 1):
value = int(input("Enter Marks (0 - 100): "))
intList.append(value)
i = value
pass_student = 0
invalid = 0
fail_student = 0
if i >= 50:
pass_student = pass_student + 1
elif i >= 100:
invalid = invalid + 1
elif i < 50:
fail_student = fail_student + 1
print('The Total Passed Student: ', pass_student)
print('Invalid Marks!!!')
print('The Total Failed Student: ', fail_student)
#Average
average = value / n
print('The Average is: ', average)
The output that I got:
Enter Any Size of Class You Want: 2
Enter Marks (0 - 100): 45
Enter Marks (0 - 100): 64
The Total Passed Student: 1
Invalid Marks!!!
The Total Failed Student: 0
The Average is: 32.0
The sample output:
Enter Any Size of Class You Want: 4
Enter Marks (0 – 100) : 40
Enter Marks (0 – 100) : 60
Enter Marks (0 - 100) : 30
Enter Marks (0 – 100) : 200
Invalid Marks !!!
The Total Passed Student : 1
The Total Failed Student : 2
The Average is: 43
n = int(input('Enter Any Size of Class You Want: '))
pass_student = 0
fail_student = 0
sum = 0
for i in range(n):
mark = int(input("Enter Marks (0 - 100): "))
if mark < 0 or mark > 100:
print('Invalid Marks!!!')
break
elif mark >= 50:
pass_student = pass_student + 1
sum += mark
else: # 0 <= mark < 50
fail_student = fail_student + 1
sum += mark
print('The Total Passed Student: ', pass_student)
print('The Total Failed Student: ', fail_student)
print('The Average is: ', sum // (pass_student + fail_student))
With the break command you exit from the closest loop, so you can assure that the program continues outside the loop.
You have to divide the summ of grades with the passed and failed students, and not with the class size, because you can enter a wrong mark also what shall not be included into the average calculation.
The average is calculated by calculating sum then dividing this sum by total number of inputs but in this example you only use last value passed to calculate the average instead use
n = int(input(' Enter Any Size of Class You Want: '))
intList = []
for i in range(1, n + 1):
value = int(input(" Enter Marks (0 - 100): "))
intList.append(value)
i = value
pass_student = 0
invalid = 0
fail_student = 0
if i >= 50:
pass_student = pass_student + 1
elif i > 100:
invalid = invalid + 1
elif i < 50:
fail_student = fail_student + 1
print(' The Total Passed Student: ', pass_student)
if invalid:
print('There is Invalid Marks!!!')
print(' The Total Failed Student: ', fail_student)
#Average
average = sum(intList) / n
print(' The Average is: ', average)
This code also print invalid marks only if there is invalid marks and make sure that some student can get 100(I guess you want this) by fixing elif i >= 100: to elif i > 100:. but NOTE that if there is invalid marks these marks will be calculated in the average. since you append invalid marks to the list no matter what and you don't adjust n accordingly.
pass_students = fail_students = 0
total = n = 0
for i in range(int(input('Class size: '))):
marks = int(input())
if 0 <= marks <= 100:
if marks < 50:
fail_students += 1
else:
pass_students += 1
total += marks
n += 1
else:
print('Invalid!!')
continue
print('Total passed students', pass_students)
print('Total failed students', fail_students)
print('Class Average', total / n)
I hope this answered you question

Getting the minimum value from user input in a while loop

I am writing a Python program that continuously asks a user for a number from 1 to 100, then once the user inputs the number 0, the program print out the smallest number and largest number provided, as well as the average of all the numbers.
My only problem: I keep getting 0 as the smallest value of the input when I want to exclude 0.
I have already tried doing the following:
count = 0
total = 0
number = 1
smallest = 0
largest = 0
while number != 0:
number = int(input("Please input a value from 1 to 100: "))
if number < 0 or number > 100:
print("Why you give me value outside of range :(\n")
count -= 1
continue
count += 1
total = total + number
if number > largest:
largest = number
if number == 0:
count -= 1
average = total / count
if number < smallest:
smallest = number
print("The results are: ")
print('Smallest: {}'.format(smallest))
print('Largest: {}'.format(largest))
print('Average: {}'.format(average))
print("\nThank you!")
You need to track both the largest and the smallest as the numbers are being input.
Also I have checked for the out of range numbers before any processing takes place:
count = 0
total = 0
number = 0
smallest = 101 # starts bigger than any input number
largest = 0 # starts smaller than any input number
while True:
number = int(input("Please input a value from 1 to 100: "))
if number == 0:
break
if number < 0 or number > 100:
print("Why you give me value outside of range :(\n")
continue
count += 1
total = total + number
if number > largest:
largest = number
if number < smallest:
smallest = number
if number == 0:
average = total / count
print("The results are: ")
print('Smallest: {}'.format(smallest))
print('Largest: {}'.format(largest))
print('Average: {}'.format(average))
print("\nThank you!")
Just add smallest = 101 in the beginning, and
if number < smallest:
smallest = number
to your while block, and remove the same code in the end.
Also, your count is off, you should just remove the two decrements count -= 1 to fix that.
You can also remove the if number == 0:, since you already have while number != 0: in the while condition, so you know it is zero.
Here is another version, this time using a list to hold the valid numbers:
numbers = []
while True:
number = int(input("Please input a value from 1 to 100: "))
if number == 0:
break
if number < 0 or number > 100:
print("Why you give me value outside of range :(\n")
continue
numbers.append(number)
if numbers:
average = sum(numbers) / len(numbers)
print("The results are: ")
print('Smallest: {}'.format(min(numbers)))
print('Largest: {}'.format(max(numbers)))
print('Average: {}'.format(average))
print("\nThank you!")

Python Grading Program

So I need to make a program that grades 10 students individually, then displays the average grade for all 10 students.
I think this is how the grading should look, but im not sure how to set up a count on the number of times its graded, or how to set up the average function. Help would be most welcome. I am a horrible coder.
score = int(input("Enter a score between 0 and 100: "))
if score >=89:
print("The grade is an A")
elif score>=79:
print("The grade is a B")
elif score>=69:
print("The grade is a C")
elif score>=59:
print("The grade is a D")
else:
print("The grade is a F")
You can try using a counter variable that goes from 0-9 and use a while loop to check and increment that counter value and after each loop calculates the average and keeps doing this till the last value has been entered
Counter = 0
average = 0
while (Counter <= 10):
score = int(input("Enter a score between 0 and 100: "))
if score >= 89:
print("The grade is an A")
elif score >= 79:
print("The grade is a B")
elif score >= 69:
print("The grade is a C")
elif score >= 59:
print("The grade is a D")
else:
print("The grade is a F")
Counter = Counter + 1
average = (score + average)
average = average/Counter
print("Average of all 10 students:",average)
So right now the code is configured specifically for just 10 loops but you can give the user the power to determine this by suggesting a value to end the loop and the while loop will check for this value and when the loop sees the value it exits the loop and gives a value
Also with each loop there is a counter value that keeps increasing and an average value that holds the sum of the values entered and when the loop exits and average is calculated by dividing the sum by the counters and this gives the results
This should do the trick.
total = 0
for i in range(10):
score = int(input("Enter a score between 0 and 100: "))
if score >= 89:
print("The grade is an A")
elif score >= 79:
print("The grade is a B")
elif score >= 69:
print("The grade is a C")
elif score >= 59:
print("The grade is a D")
else:
print("The grade is a F")
total += score
print("Average of all 10 students:", total/10)
In the for loop you get the score of each student and then add it to the total of all students. When the loop ends you divide it with the total number of students so 10.
total score / total number of students total / 10
You can define a function that finds the average score. Store all the scores in a list and then pass the list as an argument in the function
def avg(scores): #assuming scores is the name of the list
avg = sum(scores)/len(scores)
return "Average score is {}".format(avg)
Or
return f'Average score is {avg}' #for python3
Not sure I understand what you mean by number of times it is graded but I think you can include a while loop and a variable that increases by 1 every time it grades.

Variables contain 0 and do not take in user input

I try to calculate several properties of students:
the amount of students
the sum of the marks of the students
the lowest, the average and the highest mark they received.
Yet, the variable mark only shows 0.
How can I solve this problem using function but not max() and min()?
mark = 0
a = 0
student = 0
a = int(input("Enter Marks :"))
def maxx():
maxx = 0
for i in range(1, a):
if a> maxx :
maxx = a
return maxx
def minn():
minn = 0
for i in range(1, a):
if a < minn :
minn = a
return minn
while (a >= 0):
mark = mark + a
student = student + 1
a = int(input("Enter Marks :"))
print("Exit")
print("Total students :", student)
print ("The total marks is:", mark)
average = mark/student
print ("The average marks is:", average)
print("The max marks is :", maxx())
print("The min marks is :", minn())
Your code has a lot of problems. One of them is
for i in range(1, a):
This part makes no sense if you want a min or max value. You need to iterate over a list of grades instead.
mark and student are also unnecessary considering they can be replaced by sum and len respectively.
The entire code seems to lack a proper structure. Here's an example implementation. If you are not allowed to use sum or len, you may bring your own mark and student method back, but try not to make a mess and keep it readable:
def maxx(grades):
if (not grades): # if empty, we let the caller know
return None
res = grades[0] # we know the list is not empty
for i in grades:
if i > res:
res = i
return res
def minn(grades):
if (not grades):
return None
res = grades[0]
for i in grades:
if i < res:
res = i
return res
def main():
grades = [] # list of grades
while (True):
grade = int(input("Enter Mark: "))
if (grade < 0): break
grades.append(grade)
student_cnt = len(grades)
total = sum(grades)
print("Exit")
print("Total students :", student_cnt)
print("The total marks is:", total)
print ("The average marks is:", total / student_cnt)
print("The max marks is :", maxx(grades))
print("The min marks is :", minn(grades))
if __name__ == "__main__":
main()
Input/Output:
Enter Mark: 30
Enter Mark: 20
Enter Mark: 10
Enter Mark: 40
Enter Mark: -1
Exit
Total students : 4
The total marks is: 100
The average marks is: 25.0
The max marks is : 40
The min marks is : 10

Categories