Average in Dictionary in Python - python

I am trying to find the average of maths score for the class but I am not sure how to do this within a dictionary. How do I use a simple method of adding each score then dividing this by the number of students (num_students)?
login="teacher"
password="school"
usrnm=input("Please enter your username: ")
pw=input("Please enter your password: ")
if (usrnm==login) and (pw==password):
print("==Welcome to the Mathematics Score Entry Program==")
num_students = int(input("Please enter number of students:"))
print ("you entered ",num_students," students")
student_info = {}
student_data = ['Maths Score: ']
for i in range(0,num_students):
student_name = input("Name :")
student_info[student_name] = {}
for entry in student_data:
student_info[student_name][entry] = int(input(entry))
print (student_info)
else:
print("No way, Jose!")

python dictionaries have a .values() method which returns a list of the values in a dictionary which you can use, eg:
sum(d.values()) / float(len(d))
d.values() give the list of marks for your students, sum(..) gives the total of all the marks, which I divide by len(d) which is the integer length of the dictionary (ie the number of marks) obviously average is total of marks / number of marks.
you need the float because python 2 will return an integer otherwise (python 3 gives floats when appropriate)

Calculating the average can be done using the sum function as follows:
average = sum(d['Maths Score: '] for d in student_info.values()) / len(student_info)
Note that currently your code can only have students with unique names. Two students with the same name will override each other.

If you're using Python 3.4+, then you can use statistics.mean:
from statistics import mean
avg_score = mean(d.values())

Related

How do I drop one of the inputs on this for loop?

I am doing an assignment where I need to calculate an average grade, in one part I have a for loop where it takes the input of 5 quiz grades, I can't figure how to drop the lowest grade out of the ones entered during calculation.
print("Please enter 5 quiz grades.")
print("\t")
for i in range(5):
quizgrade = float(input("Quiz grade: "))
quizgradetotal += quizgrade
print("\t")
here is the code so far.
I have tried changing the loop, but I can't figure it out.
One of the ways you can approach this is to store each entered quiz grade in a list. Then you can drop the lowest grade once you know all of the grades:
quizgrades = [] # Initialize an empty list
print("Please enter 5 quiz grades.")
print("\t")
# Grab all 5 quiz grades
for i in range(5):
quizgrades.append(float(input("Quiz grade: ")))
# Now remove the lowest number from the list
quizgrades.remove(min(quizgrades))
# Now that you have a list with the lowest grade dropped, you can easily calculate the average
average = sum(quizgrades) / len(quizgrades)
print(average)
one solution is to store all your inputs in one array
gards = []
for i in range(5):
gards.append(float(input("Quiz grade: ")))
then remove the lowest grade :
gards.remove(min(gards))
finally you calculate the average of the array :
average = sum(gards) / 4
your solution is good you can overwrite the sum on every input by adding the new value then calculate the average. but the problem is that you will never know which one is the lowest once the loop is over.

Dividing a string by an integer to get GPA calculation

I am working on Python and am writing a program where the user inputs how many courses they would like to calculate. Then the program is supposed to take the appended items (the strings) and then divide them by how many courses they would like, in other words the total (integer). I cannot seem to figure out a way to implement this properly, any help? The issue is under If value = 1.
if (value == 1):
selection = int(input("How many classses would you like to include?\n"))
for i in range (0,selection):
print("What is the grade of the class?")
item = (input())
grades.append(item)
GPA_list = [sum(item)/selection for i in grades]
print(GPA_list)
You can simplify this quite a bit by using mean, which does the summing and dividing for you:
>>> from statistics import mean
>>> print(mean(
... float(input(
... "What is the grade of the class?\n"
... )) for _ in range(int(input(
... "How many classes would you like to include?\n"
... )))
... ))
How many classes would you like to include?
5
What is the grade of the class?
4
What is the grade of the class?
3
What is the grade of the class?
4
What is the grade of the class?
2
What is the grade of the class?
4
3.4
To fix your existing code, all you need to do is make sure to convert item to a float and then call sum on grades rather than each item:
grades = []
selection = int(input("How many classses would you like to include?\n"))
for i in range(0, selection):
print("What is the grade of the class?")
item = float(input())
grades.append(item)
GPA_list = sum(grades) / selection
print(GPA_list)
Note that your code prints a fraction of the average at each step in the loop until finally printing the correct result in the last iteration; if you want to fix this as well, unindent the last two lines.

How to record inputs when using "For Loop"

I'm trying to ask the user to input how many classes they have (x), ask "What are your grades in those classes?" x amount of times, and record all of the inputted grades to use later.
I tried to assign the question to a variable and ask to print the variable, but I get only the last inputted number. I don't want to print the numbers, I want to store them for later so I can add them together. I was just using the print function to see how my numbers would be stored if assigning the variable actually worked. How would I record all the inputted numbers to later add and calculate GPA?
numofclasses = int(input("How many honors classes do you have?: "))
for i in range(numofclasses):
grades = str(input("Enter the unweighted grade from one class "))
print(grades)
I want to get all the inputted numbers recorded, but by using the print option I only get the last inputted number recorded.
The thing you want to use is a list, which is used to container which holds a sequence of datatypes, like integer, characters, etc,
Think of it this way, if you want to use 3 variables in python what would you generally do
a = 1
b = 2
c = 3
This works fine, but what if the number of variables is 50, or 100, how many variables will you keep defining, hence you would need a container to store these, which is where a list comes in. So we would just do
li = [1,2,3]
And access these variables via indexes, which start from 0
a[0] #1
a[1] #2
a[2] #3
Keeping this in mind, we would do!
numofclasses = int(input("How many honors classes do you have?: "))
#List to save all grades, defined by assigning variable to []
all_grades = []
for i in range(numofclasses):
#Take grades from the user
grades = input("Enter the unweighted grade from one class ")
#Append the grades to the list, using list.append function
all_grades.append(grades)
#Loop through the list to print it
for item in all_grades:
print(item)
#Print all grades in a single line by joining all items of list in a string
s = " ".join(all_grades)
print(s)
And the output will look like
How many honors classes do you have?: 3
Enter the unweighted grade from one class A
Enter the unweighted grade from one class B
Enter the unweighted grade from one class C
#All grades in different lines
A
B
C
#All grades in single line
A B C
It seems to me there are a couple options that may be suitable.
Printing the input each iteration:
numofclasses = int(input("How many honors classes do you have?: "))
for i in range(numofclasses):
grades = str(input("Enter the unweighted grade from one class "))
print(grades) # move print to inside of loop
Storing the values in a list for printing later:
numofclasses = int(input("How many honors classes do you have?: "))
grades = []
for i in range(numofclasses):
grades.append(str(input("Enter the unweighted grade from one class ")))
print(grades) # will look like ["A", "B", "C", "B"]
Here is how yo do it:
class_dict = {}
numOfClasses = input("How many classes do you take? Enter here : ")
for i in range(int(numOfClasses)):
class_dict["class" + str(i +1)] = input("Enter your grade for class " + str(i +1) + ": ")
print(class_dict)
The above should do it.

Trying to get the function to take 4 test scores and determine the students average score out of 320 points

def getExamPoints(examPoints):
for examPoints in range(1, 5):
examPoints = input("Please enter students exam scores: ")
totalPoints = input("Please enter total possible points: ")
print("The total exam points are: " + sum(int(examPoints)))
avg = float(int(str(examPoints))/int(totalPoints))
print("the average is: ", avg)
on Line 5 I am getting the error 'int object is not iterable'
and I have no idea why.
I am attempting to write a program with functions and this portion of the function is suppose to take four homework scores each out of eighty points and calculate the average of the scores and then take that average and multiply it by the percentage that homework is worth for the class, but I cant even seem to get this chunk of the program to get an average of homework scores. I am not very good with python, also if this isn't formatted correctly I apologize in advance, but any help would be much appreciated.
examPoints is not a list of inputs in the original code, but just one variable that gets overwritten with each iteration of the user-input loop:
for examPoints in range(1, 5):
examPoints = input("Please enter students exam scores: ")
Instead, you want to keep each input separately.
e.g. by appending it to a list:
examPoints = []
for _ in range(1,5):
# add input to list after converting it to an integer
examPoints.append(int(input("Please enter students exam scores: ")))
...
The input-text-to-integer conversion can be done either as you are appending (return error to user immediately upon input that can't be converted), or when you're performing the sum, by using a list comprehension or the map function:
# sum version
sum([int(v) for v in examPoints])
# map version
sum(map(int, examPoints))
Sorry, but (In my opinion) your code is a bit messy. Instead, try:
def getExamPoints(examPoints):
points = []
for examPoints in range(1, 5):
points = points + [int(input("Please enter students exam scores: "))]
totalPoints = input("Please enter total possible points: ")
print("The total exam points are: " + sum(examPoints))
avg = float(int(str(examPoints))/int(totalPoints))
print("the average is: ", avg)
what sum() looks for is an iterable object, like a list, and adds together everything in it. Since examPoints is defined as an integer, it is not iterable. Instead, make a separate list, and put the input inside there.

Python3 about Loops Iteration multiple variable simple algorithm

What i have to do is have T number of test cases which is how many time i will
obtain the average of "n" number of students in each test case and i need to display the average score for each test case and the highest mark in that test case and the name of student
If you can tell me the proper way to code this and explain why it has to be that way i will greatly appreciate it! I am lost
My code:
t = int(input("enter number of cases: "))
def casing(t):
for case in range (1, t+1):
n = int(input("enter number of students: "))
def studentmarks(n):
total = 0
student = "none"
for computetotal in range(1,n+1):
student = input("please enter student name: ")
mark = int(input("please enter mark: "))
total = total+ mark
highestmark = mark
if studentmark(n) > mark:
highestmark = mark
achieve = student
return highestmark, acheive
return total, studentmark()[0], studentmark()[1]
average = float((studentmarks(n)[0])/ n)
print("average: ", average, "highest: ",studentmark(n)[1], "student: ", studentmark(n)[2])
I think the code, as it is, would be much simpler to understand and debug without the function declarations. Unless you're doing functional-style programming (e.g. passing around function objects) there's rarely a good reason to use nested functions. Here you're defining the functions, then immediately calling them once, which is fairly pointless. So here's a simplified version of your code:
t = int(input("enter number of cases: "))
for _ in range (t):
total = 0
highest_mark = 0
best_student = "none"
n = int(input("enter number of students: "))
for _ in range(n):
student = input("please enter student name: ")
mark = int(input("please enter mark: "))
total = total+ mark
if mark > highestmark:
highestmark = mark
beststudent = student
average = total / n
print("average: {}, highest: {}, student: {}"
.format(average, highestmark beststudent))
I also eliminated the function named studentmark (with no "s") which your code was calling but never defined. I'm not sure if I correctly interpreted what it was supposed to be doing, but I think so. It certainly wouldn't have worked before.
There are a few reasons this isn't working - but the root cause seems to be because your highestmark is started off in the wrong place. It looks like you later expect the student name and mark to be in a tuple, which is a good idea - but you never actually make this tuple anywhere. So, make one, and call it highest - it replaces both the student and highestmark variables. Start it as None instead of "none" (which could actually be a valid student name!), so you have above the loop:
total = 0
highest = None
and change your "is this one higher than the highest" logic to this:
if highest is None or mark > highest[1]:
highest = (name, mark)
Read as "if there is no highest student yet, or this one has a higher mark than the current highest, this one is the highest". Then you'll want the return to be:
return total, highest[0], highest[1]
But, since you only have a small amount of data (enough that it is feasible to have a user type it in at a console), then you can simplify this logic quite a bit. Read all of the data for a particular test case into a list of (student, mark) tuples, and then use Python's builtins to do the calculations:
def studentmarks(n):
marks = []
for _ in range(n):
student = input("please enter student name: ")
mark = int(input("please enter mark: "))
marks.append(student, mark)
return marks
# Calculations
marks = studentmarks(5)
print('Average: ', sum(result[1] for result in marks)/len(marks))
print('Highest: ', max(marks, key=lambda s: s[1])
Seeding it with:
>>> marks
[('Fred', 4), ('Wilma', 10), ('Barney', 8), ('Wilma', 7), ('Pebbles', 6)]
Gives an average of 7.0, and a maximum of ('Wilma', 10).

Categories