I see that you have some error handling for int(input(...))
. I would change it, however. Let's say that the user types a valid number of PC's, but does not type a valid player initiative. That would trigger a ValueError, and your except
block would ask again how many PC's. Why should it restart the whole process for one little mistake? You should have different try
blocks for each of those. Also, a try
block should include only the code that you expect might throw an error. If some other code throws an error, you want to know about it.
For the first use of int(input(...))
, I would just take it out completely. Why should the user need to specify how many PC's? Why not just keep going until he runs out and then hit Enter on a blank line? That can be done quite simply with iter()
. Usually, iter()
is given an iterable, but if it is given two arguments, the first argument is a callable (usually a function) that returns a value. (In our case, we use lambda: input(...)
). The second argument is the stopping point. iter()
will keep calling that function and yielding the result until it returns the second argument. Therefore, we give it ''
, and we get all of the user's inputs until he types nothing in a line.
The second use of int(input(...))
is when you are retrieving the player initiative. It should have its own try
-except
block to make sure the input is an integer. I would then put that block inside of its own while
loop so that the program keeps asking until it gets a valid answer.
Instead of a chain of string concatenations, use string formatting:
player_initiative = input('What is {} initiative? '.format(player_name))
and
print('{}: {}'.format(key, ', '.join(initiative_tracking[key])))
A loop is called that because it loops. You don't need to tell it to keep looping. It will keep looping until it is told to stop. Sometimes it is stops because a condition is not met, but sometimes it stops because it encounters a break
. You should use continue
only if you want to skip the code beneath and jump straight to the beginning of the loop. It really doesn't make sense to put continue
at the end of the loop.
The argument that is given to sorted()
has only one requirement: that it is iterable. To test if a type of object is iterable, go into a Python shell and create an instance of it. Then, do for item in my_object: print(item)
. If there is an error, your object is not iterable. Otherwise, you will see what happens when iterates. For a dictionary, you get all of the keys. Therefore, sorted(initiative_tracking.keys(), reverse=True)
can be simplified to sorted(initiative_tracking, reverse=True)
.
Full code:
print('Welcome to Initiative Tracker!')
initiative_tracking = {}
for player_name in iter(lambda: input("What is the player's name? "), ''):
player_initiative = input('What is {} initiative? '.format(player_name))
while True:
try:
player_initiative = int(player_initiative)
break
except ValueError:
player_initiative = input('Please enter an integer: ')
if player_initiative in initiative_tracking:
initiative_tracking[player_initiative].append(player_name)
else:
initiative_tracking[player_initiative] = [player_name]
print('\nYour initiative order is: ')
for key in sorted(initiative_tracking, reverse=True):
print(str(key) + ': ' + ', '.join(initiative_tracking[key]))
else
block is not indented correctly. Would you mind fixing or clarifying? The easy way to format the code is just paste it in, highlight it, and click the{}
button or hit Ctrl-k. \$\endgroup\$