How to sort integers in a variable? - python

Please note that this is on Python 3.3
Here is the code:
students=int(input("How many student's score do you want to sort? "))
options=input("What do you want to sort: [Names with scores] , [Scores high to low] , [Scores averages] ? ")
options=options.upper()
if options == ("NAMES WITH SCORES") or options == ("NAME WITH SCORE") or options == ("NAME WITH SCORES") or options == ("NAMES WITH SCORE"):
a=[]
for i in range(0,students):
name=input("Enter your scores and name: ")
a.append(name)
a.sort()
print("Here are the students scores listed alphabetically")
print(a)
if options == ("SCORES HIGH TO LOW") or options == ("SCORE HIGH TO LOW"):
b=[]
number=0
for i in range(0,students):
number = number+1
print("Student "+str(number))
name2=int(input("Enter your first score: "))
name3=int(input("Enter your second score: "))
name4=int(input("Enter your third score: "))
b.append(name2)
b.append(name3)
b.append(name4)
final_score = name2 + name3 + name4
print (final_score)
b.sort(final_score)
print("Student "+str(number) )
print(b)
Here is the outcome of the code:
>>>
How many student's score do you want to sort? 2
What do you want to sort: [Names with scores] , [Scores high to low] , [Scores averages] ? scores high to low
Student 1
Enter your first score: 1
Enter your second score: 2
Enter your third score: 3
Student 2
Enter your first score: 3
Enter your second score: 5
Enter your third score: 6
14
Traceback (most recent call last):
File "H:\GCSE Computing\Task 3\Task 3.py", line 31, in <module>
b.sort(final_score)
TypeError: must use keyword argument for key function
>>>
I want the code to add the three scores of the students and sort the total scores of the students, with the according name.
For example:
(2 Students)
Student 1
Score 1 - 2
Score 2 - 4
Score 3 - 7
(Therefore the total is 13)
Student 2
Score 1 - 5
Score 2 - 1
Score 3 - 4
(Therefore the total is 10)
(The program prints in order from highest to lowest)
"Student 1 - 15 , Student 2 - 10"

You need to use the syntax key=final_score when passing a function to sort by:
b.sort(key=final_score)
But the sort method expects a function to be passed in not a variable so passing the int value from adding name2 + name3 + name4 is not going to work.
If you just want the list of scores sorted simply call b.sort()
What you should be doing is using a defautdict and using each name as key and store all scores in a list:
from collections import defaultdict
d = defaultdict(list)
for _ in range(students):
name = input("Enter your name: ")
scores = input("Enter your scores separated by a space: "
# add all scores for the user to the list
d[name].extend(map(int,scores.split()))
To show mean, total and max it is trivial:
# from statistics import mean will work for python 3.4
for k,v in d.items():
print("Scores total for {} is {}".format(k,sum(v)))
print("Scores average for {} is {}".format(k,sum(v)/len(v))) # mean(v) for python 3,4
print("Highest score for {} is {}".format(k, max(v)))
Print sorted by highest user total score:
print("The top scoring students from highest to lowest are:")
for k,v in sorted(d.items(),key=lambda x:sum(x[1]),reverse=True):
print("{} : {}".format(k,sum(v)))
Now you have a dict where the student names are the keys and each students scores are all stored in a list.
Really you should add a try/except taking the user input and verify it is in the correct format.

Related

python program to calculate and print average of subjects and students

How do i calculate the average of students &subjects. Below is my code but only gives average of students and not subjects
values = []
for i in range(0, 3):
name = input("enter the name of the first student: ")
test_1 = int(input("Enter the score on test 1 for the student: "))
test_2 = int(input("Enter the score on test 2 for the student: "))
test_3 = int(input("Enter the score on test 3 for the student: "))
test_4 = int(input("Enter the score on test 4 for the student: "))
values.append((name, (test_1 + test_2 + test_3+test_4) / 4))
for row in values
print(row)`print(row)
print("ENTER EXAM SCORE: ")
I think it would be helpful if the arithmetic was delegated out to a separate function such as:
def Average(list):
return sum(list) / len(list)
This way you would be able to call it on all of the test scores or whatever else you wish to implement within the for loop.
It looks like you may benefit from the use of key value pairs(dictionary) to store the data at hand (names: test scores), as well. But this isn't entirely relevent to your question since you can use lists as well.
student_scores = {'Tom': '85.25', 'Jack': '80'}
test_averages = {'test_1': *avg, 'test_2': *avg}
I don't see where you are currently storing the values for each subject in order to calculate this. For example, I would expect to see something like this:
test_1 = [std1_score, std2_score, std3_score, ...etc]
test_2 = [std1_score, std2_score, std3_score, ...etc]
test_3 = [std1_score, std2_score, std3_score, ...etc]
then:
def Average(test_1):
return sum(test_1) / len(test_1)
Instead, it looks like all you are appending to "values" are the student name and their average score per loop without actually saving the test cases for each student as well. There are many ways to do this but figured this could provide a helpful visual of how to go about structuring the code itself.
There you go:
student_grades = {}
test_scores = {1: [], 2: [], 3: [], 4: []}
for i in range(0, 3):
# `.capitalize()` converts strings like jack, into Jack.
name = input("Enter the name of the student: ").capitalize()
# Avoiding duplications, when two students have the same name.
# In such instances, we'll enumerate the students with same name.
# For example: Jack, Jack(1), Jack(2), etc.
duplicate_names_count = 1
_name = name
while name in student_grades.keys():
duplicate_names_count += 1
name = f"{_name}({duplicate_names_count})"
# Create new student entry on dictionary
student_grades[name] = []
# Iterate through `test_scores` keys, to fill each test grades.
for test_index, test_values in test_scores.items():
test = int(input(f"Enter the score on Test {test_index} for {name}: "))
student_grades[name].append(test)
# Register the givem student grades, to the respective test results.
test_values.append(test)
# Compute the average score for the given student
student_grades[name] = sum(student_grades[name]) / len(student_grades[name])
# Print average score of each student
for student, score in student_grades.items():
print(f"Test average for {student} is {score:.2f}")
# Print average score of each test
for test_index, test_values in test_scores.items():
print(f"Test {test_index} average score is {sum(test_values)/len(test_values):.2f}")
# Example:
#
# Enter the name of the student: Tom
# Enter the score on Test 1 for Tom: 90
# Enter the score on Test 2 for Tom: 60
# Enter the score on Test 3 for Tom: 70
# Enter the score on Test 4 for Tom: 80
# Enter the name of the student: Jack
# Enter the score on Test 1 for Jack: 90
# Enter the score on Test 2 for Jack: 90
# Enter the score on Test 3 for Jack: 85
# Enter the score on Test 4 for Jack: 100
# Enter the name of the student: Mary
# Enter the score on Test 1 for Mary: 95
# Enter the score on Test 2 for Mary: 96
# Enter the score on Test 3 for Mary: 97
# Enter the score on Test 4 for Mary: 98
# Test average for Tom is 75.00
# Test average for Jack is 91.25
# Test average for Mary is 96.50
# Test 1 average score is 91.67
# Test 2 average score is 82.00
# Test 3 average score is 84.00
# Test 4 average score is 92.67
Notes
The code is a little lengthy, but it accounts for things like students with the same name. You can also swap test = int(input(f"Enter the score on Test {test_index} for {name}: ")) for a while/loop to ensure the inputted grade stays between 0, and 100.
here is pythonic way to do this, feel free adjust the tests_number and students_number
tests_number = 3
students_number = 4
values = {}
for student in range(students_number):
name = input("enter the name of the student: ")
scores = []
for test in range(tests_number):
scores.append(
int(input(f"Enter the score on test {test+1} for the student: "))
)
values.update({name: scores})
for name, scores in values.items():
print(f"Test average for {name} is {sum(scores)/len(scores):.2f}")
for test in range(tests_number):
test_average = sum(map(lambda x: x[test], values.values())) / tests_number
print(f"Test {test+1} average is {test_average:.2f}")

(TypeError: unsupported operand type(s) for +: 'int' and 'list') calculating the average score in list

I'm trying to calculate the average score. but there seems to be some problem with my code. I'm not sure what to do but it says in the introduction:
f) Create a new list called avg_scores that is the list of average extra credit test scores of Marla, Ashford, and Sam.
• Use the data from the updated all_scores to calculate the averages. You do NOT need nested for loops for this step.
• Use a single for loop to access each inner list, then calculate the average of the inner list. Append that average to the avg_scores list.
• Display avg_scores.
# a
m_list = []
print("Please enter Marla's scores one by one.")
for i in range(3):
m_test = int(input("Enter a score: "))
m_list.append(m_test)
print("Marla's scores: ", m_list)
# b
a_list = []
print("Please enter Ashford's scores one by one.")
for i in range(3):
a_test = int(input("Enter a score: "))
a_list.append(a_test)
print("Ashford's scores: ", a_list)
# c
s_list = []
print("Please enter Sam's scores one by one.")
for i in range(3):
s_test = int(input("Enter a score: "))
s_list.append(s_test)
print("Sam's scores: ", s_list)
# d
all_scores = []
for i in (m_list, a_list, s_list):
all_scores.append(i)
print("All scores: ", all_scores)
# e
for i in range(len(all_scores)):
for p in range(len(all_scores[i])):
all_scores[i][p] = all_scores[i][p] + 2
print("All scores after extra point:", all_scores)
# f
sum_scores = sum(all_scores)
len_scores = len(all_scores)
avg_scores = sum_scores/len_scores
print("Average scores: ", avg_scores)
all_scores is a 2-D list, so you need to take each list and add its sum to sum_scores using a for loop:
avg_scores = []
for scores in all_scores:
avg_scores.append(sum(scores) / len(scores))
Alternatively, if you want something more concise, you can do:
avg_scores = list(score / 3 for score in map(sum, all_scores))
(I've only included this approach for completeness; most developers would not reasonably expect someone just starting out to be familiar with this syntax.)
To compute the average for each student, you need to take sum(scores) / len(scores) for each scores list in all_scores, i.e.:
avg_scores = [sum(scores) / len(scores) for scores in all_scores]
Note that you can take advantage of for loops to get the scores for each student without having to copy and paste the same code for each one individually:
all_scores = []
for name in ("Marla", "Ashford", "Sam"):
print(f"Please enter {name}'s scores one by one.")
all_scores.append([int(input("Enter a score: "))for _ in range(3)])
print("All scores:", all_scores)
all_scores = [[i + 2 for i in scores] for scores in all_scores]
print("All scores after extra point:", all_scores)
avg_scores = [sum(scores) / len(scores) for scores in all_scores]
print("Average scores:", avg_scores)
Please enter Marla's scores one by one.
Enter a score: 5
Enter a score: 5
Enter a score: 4
Please enter Ashford's scores one by one.
Enter a score: 3
Enter a score: 5
Enter a score: 4
Please enter Sam's scores one by one.
Enter a score: 5
Enter a score: 5
Enter a score: 5
All scores: [[5, 5, 4], [3, 5, 4], [5, 5, 5]]
All scores after extra point: [[7, 7, 6], [5, 7, 6], [7, 7, 7]]
Average scores: [6.666666666666667, 6, 7]

How do I use user input to determine how the program works?

this is my first post here on stackoverflow and this is my first time using Python to make a program. I want to make a program to ask the user to input names of students then be able to add more information to that student as the program continues to run. Ideally I want the user to choose how many students there are, choose how many rounds are played, give them names, assign scores, and at the end output the final score and the averages of each student.
This is what I have currently:
name_students = list()
num_students = input("How many students?: ")
competitionRounds = input("How many rounds: ")
score_students = list ()
myList = name_students
for i in range(1, int(num_students) + 1):
name_students.append(input("Student Name: "))
print(name_students)
for i in range (1, int(competitionRounds)):
print(input(name_students [0] + " Total Score for each round: "))
This is how the program runs:
How many student?: 3 #Have the user input answers to these questions
How many rounds?: 2
Student Name: Nick
Student Name: Bob
Student Name: Lisa
Nick Total Score for each round:
I was trying to get it to ask for every name listed like
Nick Total Score for round 1:
Bob Total score for round 1:
Lisa Total score for round 1:
Nick Total score for round 2:
Etc.
I appreciate anyone who replies.
---Edit---
So I now have problems taking the numbers inputted by the user and adding them together by the name placed by the user.
My expected outcomes is:
Nick Total Score for round 1: 2
Bob Total score for round 1:3
Lisa Total score for round 1:1
Nick Total Score for round 2:2
Bob Total score for round 2:3
Lisa Total score for round 2:1
Nick Total score for all rounds: 4
Etc
Currently my code looks like:
name_students = list()
num_students = input("How many students?: ")
competitionRounds = input("How many rounds: ")
score_students = []
myList = name_students
total_scores = 0, []
for i in range(1, int(num_students) + 1):
name_students.append(input("Student Name: "))
for i in range (1, int(competitionRounds) +1):
for j in range(len(name_students)):
score_students.append(input(name_students [j] + " Total Score for round " + str(i) +": "))
for i in range (1,int(competitionRounds) +1):
for t in range(len(score_students)):
print(name_students + score_students + total_scores)
You need to change the last loop
for i in range (1, int(competitionRounds)):
for j in range(len(name_students)):
score_students.append(input(name_students [j] + " Total Score for round " + str(i) + ": "))
This will ask the user for each student's score for each round, and keep appending that to score_students. You may then manipulate that the way you want.
How many students?: 2
How many rounds: 3
Student Name: A
Student Name: B
['A', 'B']
A Total Score for round 1: 2
B Total Score for round 1: 1
A Total Score for round 2: 2
B Total Score for round 2: 1

Get average grade for 10 students - python

I have a program that asks a user to enter a Student NETID and then what grades they got on 5 assignments plus the grade they got on the mid-term and final. It then adds them and divides to get that students average grade which displays in table format.
What I need to do, is loop through that whole process 9 more times. So essentially, Ill be asking 9 more students the same input, which then Ill need to display in the table format.
My question is how would I loop through the process that I have right now 'x' amount of times, then display the average of all students.
This is my code right now:
# x holds the list of grades
x = []
# count of assignments
assignments = 5
# Ask for a student ID from user
NETID = int(input('Enter your 4 digit student NET ID: '))
# fill list with grades from console input
x = [int(input('Please enter the grade you got on assignment {}: '.format(i+1))) for i in range(assignments)]
midTermGrade = int(input('Please enter the grade you got on you Mid-Term: '))
finalGrade = int(input('Please enter the grade you got on you Final: '))
# count average,
average_assignment_grade = (sum(x) + midTermGrade + finalGrade) / 7
print()
print('NET ID \t Average Final Grade')
print('---------------------------------')
for number in range(1):
print(NETID, '\t\t', format(average_assignment_grade, '.1f'),'%')
main()
And this is how it looks on console:
You really did the hardest part. I don't see why you couldn't so the loop of the average. Anyway:
student_count = 5;
A = [student_count]
for id_student in range(student_count):
print("STUDENT #", id_student+1)
# x holds the list of grades
x = []
# count of assignments
assignments = 5
# Ask for a student ID from user
NETID = int(input('Enter your 4 digit student NET ID: '))
# fill list with grades from console input
x = [int(input('Please enter the grade you got on assignment {}: '.format(i+1))) for i in range(assignments)]
midTermGrade = int(input('Please enter the grade you got on you Mid-Term: '))
finalGrade = int(input('Please enter the grade you got on you Final: '))
# count average,
average_assignment_grade = (sum(x) + midTermGrade + finalGrade) / 7
print()
print('NET ID | Average Final Grade')
print('---------------------------------')
for number in range(1):
print(NETID, " | ", format(average_assignment_grade, '.1f'),'%')
A.append(average_assignment_grade);
grades_sum = sum(A)
grades_average = grades_sum / 5;
print("SUM OF ALL STUDENTS = " + grades_sum)
print("AVERAGE OF ALL STUDENTS = " + grades_average)
Update: As suggested above, you should make a function for a single student and loop through that function in another, since SO is not a coding service I won't do that for you, but I think you got the idea.

Control conditional loop in Python

I'm creating a program that asks for the number of students, then asks for their names.
Ex:
Enter the test scores of the students:
> 4
When I use the same method for grades, it won't work (the final output desired is the name of the student next to the grade). My second loop doesn't seem to work.
Desired Output:
Enter the test scores of the students: 5
Bob
Tom
Obi
Eli
Brady (only lets me add 5 names)
Enter the test scores of the students:
100
99
78
90
87 (only lets me add 5 grades)
OUTPUT:
Bob 100
Tom 99
Obi 78
Eli 90
Brady 87
Here is the code I have tried:
students = []
scores = []
count = 0
count2 = 0
number_of_students = int(input("Enetr the number of students: "))
while count != number_of_students:
new_student = input()
students.append(new_student)
count = count + 1
if count == number_of_students:
break
print("Enter the test scores of the students: ")
while count2 != count:
new_score = input()
scores.append(new_score)
count2 = count2 + 1
if count == number_of_students:
break
What can I change?
I think this is a case where you're making the problem harder than it is. You don't need to check the end condition both at the while and at the end of the loop -- just once should be fine. Also you don't need a counter for the second loop, you can just loop over the names from the first loop:
students = []
scores = []
count = 0
number_of_students = int(input("Enter the number of students: "))
while count < number_of_students:
new_student = input("Student name: ")
students.append(new_student)
count = count + 1
print("Enter the test scores of the students:")
for name in students:
new_score = input("Score for " + name + ": ")
scores.append(new_score)
But whenever I see parallel arrays like this, an alarm goes off that says you need a better data structure. Perhaps an array of tuples or a dictionary.

Categories