I've tried to make a program that will sort the results of a competition, by asking the user the number of competitors, then the name and score of each one.
It worked but now i have to make it recognize when two or more people get the same score (that is) they have the same position, and that the number of extra people on a position will be the number of position that will be omitted before it continues ranking the others. Here is what i have done, so far,
# Filename: result_sorter.py
# A Program that's sorts results
#
# Obasa Adegoke - 18/04/11(dd/mm/yy)
# This function allows the user to quit at any time in the program
def quitter(word):
""" Allows the user to quit at any time"""
if word.upper() == "Q":
quit()
else:
pass
def result_sorter():
play_again = 'yes'
while play_again == 'yes' or play_again == 'y':
# This line asks the user for the number of values
count = input("Number")
quitter(count)
count = int(count)
# Initialize the various lists to be used
name = []
score = []
sorting = []
# The Various names and respective scores are added to the lists
for i in range(count):
# this line accepts the name
temp1 = input("name")
quitter(temp1)
temp1 = str(temp1.title())
name.append(temp1)
# this line accepts the respective score
temp2 = input("score")
quitter(temp2)
temp2 = int(temp2)
score.append(temp2)
sorting.append(temp2)
# Scores are sorted in ascending order
sorting.sort()
print("\t Postion \t Name \t \t Score")
n = 1
k = count
while n!= count +1:
rank = sorting.pop(0)
index = int(score.index(rank))
name_sort = name[index]
print('\t {0} \t \t \t {1} \t \t {2}'.format(k, name_sort, rank))
n += 1
k -= 1
play_again = input("Do you want to sort again [y or n]")
play_again = play_again.lower()
print(" Result Sorter ".center(40, '*').center(70))
print(" version 1.0 ".center(40, '*').center(70))
print('To quit at anytime just type [q]'.center(70))
result_sorter()
print("copyright 2011".center(70)) Will love to know how i can make it do this, and also how i can make it print from top to bottom instead of bottom to top.
Thanks in advance.
To associate name and score you would use a list, tuple or dictionary of pairs, so as to keep them together. The name and score that you print do not necessarily go together. The Python sorting HowTo is here .
import operator
name_score = []
## example data
name = "Joe"
score = 5
name_score.append([name, score])
name = 'Steve'
score = 2
name_score.append([name, score])
name = 'Mike'
score = 7
name_score.append([name, score])
print name_score
name_score.sort() ## in name order
print "\nname order", name_score
## itemgetter[1] = memory offset X 1 = second item = score
score_sorted = sorted(name_score, key=operator.itemgetter(1))
print "\nscore order", score_sortedI'm sorry I forgot something, how about when i want to add positions, and two or more persons have the same scores, how do i go about doing things like that, i still trying to work on that.
Well this is what i now have, thanks for the help
# Filename: result_sorter.py
# A Program that's sorts results
#
# Obasa Adegoke - 18/04/11(dd/mm/yy)
import operator
# This function allows the user to quit at any time in the program
def quitter(word):
""" Allows the user to quit at any time"""
if word.upper() == "Q":
quit()
else:
pass
def result_sorter():
play_again = 'yes'
while play_again == 'yes' or play_again == 'y':
# This line asks the user for the number of values
count = input("Number\n".center(70))
quitter(count)
count = int(count)
# Initialize the various list to be used
name_score = []
# The Various names and respective scores are added to the lists
for i in range(count):
# this line accepts the name
name = input("Competitor\n".center(70))
quitter(name)
name = str(name.title())
# this line accepts the respective score
score = input("Competitor's score\n".center(70))
quitter(score)
score = int(score)
name_score.append([name, score])
# results in raw form
print("| |".center(70))
print("Results".center(40).center(70))
for i in name_score:
print('{0}'.format(i).center(40).center(70))
# results sorted
name_score.sort()
# results in name order
print("| |".center(70))
print("Results sorted in name order".center(40).center(70))
for i in name_score:
print('{0}'.format(i).center(40).center(70))
print('-'.center(20, '-').center(70))
score_sorted = sorted(name_score, key = operator.itemgetter(1))
# results in rank order
print("| |".center(70))
print("Ranked results".center(40).center(70))
for i in score_sorted:
print('{0}'.format(i).center(40).center(70))
play_again = input("Do you want to sort again [y or n]")
play_again = play_again.lower()
# start program
print("+--------------------------------+".center(70))
print("| Result Sorter v1.0 |".center(40).center(70))
print("+--------------------------------+".center(70))
print('|To quit at anytime just type [q]|'.center(70))
result_sorter()
print("| |".center(70))
print("| copyright 2011 |".center(70))
print("+--------------------------------+".center(70))
how did I do.
You could use itertools.groupby which has a nice example right in the docs.
Once you have the groups, just calculate the ranking: All the folks in the first group tie for 1st place. All the folks in the second group tie for (count of 1st-place people + 1); All in the Nth group tie for place (sum of people in previous groups)+1
Or you can keep the original, sorted by points list and record the points where number of points change + 1 (or enumerate starting from 1) as position for that many points in dictionary.
import random
COUNT = 20
MAXPOINTS = 12
points = [random.randint(1, MAXPOINTS) for count in range(COUNT)]
print('Points unsorted', points)
points_sorted = sorted(points, reverse = True)
print('Points sorted', points_sorted)
positions = dict()
prev = float('inf')
for place, p in enumerate(points_sorted, 1):
if prev > p:
positions[p] = place
prev=p
for player_no, p in enumerate(points, 1):
print('Player %i, points %i, position %i' %(player_no, p, positions[p]))You could use itertools.groupby which has a nice example right in the docs. Once you have the groups, just calculate the ranking: All the folks in the first group tie for 1st place. All the folks in the second group tie for (count of 1st-place people + 1); All in the Nth group tie for place (sum of people in previous groups)+1
itertools seems to be very good,I'll check it out, thanks a lot.
Or you can keep the original, sorted by points list and record the points where number of points change + 1 (or enumerate starting from 1) as position for that many points in dictionary.
import random COUNT = 20 MAXPOINTS = 12 points = [random.randint(1, MAXPOINTS) for count in range(COUNT)] print('Points unsorted', points) points_sorted = sorted(points, reverse = True) print('Points sorted', points_sorted) positions = dict() prev = float('inf') for place, p in enumerate(points_sorted, 1): if prev > p: positions[p] = place prev=p for player_no, p in enumerate(points, 1): print('Player %i, points %i, position %i' %(player_no, p, positions[p]))
Thanks a lot, i will try and read through this understand and implement, thanks again for the help.