patternpythonMajor
Spin-the-bottle-like game
Viewed 0 times
thebottlespinlikegame
Problem
I've started coding about 3 weeks ago, just for fun and maybe practical uses later. My GF dared me to make a PGM that would replace this dice game where you roll two dice, one with body parts and one with actions, then resulting in stuff like 'kiss, lips'.
All I know is off of YouTube and sites such as Stack Overflow. I would appreciate if I could get tips and constructive criticism on how to code more efficient, clear, correct and maybe more 'pythonic'.
A bunch of notes are in there to clarify what I'm doing. As far as I've tested it is working correctly. As you will see there is a load/save function intended to store the game data to a text file.
```
def enterplayers():
# Set players for the game
global player1
player1 = input('Enter player 1 name: ')
global player2
player2 = input('Enter player 2 name: ')
global playerlist
playerlist = [player1, player2]
global player
player = cycle(playerlist)
def enteractions():
# Add actions to existing (or empty) list
print("Add ACTIONS and enter 'q' when done")
while True:
nextitem = input("Add: ")
if nextitem == 'q':
break
elif nextitem == '':
continue
else:
nextitem = nextitem.lower()
if ' ' in nextitem:
nextitem = nextitem.replace(' ', '_')
actionlist.append(nextitem)
def enterbp():
# Add body parts to existing (or empty) list
print("Add BODY PARTS and enter 'q' when done")
while True:
nextitem = input("Add: ")
if nextitem == 'q':
break
elif nextitem == '':
continue
else:
nextitem = nextitem.lower()
if ' ' in nextitem:
nextitem = nextitem.replace(' ', '_')
bplist.append(nextitem)
def loaddata():
#empty them out in case something there
global bplist
bplist = []
global actionlist
actionlist = []
#Load each one in its
All I know is off of YouTube and sites such as Stack Overflow. I would appreciate if I could get tips and constructive criticism on how to code more efficient, clear, correct and maybe more 'pythonic'.
A bunch of notes are in there to clarify what I'm doing. As far as I've tested it is working correctly. As you will see there is a load/save function intended to store the game data to a text file.
```
def enterplayers():
# Set players for the game
global player1
player1 = input('Enter player 1 name: ')
global player2
player2 = input('Enter player 2 name: ')
global playerlist
playerlist = [player1, player2]
global player
player = cycle(playerlist)
def enteractions():
# Add actions to existing (or empty) list
print("Add ACTIONS and enter 'q' when done")
while True:
nextitem = input("Add: ")
if nextitem == 'q':
break
elif nextitem == '':
continue
else:
nextitem = nextitem.lower()
if ' ' in nextitem:
nextitem = nextitem.replace(' ', '_')
actionlist.append(nextitem)
def enterbp():
# Add body parts to existing (or empty) list
print("Add BODY PARTS and enter 'q' when done")
while True:
nextitem = input("Add: ")
if nextitem == 'q':
break
elif nextitem == '':
continue
else:
nextitem = nextitem.lower()
if ' ' in nextitem:
nextitem = nextitem.replace(' ', '_')
bplist.append(nextitem)
def loaddata():
#empty them out in case something there
global bplist
bplist = []
global actionlist
actionlist = []
#Load each one in its
Solution
First off, welcome to programming and Python. They are both awesome!
Ok, with this being your first foray into coding, instead of giving specific code improvements, I will give some high-level recommendations and then let you use them as you will.
Style
Python has an official style guide called PEP8 that defines the preferred way to style your code. It touches on variable naming conventions, proper white space, flow of code, etc. I strongly advise taking a look and trying to make your code fit what it says.
Classes
This program description is basically built for object-oriented programming (OOP). Classes are very easy to create in Python and provide simple ways to access similar data. Below is a skeleton
From this point, using a
Much of your code can be pulled into classes (
Strings
You do a lot of print statements. That is fine. However, you can take out about 95% of them if you use triple-quote syntax. Essentially by using
to this:
Also, you have some statments that use strings like this:
A simple way of writing this is using the
This way we don't have to worry about all of the string concatenation that is happening in the old statement.
Miscellaneous Thoughts
Here are some random improvements I can see:
-
There is no need to check for a substring in a string before replacing. If there are none,
-
'Infinite' Loops
While I love
This could be simplified to:
-
Using
There are other things, but I think this i
Ok, with this being your first foray into coding, instead of giving specific code improvements, I will give some high-level recommendations and then let you use them as you will.
Style
Python has an official style guide called PEP8 that defines the preferred way to style your code. It touches on variable naming conventions, proper white space, flow of code, etc. I strongly advise taking a look and trying to make your code fit what it says.
Classes
This program description is basically built for object-oriented programming (OOP). Classes are very easy to create in Python and provide simple ways to access similar data. Below is a skeleton
Die class that can be used to represent one of your dice in your game:class Die():
def __init__(self, options=[]):
# This is the function that is called when a new `Die` instance
# is created. The `options` parameter is optional (denoted with the `=`).
self.options = options
def __str__(self):
# This 'magic method' is called when you used the `print` function.
return ', '.join(self.options)
def add_options(self, options):
# Adds multiple options. HINT: use the following method.
def add_option(self, option):
# Add an option to the current list
def roll(self):
# Return one of its options based on a random numberFrom this point, using a
Die is as easy as:>>>body_parts = Die(['arm', 'leg', 'nose'])
>>>body_parts.add_options(['head', 'foot'])
>>>body_parts.roll()
'leg'
>>>print(body_parts)
arm, leg, nose, head, footMuch of your code can be pulled into classes (
Die as above, Game, Player, etc.). This is evident by how much you use the global keyword. Having to use a variable in many places implies a relationship between the variable and the functions it is used in. This relationship is one of the main ideas behind OOP.Strings
You do a lot of print statements. That is fine. However, you can take out about 95% of them if you use triple-quote syntax. Essentially by using
'''Some text''' Python keeps the structure of the string as it looks in the code. So your menu function can be scaled down from this:def menu():
print()
print('- - - - - - - - - - - -')
print(' MAIN MENU')
print()
print('1. Start game')
print()
print('2. Enter player names')
print('3. Add actions')
print('4. Add body parts')
print()
print('6. Load data')
print('7. Save data')
print()
print('8. Print instructions')
print('9. Quit ')
print('- - - - - - - - - - - -')
print()to this:
def menu():
print('''
- - - - - - - - - - - -
MAIN MENU
1. Start game
2. Enter player names
3. Add actions
4. Add body parts
5. Load data
6. Save data
7. Print instructions
8. Quit
- - - - - - - - - - - -
''')Also, you have some statments that use strings like this:
file.write('player1: ' + player1 + '\n')A simple way of writing this is using the
format() function provided by Python:file.write('player1: {}\n'.format(player1))This way we don't have to worry about all of the string concatenation that is happening in the old statement.
Miscellaneous Thoughts
Here are some random improvements I can see:
-
replace()There is no need to check for a substring in a string before replacing. If there are none,
replace() will handle it gracefully:>>>'Hello Planet!'.replace('Planet', 'World')
Hello World!
>>>'Hello World!'.replace('Planet', 'World')
Hello World!-
'Infinite' Loops
While I love
while True loops in the right circumstances, you do not need most (if not all) of them. Take you while-loop in enterbp:def enterbp():
# Add body parts to existing (or empty) list
print("Add BODY PARTS and enter 'q' when done")
while True:
nextitem = input("Add: ")
if nextitem == 'q':
break
elif nextitem == '':
continue
else:
nextitem = nextitem.lower()
if ' ' in nextitem:
nextitem = nextitem.replace(' ', '_')
bplist.append(nextitem)This could be simplified to:
def enterbp():
# Add body parts to existing (or empty) list
print("Add BODY PARTS and enter 'q' when done")
nextitem = input("Add: ")
while nextitem != 'q':
if nextitem == '':
continue
bplist.append(nextitem.lower().replace(' ', '_'))
nextitem = input("Add: ")-
Using
listslists are awesome. You could simply use a list to implement your menu:# This is a list of functions.
menu_options = [play, enterplayers, enteractions, enterbp,
loaddata, savedata, instructions, quit]
choice = input('What do you choose: ')
# Finds the correct function, then calls it
menu_options[choice-1]()There are other things, but I think this i
Code Snippets
class Die():
def __init__(self, options=[]):
# This is the function that is called when a new `Die` instance
# is created. The `options` parameter is optional (denoted with the `=`).
self.options = options
def __str__(self):
# This 'magic method' is called when you used the `print` function.
return ', '.join(self.options)
def add_options(self, options):
# Adds multiple options. HINT: use the following method.
def add_option(self, option):
# Add an option to the current list
def roll(self):
# Return one of its options based on a random number>>>body_parts = Die(['arm', 'leg', 'nose'])
>>>body_parts.add_options(['head', 'foot'])
>>>body_parts.roll()
'leg'
>>>print(body_parts)
arm, leg, nose, head, footdef menu():
print()
print('- - - - - - - - - - - -')
print(' MAIN MENU')
print()
print('1. Start game')
print()
print('2. Enter player names')
print('3. Add actions')
print('4. Add body parts')
print()
print('6. Load data')
print('7. Save data')
print()
print('8. Print instructions')
print('9. Quit ')
print('- - - - - - - - - - - -')
print()def menu():
print('''
- - - - - - - - - - - -
MAIN MENU
1. Start game
2. Enter player names
3. Add actions
4. Add body parts
5. Load data
6. Save data
7. Print instructions
8. Quit
- - - - - - - - - - - -
''')file.write('player1: ' + player1 + '\n')Context
StackExchange Code Review Q#51272, answer score: 21
Revisions (0)
No revisions yet.