6
\$\begingroup\$

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)
asked Mar 21, 2021 at 9:56
\$\endgroup\$
4
  • 2
    \$\begingroup\$ Does this exist as part of a larger program? If so, please show the full source. \$\endgroup\$ Commented Mar 21, 2021 at 16:34
  • \$\begingroup\$ Updated post with full source. \$\endgroup\$ Commented 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\$ Commented Mar 22, 2021 at 20:00
  • 1
    \$\begingroup\$ Yes and yes - HTTP Status Code 402 would make more sense \$\endgroup\$ Commented Mar 22, 2021 at 20:02

2 Answers 2

4
\$\begingroup\$
  • characters should be named Character
  • Add some type hints
  • Use f-strings
  • Use int or float for power score, not str
  • 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()
answered Mar 22, 2021 at 15:07
\$\endgroup\$
2
\$\begingroup\$

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')
Mast
13.8k12 gold badges56 silver badges127 bronze badges
answered Mar 21, 2021 at 16:19
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.