1

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?

demongolem
  • 9,474
  • 36
  • 90
  • 105
  • 1
    Are you saying that the lowest score is the best? – Douglas Dec 14 '16 at 16:26
  • Should the leaderboard only store the top five players? – pzp Dec 14 '16 at 16:32
  • Where is answer initialized? Is this all of your code? – pzp Dec 14 '16 at 16:34
  • You want the leaderboard_list to contain numbers because when sorting strings, 11 does come before 2. Why are you appending score as a string? Perhaps it is a map (dictionary) your are after instead of a list? – demongolem Dec 14 '16 at 16:49
  • Yes the lowest score is better as it shows they got the correct answer in less tries. It would be useful if it only displayed the top five players but it is not necessary. The answer is simply a random number. Finally, thanks demongolem as I have found dictionaries much more useful than lists. – MUG TheLimeLine Dec 15 '16 at 15:34

2 Answers2

0

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.

chepner
  • 497,756
  • 71
  • 530
  • 681
0

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']]  
Community
  • 1
  • 1
Jalo
  • 1,131
  • 1
  • 12
  • 28
  • High-score lists typically allow multiple scores per name, which makes a dictionary keyed on name not necessarily suitable. – chepner Dec 14 '16 at 16:47
  • @chepner you are right, but I am trying to give a solution to the OP, where it is not specified that the same user may have several scores. If that is the case, I will try to adapt the answer or delete it – Jalo Dec 14 '16 at 17:17
  • @chepner I see your point and after further testing I see that it would be useful to have more than one score to the same name but for now I am happy with Jalo's answer. – MUG TheLimeLine Dec 15 '16 at 16:26
  • @MUGTheLimeLine I added a new solution with arrays, in case you would like toget more than one score per player – Jalo Dec 15 '16 at 17:03