So I have encountered a problem with asking user for input to be exact what is the best way to ask yes/no, for example accepting y / n and why is if i == no or i == c_n:
not working? What are other mistakes or bad practices that I'm doing here?
i = input('yes/no: ')
success = "Success"
exit = "EXIT"
error = 'ERROR'
yes = 'yes'
c_y = 'y'
c_n = 'n'
no = 'no'
if i.lower().strip() == yes:
i = input('Continue: ').lower().strip()
if i == yes or i == c_y:
print('{}'.format(success))
if i == no or i == c_n:
print('{}'.format(exit))
else:
print('{}'.format(error))
Solution to my problem:
success = "Success"
exit = "EXIT"
error = 'ERROR'
yesAnswers = ['yes', 'y', 'sure!', ''];
noAnswers = ['no', 'n', 'nope']
answer = input('Yes/No or Enter: ').lower().strip()
if answer in yesAnswers:
print(success)
elif answer in noAnswers:
print(exit)
else:
print(error)
Full code:
class characters:
def __init__(self, title, character_name, power_score, biography):
self.title = title
self.character_name = character_name
self.power_score = '| ' + 'Power score - ' + power_score + ' -\n'
self.biography = biography
def title_name(self):
print('{} {}'.format(self.title,self.character_name))
def characters_data(self):
print('{} {} {} {}'.format(self.title, self.character_name, self.power_score, self.biography))
B_Cider = characters('Barbarian', 'Cider', '4854', 'Not much is known about this character')
L_Cido = characters('Lord', 'Cido', '7910', 'Not much is known about this character' )
# Y(Height) of ascii-art
z = 12
for x in range(z):
print("-" * (z-x) + "*" * x + " " * x + "-" * (z-x))
# ...............
answer = input('Are you ready to play? (Yes/No or Enter) : ').lower().strip()
first_selection = "Do you want to be a Hero? (Yes/No or Enter) : "
not_Ahero = "\nYou have selected not to be a hero\n____\nYour characters profile:"
Ahero = "\nYou have selected to be a hero\n____\nYour characters profile:"
error = 'ERROR'
yesAnswers = {'yes', 'y', 'sure!', 'yea', 'yeah', 'ye', 'si', ''}
noAnswers = {'no', 'n', 'nope', 'nah', 'not'}
if answer in yesAnswers:
answer = input(first_selection).lower().strip()
if answer in yesAnswers:
print(Ahero)
print(characters.characters_data(B_Cider))
if answer in noAnswers:
print(not_Ahero)
print(characters.characters_data(L_Cido))
else:
print(error)
-
2\$\begingroup\$ Does this exist as part of a larger program? If so, please show the full source. \$\endgroup\$Reinderien– Reinderien2021年03月21日 16:34:58 +00:00Commented Mar 21, 2021 at 16:34
-
\$\begingroup\$ Updated post with full source. \$\endgroup\$HTTP402– HTTP4022021年03月21日 21:45:17 +00:00Commented Mar 21, 2021 at 21:45
-
\$\begingroup\$ Off-topic, but uh. There's no such thing as an HTML402. Maybe you meant an HTTP 402. \$\endgroup\$Reinderien– Reinderien2021年03月22日 20:00:15 +00:00Commented Mar 22, 2021 at 20:00
-
1\$\begingroup\$ Yes and yes - HTTP Status Code 402 would make more sense \$\endgroup\$HTTP402– HTTP4022021年03月22日 20:02:45 +00:00Commented Mar 22, 2021 at 20:02
2 Answers 2
characters
should be namedCharacter
- Add some type hints
- Use f-strings
- Use
int
orfloat
for power score, notstr
- Use a
@property
where appropriate - As-is, there isn't a lot of advantage to separating your prompt strings into variables
- For the data method, don't force a
print
- just return a string and print at the outer level - Add a
main
- Square brackets around an input choice implies that it is the default to be selected on 'enter'
- Simplify your yes/no check to only care about the first letter; anything more complicated isn't all that useful
- Add an input validation loop
Suggested:
class Character:
def __init__(
self,
title: str,
name: str,
power_score: int,
biography: str = 'Not much is known about this character',
):
self.title = title
self.name = name
self.power_score = power_score
self.biography = biography
@property
def full_name(self) -> str:
return f'{self.title} {self.name}'
@property
def data(self) -> str:
return (
f'{self.title} {self.name} | Power score - {self.power_score} -\n'
f'{self.biography}'
)
def ascii_art():
# Y(Height) of ascii-art
z = 12
for x in range(z):
hyphens = "-" * (z-x)
print(hyphens + "*" * x + " " * x + hyphens)
def input_yesno(prompt: str) -> bool:
full_prompt = f'{prompt} ([Yes]/No): '
while True:
answer = input(full_prompt).strip()
if answer == '':
return True
answer = answer[0].lower()
if answer == 'y':
return True
if answer == 'n':
return False
print('ERROR')
def main():
ascii_art()
if not input_yesno('Are you ready to play'):
return
is_hero = input_yesno('Do you want to be a Hero')
print('\nYou have selected', end=' ')
if is_hero:
print('to be a hero')
character = Character('Barbarian', 'Cider', 4854)
else:
print('not to be a hero')
character = Character('Lord', 'Cido', 7910)
print("\nYour character's profile:")
print(character.data)
if __name__ == '__main__':
main()
Your updated code looks way cleaner already. Your membership tests answer in yesAnswers
/ answer in noAnswers
are obviously not performance critical here. But in general (especially on large datasets) it's preferrable to use sets for membership tests since they can provide membership information in constant instead of linear time.
Examples:
yesAnswers = {'yes', 'y', 'sure!', ''}
or
noAnswers = set('no', 'n', 'nope')