There are plenty plenty of questions questions about these operators these operators. And the documentation for them is quite bare.
There are plenty of questions about these operators. And the documentation for them is quite bare.
There are plenty of questions about these operators. And the documentation for them is quite bare.
- 44.4k
- 7
- 80
- 157
#Format#str.format
I personally love the str.format()
function and would encourage you look into it. It allows you to writeOver the structureyears of the outputPython, there has mostly been two ways to join stings and re-usevariables. And now we have the inputnew format way. Also, you don't seem to use type conversion at all and so I
We will cover that slightlyuse the following constants in the examples.
# Currently you output with.
print("\nYou used Mega Punch. It dealt ", player_move, " damage.")
>>> # This is fine, however being able to define a layout for the output is nicer.
>>> move_str = "\n{} used {}. It dealt {} damage."
>>> # Now we can use the string to display information
>>> move_str.format('You', 'Mega Punch', 50)
'\nYou used Mega Punch. It dealt 50 damage.'
>>> # However, if you wanted to make a new string for criticals.
>>> crit_strb = "\n{0} used {1}. It dealt {2} damage. That was a critical hit! Of {2}."
>>> crit_str.format('You', 'Mega Punch', 50)
'\nYou used Mega Punch. It dealt 50 damage. That was a critical hit! Of 50.'
>>> # Lets say that you add decimals. But the number is 20.333333333333333,
>>> # and that looks horrible when printed.
>>> move_strc = "\n{} used {}. It dealt {:.2f} damage."
>>> move_str.format('You', 'Mega Punch', 20.3333333333333)
'\nYou used Mega Punch. It dealt 20.33 damage.'
>>> # I didn't know about this until now, however you can do things like the
>>> # following. Which makes console layouts much easier.
>>> '{}{:->15}'.format('Pika', '23/100')
'Pika---------23/100'
>>> '{}{:>15}'.format('Pika', '23/100')
'Pika 23/100'50
I personally find it to be one of the best things about Python.##The first way
#Don't use 'Arbitrary Argument lists' (yet)
>>> a + ' used ' + b + '. It dealt ' + str(c) + ' damage.'
'You used Mega Punch. It dealt 50 damage.'
Also, I would encourage youThis is annoying to look at Arbitrary Argument lists type, and is unsafe if you wanta or b change to an int. I didn't use the print_lines,
function aboveoperator, as it will make a tuple if you assign it to a variable.
##The second way
>>> def print_lines(*lines):print('\n'.join([line for line in lines]))
# There are two more consise ways to write it.
# The first without a list comp.
>>>'%s defused print_lines(*lines):print('\n'%s.join(lines))
>>> print_lines('hello', 'world')
hello
world
# The second, using the print function!It Nodealt more%s 2damage.x print messes!
>>>' def% print_lines(*lines):print(*linesa, sep='\n')
>>> print_lines('hello'b, 'world'c)
hello
world
# However the problem with these, is they require you to'You inputused themMega manuallyPunch.
# Or via messing around withIt thedealt `*`50 operatordamage.
# Here is a better alternate:
>>> print(['hello', 'world'], sep='\n')
hello
world'
WhyThis is it better? Who wants to havequite a static program? No-one. Withlot like the new final
.format method you can pass a list of strings, as shown, and know that it will work. You can also change the list at a later date, without having to restartHowever there are arguments against it, editas stated in the .py and then rundocumentation for it again. Or you can use a weird tuple un-tuple operator:
The formatting operations described here exhibit a variety of quirks that lead to a number of common errors (such as failing to display tuples and dictionaries correctly). Using the newer str.format() interface helps avoid these errors, and also provides a generally more powerful, flexible and extensible approach to formatting text.
##The str.format way
>>> def'{} print_linesused {}. It dealt {} damage.'.format(*linesa, b, c):print
'You used Mega Punch. It dealt 50 damage.'
>>> '{1} used {0}. It dealt {2} damage.'.format(*linesa, sep='\n'b, c)
'Mega Punch used You. It dealt 50 damage.'
>>> print_lines'{0} used {1}. {0} dealt {2} damage.'.format(*['hello'a, 'world']b, c)
'You used Mega Punch. You dealt 50 damage.'
#Every console app that makes a UI needs this!
>>> '{}{:>15}'.format('Pika', '23/100')
'Pika 23/100'
And ifThis is just to show a few ways to use the str.format method. It also allows you really wantto change the print_lines optiontype of no []
:inputted variable, the amount of decimal places shown and manipulate lists. But most of all it just rocks!
#About the *
and **
operators.
There are plenty of questions about these operators . And the documentation for them is quite bare.
>>> printa = random.randint(1, 9)
>>> a
9
>>> a
9
# It didn't "Hello."change? That's 'cause you are not calling the function,
# you're just asking "Goodbye"for the same output again. So if we could...
>>> l = [1, 9]
>>> random.randint(l)
TypeError: randint() takes exactly 3 sep='\n'arguments (2 given)
# And this is why we have the `*` operator
>>> random.randint(*l)
4
>>> random.randint(*l)
2
As I don't want to just be bashing on someone-else's code,But I would recommend not using it. As you will add one more pointcome up with things like:
def print_lines(*lines):
print("\n".join([line for line in lines]))
# This is confusing. And `print` is a function in python3!
# If we ignore how good print is we get
def print_lines(*lines):
print('\n'.join(lines))
# But how do we use it?
print_lines('hello', 'world')
print_lines(*['hello', 'world'])
# "There should be one-- and preferably only one --obvious way to do it."
print('hello', 'world', sep='\n')
print(['hello', 'world'], sep='\n')
Print is a function now! And the quote is from The Zen of Python.
I use this later in the Class example, and I bashed the other persons use of it. They allow you to reduce the amount of code you write. And you can simply change them so that they are generators . Generators are good for large amounts of data, as they only put the information into memory when needed.
# You have a list of strings, and you want them to be all lowercase.
>>> lst = [ ... ]
>>> lst2 = []
>>> for i in lst:
lst2.append(i.lower())
# That's a lot of writing for such a simple task.
# And so we will use list comprehension.
>>> lst3 = [i.lower() for i in lst]
# And they are the same.
>>> lst2 == lst3
True
moves={'Punch': [18, 25],
'Mega Punch': [10, 35],
'Heal': [-25, -20]
}
moves_list=list(moves)
moves_list_lower=[move.lower() for move in moves_list]
move_names='\n'+'\n'.join(
"{0}. {1} (Deal damage between '{2[0]}' - '{2[1]}')".format(
i,
move,
moves[move]
)
for i, move in enumerate(moves_list)
)
class Pokemon:
def __init__(self, title):
self.title = title
def select_move(self)
move = input(move_names + '\n> ').lower()
try:
return moves_list[int(move)]
except ValueError:
return moves_list[moves_list_lower.index(move)]
except IndexError:
print('That is not a valid move. Please try again.')
def use_move(self, other, move):
# 20% of missing
if random.randint(1,5):
print('{} missed!'.format(self.title.capitalize()))
else:
# I could wrap the function,
# however thought mightWorks as well do the easyshown thingearlier.
magnitude = random.randint(*moves[move])
if moves[move][0] < 0:
# A simple self.health += magnitude
self.heal(magnitude)
desc = 'healed for {} health.'
else:
# A simple self.health -= magnitude
other.deal(magnitude)
desc = 'dealt {} damage.'
print(('{} used {}. It' + desc).format(
self.title.capitalize(),
move,
magnitude
))
I have made it so if you want you can add more moves, with little extra effort, like adding more if statements. you add to the moves dictionary. This shows why .format is so helpful, and why you don't really want to use static functions.
I didn't re-implement all of it, as I would use things that an up and coming programmer wouldn't know, such as inheritance to change how select_move
works for a computer, and my favourite thing to stop writing lots of self.title = title
stuff. self.__dict__.update(kwargs)
. And I would have made a really long answer.
The bits in global name-space are to make all the information about the moves.
- We keep your simple dictionary of moves, as it stores all the information we need.
moves_list
is a a copy of all the keys of the dictionary, so that we can index easier.moves_list_lower
is a lowercase copy ofmoves_list
. This is so we can use it to see if the person entered a valid move.move_names
will output roughly the same as the print statement at the start of each players turn. However it will change every time you load the game, due to how dictionary's work. You can sortmoves_list
so that it becomes fixed if you wanted to 'fix' this. It also outputs healing as negative damage. I'm sure you can figure a way to fix that.
I also make useAll of list comprehensionsit should however be wrapped in a [i forif i__name__ in== lst]"__main__":
to make a kinda bad moves list. And so you don't have to re-write a lot of things when adding another moveas @EthanBierlein said.
I left out some key points in this program, as it's just meant to show you how you could implement it. And allows you to do thinking on your own. I personally hate, 'learn classes, here's how
__init__
works'.I also used a try except statement. I don't know if it's fully functional, but it shows you how you can remove some clutter. For more information on these 'handling exceptions '.
If I were to continue making this program I would personally use inheritance and use method overriding to make it so the computer has a diffrent way to
select_move
.If you want to know what the best way to style Python there is PEP8 and PEP257 .
Also, I didn't notice at first, however, moves = {"Punch": random.randint(18, 25) ...
. This isanswer was re-written so that it has a static variablebetter layout, and so I changed it to an arraypresentation of information, rather than being a mess. I re-wrote this and passhope that it is as ifgood or better than the previous version. If not, revert it were arguments as said above. -Author.
#Format
I personally love the str.format()
function and would encourage you look into it. It allows you to write the structure of the output, and re-use the input. Also, you don't seem to use type conversion at all and so I will cover that slightly.
# Currently you output with.
print("\nYou used Mega Punch. It dealt ", player_move, " damage.")
>>> # This is fine, however being able to define a layout for the output is nicer.
>>> move_str = "\n{} used {}. It dealt {} damage."
>>> # Now we can use the string to display information
>>> move_str.format('You', 'Mega Punch', 50)
'\nYou used Mega Punch. It dealt 50 damage.'
>>> # However, if you wanted to make a new string for criticals.
>>> crit_str = "\n{0} used {1}. It dealt {2} damage. That was a critical hit! Of {2}."
>>> crit_str.format('You', 'Mega Punch', 50)
'\nYou used Mega Punch. It dealt 50 damage. That was a critical hit! Of 50.'
>>> # Lets say that you add decimals. But the number is 20.333333333333333,
>>> # and that looks horrible when printed.
>>> move_str = "\n{} used {}. It dealt {:.2f} damage."
>>> move_str.format('You', 'Mega Punch', 20.3333333333333)
'\nYou used Mega Punch. It dealt 20.33 damage.'
>>> # I didn't know about this until now, however you can do things like the
>>> # following. Which makes console layouts much easier.
>>> '{}{:->15}'.format('Pika', '23/100')
'Pika---------23/100'
>>> '{}{:>15}'.format('Pika', '23/100')
'Pika 23/100'
I personally find it to be one of the best things about Python.
#Don't use 'Arbitrary Argument lists' (yet)
Also, I would encourage you to look at Arbitrary Argument lists if you want to use the print_lines
function above.
>>> def print_lines(*lines):print('\n'.join([line for line in lines]))
# There are two more consise ways to write it.
# The first without a list comp.
>>> def print_lines(*lines):print('\n'.join(lines))
>>> print_lines('hello', 'world')
hello
world
# The second, using the print function! No more 2.x print messes!
>>> def print_lines(*lines):print(*lines, sep='\n')
>>> print_lines('hello', 'world')
hello
world
# However the problem with these, is they require you to input them manually.
# Or via messing around with the `*` operator.
# Here is a better alternate:
>>> print(['hello', 'world'], sep='\n')
hello
world
Why is it better? Who wants to have a static program? No-one. With the final
method you can pass a list of strings, as shown, and know that it will work. You can also change the list at a later date, without having to restart, edit the .py and then run it again. Or you can use a weird tuple un-tuple operator.
>>> def print_lines(*lines):print(*lines, sep='\n')
>>> print_lines(*['hello', 'world'])
And if you really want the print_lines option of no []
:
>>> print(
"Hello.",
"Goodbye",
sep='\n'
)
As I don't want to just be bashing on someone-else's code, I will add one more point.
moves={'Punch': [18, 25],
'Mega Punch': [10, 35],
'Heal': [-25, -20]
}
moves_list=list(moves)
moves_list_lower=[move.lower() for move in moves_list]
move_names='\n'+'\n'.join(
"{0}. {1} (Deal damage between '{2[0]}' - '{2[1]}')".format(
i,
move,
moves[move]
)
for i, move in enumerate(moves_list)
)
class Pokemon:
def __init__(self, title):
self.title = title
def select_move(self)
move = input(move_names + '\n> ').lower()
try:
return moves_list[int(move)]
except ValueError:
return moves_list[moves_list_lower.index(move)]
except IndexError:
print('That is not a valid move. Please try again.')
def use_move(self, other, move):
# 20% of missing
if random.randint(1,5):
print('{} missed!'.format(self.title.capitalize()))
else:
# I could wrap the function,
# however thought might as well do the easy thing.
magnitude = random.randint(*moves[move])
if moves[move][0] < 0:
# A simple self.health += magnitude
self.heal(magnitude)
desc = 'healed for {} health.'
else:
# A simple self.health -= magnitude
other.deal(magnitude)
desc = 'dealt {} damage.'
print(('{} used {}. It' + desc).format(
self.title.capitalize(),
move,
magnitude
))
I have made it so if you want you can add more moves, with little extra effort, like adding more if statements. you add to the moves dictionary. This shows why .format is so helpful, and why you don't really want to use static functions.
I didn't re-implement all of it, as I would use things that an up and coming programmer wouldn't know, such as inheritance to change how select_move
works for a computer, and my favourite thing to stop writing lots of self.title = title
stuff. self.__dict__.update(kwargs)
. And I would have made a really long answer.
I also make use of list comprehensions [i for i in lst]
to make a kinda bad moves list. And so you don't have to re-write a lot of things when adding another move.
Also, I didn't notice at first, however, moves = {"Punch": random.randint(18, 25) ...
. This is a static variable, and so I changed it to an array, and pass it as if it were arguments as said above.
#str.format
Over the years of Python, there has mostly been two ways to join stings and variables. And now we have the new format way.
We will use the following constants in the examples.
>>> a = 'You'
>>> b = 'Mega Punch'
>>> c = 50
##The first way
>>> a + ' used ' + b + '. It dealt ' + str(c) + ' damage.'
'You used Mega Punch. It dealt 50 damage.'
This is annoying to type, and is unsafe if a or b change to an int. I didn't use the ,
operator, as it will make a tuple if you assign it to a variable.
##The second way
>>> '%s used %s. It dealt %s damage.' % (a, b, c)
'You used Mega Punch. It dealt 50 damage.'
This is quite a lot like the new .format method. However there are arguments against it, as stated in the documentation for it:
The formatting operations described here exhibit a variety of quirks that lead to a number of common errors (such as failing to display tuples and dictionaries correctly). Using the newer str.format() interface helps avoid these errors, and also provides a generally more powerful, flexible and extensible approach to formatting text.
##The str.format way
>>> '{} used {}. It dealt {} damage.'.format(a, b, c)
'You used Mega Punch. It dealt 50 damage.'
>>> '{1} used {0}. It dealt {2} damage.'.format(a, b, c)
'Mega Punch used You. It dealt 50 damage.'
>>> '{0} used {1}. {0} dealt {2} damage.'.format(a, b, c)
'You used Mega Punch. You dealt 50 damage.'
#Every console app that makes a UI needs this!
>>> '{}{:>15}'.format('Pika', '23/100')
'Pika 23/100'
This is just to show a few ways to use the str.format method. It also allows you to change the type of inputted variable, the amount of decimal places shown and manipulate lists. But most of all it just rocks!
#About the *
and **
operators.
There are plenty of questions about these operators . And the documentation for them is quite bare.
>>> a = random.randint(1, 9)
>>> a
9
>>> a
9
# It didn't change? That's 'cause you are not calling the function,
# you're just asking for the same output again. So if we could...
>>> l = [1, 9]
>>> random.randint(l)
TypeError: randint() takes exactly 3 arguments (2 given)
# And this is why we have the `*` operator
>>> random.randint(*l)
4
>>> random.randint(*l)
2
But I would recommend not using it. As you will come up with things like:
def print_lines(*lines):
print("\n".join([line for line in lines]))
# This is confusing. And `print` is a function in python3!
# If we ignore how good print is we get
def print_lines(*lines):
print('\n'.join(lines))
# But how do we use it?
print_lines('hello', 'world')
print_lines(*['hello', 'world'])
# "There should be one-- and preferably only one --obvious way to do it."
print('hello', 'world', sep='\n')
print(['hello', 'world'], sep='\n')
Print is a function now! And the quote is from The Zen of Python.
I use this later in the Class example, and I bashed the other persons use of it. They allow you to reduce the amount of code you write. And you can simply change them so that they are generators . Generators are good for large amounts of data, as they only put the information into memory when needed.
# You have a list of strings, and you want them to be all lowercase.
>>> lst = [ ... ]
>>> lst2 = []
>>> for i in lst:
lst2.append(i.lower())
# That's a lot of writing for such a simple task.
# And so we will use list comprehension.
>>> lst3 = [i.lower() for i in lst]
# And they are the same.
>>> lst2 == lst3
True
moves={'Punch': [18, 25],
'Mega Punch': [10, 35],
'Heal': [-25, -20]
}
moves_list=list(moves)
moves_list_lower=[move.lower() for move in moves_list]
move_names='\n'+'\n'.join(
"{0}. {1} (Deal damage between '{2[0]}' - '{2[1]}')".format(
i,
move,
moves[move]
)
for i, move in enumerate(moves_list)
)
class Pokemon:
def __init__(self, title):
self.title = title
def select_move(self)
move = input(move_names + '\n> ').lower()
try:
return moves_list[int(move)]
except ValueError:
return moves_list[moves_list_lower.index(move)]
except IndexError:
print('That is not a valid move. Please try again.')
def use_move(self, other, move):
# 20% of missing
if random.randint(1,5):
print('{} missed!'.format(self.title.capitalize()))
else:
# Works as shown earlier.
magnitude = random.randint(*moves[move])
if moves[move][0] < 0:
# A simple self.health += magnitude
self.heal(magnitude)
desc = 'healed for {} health.'
else:
# A simple self.health -= magnitude
other.deal(magnitude)
desc = 'dealt {} damage.'
print(('{} used {}. It' + desc).format(
self.title.capitalize(),
move,
magnitude
))
The bits in global name-space are to make all the information about the moves.
- We keep your simple dictionary of moves, as it stores all the information we need.
moves_list
is a a copy of all the keys of the dictionary, so that we can index easier.moves_list_lower
is a lowercase copy ofmoves_list
. This is so we can use it to see if the person entered a valid move.move_names
will output roughly the same as the print statement at the start of each players turn. However it will change every time you load the game, due to how dictionary's work. You can sortmoves_list
so that it becomes fixed if you wanted to 'fix' this. It also outputs healing as negative damage. I'm sure you can figure a way to fix that.
All of it should however be wrapped in a if __name__ == "__main__":
as @EthanBierlein said.
I left out some key points in this program, as it's just meant to show you how you could implement it. And allows you to do thinking on your own. I personally hate, 'learn classes, here's how
__init__
works'.I also used a try except statement. I don't know if it's fully functional, but it shows you how you can remove some clutter. For more information on these 'handling exceptions '.
If I were to continue making this program I would personally use inheritance and use method overriding to make it so the computer has a diffrent way to
select_move
.If you want to know what the best way to style Python there is PEP8 and PEP257 .
This answer was re-written so that it has a better layout, and presentation of information, rather than being a mess. I re-wrote this and hope that it is as good or better than the previous version. If not, revert it. -Author.
#format#Format
I personally love the str.format()str.format()
function. And and would encourage you look into it.
It allows you to write the structure of the output, and re-use the input. Also Also, you don't seem to use type conversion at all and so I will cover that slightly.
I personally find it to be one of the best things about pythonPython.
#Don't use 'Arbitrary Argument lists' (yet) Also
Also, I would encourage lookingyou to look at Arbitrary Argument lists if you want to use the print_linesprint_lines
function above. (I would have made a comment, but I need 50 rep.)
Why is it better? Who wants to have a static program? No-one.
With With the finalfinal
method you can pass a list of strings, as shown, and know that it will work. You can also change the list at a later date, without having to restart, edit the .py and then run it again.
Or Or you can use a weird tuple un-tuple operator.
And if you really want the print_lines option of no []
:
As I don't want to just be bashing on someone-else's code., I will add one more point.
#Classes You
You want to have code re-use. And that is the brain dead response for what classes are! The The main function of your code implement misses, moves, and checks to see if one of the Pokemon have fainted. When When I was introduced to classes, I was told to use super, inheritance and a lot of things that I struggled with. And so I will give you a 'small' example of a simple way to make a class. (As you didn't use one I am assuming you don't like/understand/know them.)
I have made it so if you want you can add more moves, with little extra effort, like adding more if statements. you add to the moves dictionary. This shows why .format is so helpful, and why you don't really want to use static functions.
I didn't re-implement all of it, as I would use things that an up and coming programmer wouldn't know, such as inheritance to change how select_move
works for a computer, and my favourite thing to stop writing lots of self.title = title
stuff. self.__dict__.update(kwargs)
. And I would have made a really long answer.
I
I also make use of list comprehensions [i for i in lst]
to make a kinda bad moves list. And so you don't have to re-write a lot of things when adding another move.
Also
Also, I didn't notice at first, however, moves = {"Punch": random.randint(18, 25) ...
. This is a static variable, and so I changed it to an array, and pass it as if it were arguments as said above.
P.S. I will reform this answer to be better formatted, and have more citations. However, despite my best hopes, I will be unable to at the moment of posting, due to sleep deprivation. (Please edit for better grammar, as I am very poor at that even when fully alert.)
#format I personally love the str.format() function. And would encourage you look into it.
It allows you to write the structure of the output, and re-use the input. Also you don't seem to use type conversion at all and so I will cover that slightly.
I personally find it to be one of the best things about python.
#Don't use 'Arbitrary Argument lists' (yet) Also I would encourage looking at Arbitrary Argument lists if you want to use the print_lines function above. (I would have made a comment, but I need 50 rep.)
Why is it better? Who wants to have a static program? No-one. With the final method you can pass a list of strings, as shown, and know that it will work. You can also change the list at a later date, without having to restart, edit the .py and then run it again. Or use a weird tuple un-tuple operator.
And if you really want the print_lines option of no []
As I don't want to just be bashing on someone-else's code. I will add one more point.
#Classes You want to have code re-use. And that is the brain dead response for what classes are! The main function of your code implement misses, moves, and checks to see if one of the Pokemon have fainted. When I was introduced to classes, I was told to use super, inheritance and a lot of things that I struggled with. And so I will give you a 'small' example of a simple way to make a class. (As you didn't use one I am assuming you don't like/understand/know them.)
I have made it so if you want you can add more moves, with little extra effort, like adding more if statements. you add to the moves dictionary. This shows why .format is so helpful, and why you don't really want to use static functions.
I didn't re-implement all of it, as I would use things that an up and coming programmer wouldn't know, such as inheritance to change how select_move
works for a computer, and my favourite thing to stop writing lots of self.title = title
stuff. self.__dict__.update(kwargs)
. And I would have made a really long answer.
I also make use of list comprehensions [i for i in lst]
to make a kinda bad moves list. And so you don't have to re-write a lot of things when adding another move.
Also I didn't notice at first, however, moves = {"Punch": random.randint(18, 25) ...
. This is a static variable, and so I changed it to an array, and pass it as if it were arguments as said above.
P.S. I will reform this answer to be better formatted, and have more citations. However, despite my best hopes, I will be unable to at the moment of posting, due to sleep deprivation. (Please edit for better grammar, as I am very poor at that even when fully alert.)
#Format
I personally love the str.format()
function and would encourage you look into it. It allows you to write the structure of the output, and re-use the input. Also, you don't seem to use type conversion at all and so I will cover that slightly.
I personally find it to be one of the best things about Python.
#Don't use 'Arbitrary Argument lists' (yet)
Also, I would encourage you to look at Arbitrary Argument lists if you want to use the print_lines
function above.
Why is it better? Who wants to have a static program? No-one. With the final
method you can pass a list of strings, as shown, and know that it will work. You can also change the list at a later date, without having to restart, edit the .py and then run it again. Or you can use a weird tuple un-tuple operator.
And if you really want the print_lines option of no []
:
As I don't want to just be bashing on someone-else's code, I will add one more point.
#Classes
You want to have code re-use. And that is the brain dead response for what classes are! The main function of your code implement misses, moves, and checks to see if one of the Pokemon have fainted. When I was introduced to classes, I was told to use super, inheritance and a lot of things that I struggled with. And so I will give you a 'small' example of a simple way to make a class. (As you didn't use one I am assuming you don't like/understand/know them.)
I have made it so if you want you can add more moves, with little extra effort, like adding more if statements. you add to the moves dictionary. This shows why .format is so helpful, and why you don't really want to use static functions.
I didn't re-implement all of it, as I would use things that an up and coming programmer wouldn't know, such as inheritance to change how select_move
works for a computer, and my favourite thing to stop writing lots of self.title = title
stuff. self.__dict__.update(kwargs)
. And I would have made a really long answer.
I also make use of list comprehensions [i for i in lst]
to make a kinda bad moves list. And so you don't have to re-write a lot of things when adding another move.
Also, I didn't notice at first, however, moves = {"Punch": random.randint(18, 25) ...
. This is a static variable, and so I changed it to an array, and pass it as if it were arguments as said above.