-2

I am trying to do a Reddit challenge but it seems to have gotten stuck on an if statement that plays even when false.

Screen shot of it happening

type1 = input()
type2 = input()
if type1[:3] == 'nor':
    if type2[:3] == 'nor'or'fir'or'wat'or'ele'or'gra'or'ice'or'fig'or'poi'or'gro'or'fly'or'psy'or'bug':
        print('Normal 100% Damage')
    elif type2[:3] == 'roc' or 'ste':
        print('Not very effective 50% Damage')
    elif type2[:3] == 'gho':
        print('No effect 0% Damage')
    else:
        print('Not a valid type')
clemens
  • 15,334
  • 11
  • 41
  • 58
David
  • 1
  • 2
  • 3
    Because the if-statement isn't false, and can never be false. A non-empty string is parsed as `true`, the items after `type2[:3] == 'nor'` don't assume you are comparing to `type2[:3]`. Instead it's parsing the strings as conditionals. See [this question](https://stackoverflow.com/questions/15112125/how-do-i-test-multiple-variables-against-a-value) to ways to compare one item against multiple values in a if-statement. – Spencer Wieczorek Nov 26 '17 at 06:57
  • Sigh... another of these... this is a woefully common mistake. Please carefully read the docs on how these operators work. – cs95 Nov 26 '17 at 07:31

2 Answers2

2

This is a common mistake:

>>> value = 'maybe'
>>> print(bool(value == 'yes' or 'no'))
True

It makes sense if you break it down:

>>> print(bool(value == 'yes') or bool('no'))
True
>>> print(bool('no'))
True

What you meant to do is this:

>>> print(value in ['yes', 'no'])
False

Which will give the expected output.

Sebastian Mendez
  • 2,776
  • 13
  • 25
  • I have tried implementing what you have said but now it simply skips to the else statement. I replace or with , and placed them all in parentheses. Example: ('nor','fir',etc.) – David Nov 26 '17 at 07:23
  • [You must've done it wrong](https://tio.run/##hY/BDoIwDIbvPEUvZpB4AIwXEm6efQHjYWIZTea2jIHh6acrHkwksZcv6998Xd0SBmsOMYbFYQUtkHFTyIssveuvN/XAI5fmcIW2BWGsF00G7/pENUdkIOdsD6InxlOGBNSYoLxMoA7XEZXgLK2Z5aZeuDkybpMSxboplfNkQi7O1j@khqosd3CSD6lQFDyD@vc/3nbJNAbcNAWY0S@AfY9doBnh@Eea7leDFRuujwV@DSNurpYwS013tosiRsOHZW@8AA). Note that this probably isn't the best way to achieve what I think you're doing for. A data structure such as a nested dictionary would be better for checking the effectiveness of an attack given an attack type and defense type. – Sebastian Mendez Nov 26 '17 at 07:34
  • I see now, Thanks. I have heard of dictionarys in python but have never gotten around to learning more about it. I know it uses these { }. Ill be sure to learn more about them. – David Nov 26 '17 at 07:39
1

First problem I see with your code is that, like @Sebastian said that what you did was a common mistake, my solution is doing it like this :

element_list = [
'nor','fir','wat',
'ele','gra','ice',
'fig','poi','gro',
'fly','psy','bug',
'roc', 'ste'
]

if type2[:3] in element_list:
    print('Normal 100% Damage')
elif type2[:3] in element_list:
    print('Not very effective 50% Damage')
elif type2[:3] in element_list:
    print('No effect 0% Damage')
else:
    print('Not a valid type')

This works because the type2 variable checks if that particular string is in the list or not. And it will output differently depending on the input that is given.

Next time you are doing this, please remember that :

if a == b or a == c : is not if a == b or c :

Abhishta Gatya
  • 783
  • 1
  • 13
  • 31