Arrays in python, arrays won't line up, ( a beginner to coding) - python

I am trying to code some arrays in python, but when I run the code below, the "sort" and "people" lists won't line up properly ie. the sort is showing the wrong people. I am quite new to python so please keep code simple thanks.
I know a lot of the code is repeated, but I am working on it. The problem area is mostly the last 3 lines but i have attached the rest, just to be sure.
people = []
score = []
people.append("Doc")
people.append("Sarah")
people.append("Jar-Jar")
Doc1 = int(input("Enter the test score for Doc "))
print("Test score:", Doc1)
Sarah1 = int(input("Enter the test score for Sarah "))
print("Test score:", Sarah1)
Jar1 = int(input("Enter the test score for Jar-Jar "))
print("Test score:", Jar1)
score.append(Doc1)
score.append(Sarah1)
score.append(Jar1)
sort = sorted(score, reverse = True)
print("[",sort[0],", '", people[0],"']")
print("[",sort[1],", '", people[1],"']")
print("[",sort[2],", '", people[2],"']")

Make tuples out of the scores and names so you can keep them together, and put those in a list; then just sort the list.
people = ["Doc", "Sarah", "Jar-Jar"]
scores = [
(int(input(f"Enter the test score for {person} ")), person)
for person in people
]
scores.sort(reverse=True)
for score, person in scores:
print(f"[{score}], '{person}'")
Enter the test score for Doc 1
Enter the test score for Sarah 4
Enter the test score for Jar-Jar 3
[4], 'Sarah'
[3], 'Jar-Jar'
[1], 'Doc'

Related

Why is my code not sorting correctly? Or what changes need to be made to it?

I am supposed to get input for a few bowlers, and their scores. Then output the top score, lowest score and the average team score. My code will not sort the scores correctly.
def myMax(list):
maxVal= -100000
maxIndex = -1
for i in range(len(list)):
if list[i] > maxVal:
maxVal = list[i]
maxIndex = i
nsList = []
while True:
temp = input("Enter Bowler and thier score by Name, Score ")
if(len(temp)==0):
break
split_list = temp.split(' ')
score=int(split_list[1])
nsList.append((split_list[0],score))
#end of loop
#print ("The high score is ", maxVal)
print(nsList)
print ("The high score is", (nsList[0]))
print ("Sorry" , nsList[-1], "has the lowest score")
You can sort your list in descending order with the following:
nsList.sort(key=lambda v : v[1], reverse=True)
Put this after your for loop that builds nsList, and you'll be good. You don't need your myMax function.
Btw, you should make it clear what your input format is in your prompt message. You currently say: "Enter Bowler and thier score by Name, Score ". This suggests that you should put a comma between Name and Score, but your code requires a single space character between them to work correctly. Alternately, you could beef up your input parsing code to be more flexible in the input it takes.

Average in Dictionary in 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())

How do I sort a list if there is an integer tied to a string by the smallest number?

I am quite new to programming and I am trying to make a leader board for a number guessing game in python 3 where you have the score then the name sorted by the lowest score first:
leaderboard_list = [0,0,0,0,0]
while True:
leaderboard_list.sort()
print("This in the leaderboard",leaderboard_list)
name = ("What is your name?")
while user_num != answer:
user_num = input("Guess a number: ")
if user_num = answer:
print("YAY")
else:
score = score + 1
leaderboard_list.append(score+" "+name)
I have tried many different ways and have figured out that if you get a score of 11, then it will say you are higher in the leader board than someone with a score of 2, which it shouldn't. I have also tried to change the score to an int type however you can't have an int and a string in the same list. How can I get around this?
Dictionary solution
dictionaries are well suited for the task of storing the scores and linking them to the user name. Dictionaries can't be directly sorted. However, there is an easy solution in this other post.
Moreover, in the OP, the name declaration is wrong, as it is not getting any value from the user. With the following code, it works perfectly. A condition for ending the while loop should added as well.
import operator
#Store the names and scores in a dictionary
leaderboard_dict = {}
#Random number
answer = 3
while True:
#Sort the dictionary elements by value
sorted_x = sorted(leaderboard_dict.items(), key=operator.itemgetter(1))
#Rewrite the leaderboard_dict
leaderboard_dict = dict(sorted_x)
print("This in the leaderboard",leaderboard_dict)
name = input("What is your name?")
#initialize score and user_num for avois crashes
user_num = -1
score = 0
while user_num != answer:
user_num = input("Guess a number: ")
if user_num is answer:
print("YAY")
else:
score += 1
leaderboard_dict[name] = score
NumPy array solution
EDIT: In case that you want to store more than one score for each player, I would user NumPy arrays, as they let you do plenty of operations, like ordering indexes by slicing and getting their numeric order, that is the request of the OP. Besides, their syntax is very understandable and Pythonic:
import numpy as np
#Random number
answer = 3
ranking = np.array([])
while True:
name = input("What is your name?")
user_num = -1
score = 1
while user_num != answer:
user_num = input("Guess a number: ")
if user_num is answer:
print("YAY")
else:
score += 1
#The first iteration the array is created
if not len(ranking):
ranking = np.array([name, score])
else:
ranking = np.vstack((ranking, [name,score]))
#Get the index order of the scores
order = np.argsort(ranking[:,1])
#Apply the obtained order to the ranking array
ranking = ranking[order]
And an example of its use:
>> run game.py
What is your name?'Sandra'
Guess a number: 3
YAY
What is your name?'Paul'
Guess a number: 6
Guess a number: 3
YAY
What is your name?'Sarah'
Guess a number: 1
Guess a number: 5
Guess a number: 78
Guess a number: 6
Guess a number: 3
YAY
What is your name?'Sandra'
Guess a number: 2
Guess a number: 4
Guess a number: 3
YAY
What is your name?'Paul'
Guess a number: 1
Guess a number: 3
YAY
Being the output:
print ranking
[['Sandra' '1']
['Paul' '2']
['Paul' '2']
['Sandra' '3']
['Sarah' '5']]
The leaderboard itself should store more structured data; use strings only to display the data.
# Store a list of (name, score) tuples
leaderboard = []
while True:
# Print the leaderboard
print("This in the leaderboard")
for name, score in leaderboard:
print("{} {}".format(score, name))
name = ("What is your name?")
score = 0
while user_num != answer:
user_num = input("Guess a number: ")
if user_num == answer:
print("YAY")
else:
score = score + 1
# Store a new score
leaderboard.append((name, score))
# Sort it
leaderboard = sorted(leaderboard, key=lambda x: x[1], reverse=True)
# Optional: discard all but the top 5 scores
leaderboard = leaderboard[:5]
Note that there are better ways to maintain a sorted list than to resort the entire leaderboard after adding a new score to the end, but that's beyond the scope of this answer.

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