0

I am a newbie programmer and am trying to code a program where I ask the user for a specific input like Obama, Clinton or Bush and congratulate them when they give the right answer or notify them when they give the wrong answer.

I am pretty sure I made a very simple and a dumb mistake so I would appreciate it if anyone could help me out.

def main ():

    pres = input ('Please enter the surname of a recent President of the United States: ')
    if pres == 'Bush' or 'Obama' or 'Clinton':
        print('Great job! You know your stuff!')
    else:
        print('Sorry, that was incorrect.')

main()

Thank you!

Eevee
  • 47,412
  • 11
  • 95
  • 127
AvenNova
  • 337
  • 2
  • 6
  • 16

3 Answers3

6

You have:

if pres == 'Bush' or 'Obama' or 'Clinton':

While that makes sense to a human being, Python thinks you mean this:

if (pres == 'Bush') or ('Obama') or ('Clinton'):

'Obama' and 'Clinton' are non-empty strings, so they're always true, so this whole expression is always true and it doesn't make any difference what you enter.

You need to be explicit about what you mean:

if pres == 'Bush' or pres == 'Obama' or pres == 'Clinton':

But that's a mouthful, so you can also do this, which will check whether pres is in the set of correct answers:

if pres in {'Bush', 'Obama', 'Clinton'}:
Eevee
  • 47,412
  • 11
  • 95
  • 127
  • Changing that `tuple` to a `set` would be even more ideal imo. – Slater Victoroff Jan 28 '15 at 22:54
  • i doubt it would make much difference with only three items (might even be slower!) but fair point :) – Eevee Jan 28 '15 at 22:56
  • 2
    Ran a quick timeit test and the `tuple` is totally faster for this size, though I still think the set makes more ideological sense. – Slater Victoroff Jan 28 '15 at 22:58
  • i'm going with the set just because "the set of correct answers" reads better than "the tuple of correct answers" – Eevee Jan 28 '15 at 22:59
  • Makes total sense, but also in a large oversight, `tuple` ceases to be faster if the match isn't the first entry, and at 6 entries `tuple` is slower on average by about 2x – Slater Victoroff Jan 28 '15 at 23:01
2

The best choice for check membership is using set that has O(1) so you can use the following instead your if statement :

if pres in {'Bush','Obama','Clinton'}

from python wiki :

The sets module provides classes for constructing and manipulating unordered collections of unique elements. Common uses include membership testing, removing duplicates from a sequence, and computing standard math operations on sets such as intersection, union, difference, and symmetric difference.

Mazdak
  • 105,000
  • 18
  • 159
  • 188
  • 1
    The cost of building a set for a single lookup makes this not as good as checking membership in a list or a tuple, though. – Adam Smith Jan 28 '15 at 22:55
  • 3
    O(1) ≈ O(n) when n == 3 ;) – Eevee Jan 28 '15 at 22:57
  • @AdamSmith what you mean by cost ? – Mazdak Jan 28 '15 at 22:57
  • @Eevee i add this as a general note ! ;) – Mazdak Jan 28 '15 at 22:57
  • He's building a *constant*, hence it happens in constant time. :) – mbomb007 Jan 28 '15 at 22:58
  • @KasraAD The amount of money you have to feed into the bill reader on the side of your computer before the program will run the time it takes to build the set makes the faster membership test useless. Apparently in 3.2+ this isn't true, though [see here](http://stackoverflow.com/questions/25368337/tuple-or-list-when-using-in-in-an-if-clause). Testing membership with a set is amazing if you have to test membership MULTIPLE TIMES (e.g. `if a in your_set: foo(); elif b in your_set: bar(); elif c in your_set: spam(); else: eggs()`) – Adam Smith Jan 28 '15 at 22:58
  • 1
    @AdamSmith im agree for a set with a few members its true but for sets with much members or as you say *MULTIPLE TIMES* its more efficient that use `set` ! any way thanks for your attention and reminding ! – Mazdak Jan 28 '15 at 23:03
1

You should do this:

if pres == 'Bush' or pres == 'Obama' or pres == 'Clinton':
stenci
  • 8,290
  • 14
  • 64
  • 104