Comparing Strings

Hello, I am attempting to teach myself Python using MIT’s OCW. I am trying to program a Hangman game using functions and I need to compare a string (letters_guessed) to the word the computer chose (secret_word (also a string)). I want to do a simple ‘if’ statement, but since I won’t be guessing the letters in the correct order, is there a way to compare the string without a simple ‘==’ that would check if the letters match instead of the entire string? I’ve thought of using a ‘for’ loop, but have not been able to compare more than one character at a time. Any help would be appreciated!

Another way to say it in plain language would be “If all characters of secret_word are in letters_guessed return true, else return false.”

1 Like

Have a look at the in operator, list comprehensions, and the all() builtin function, and note that you can iterate a str to get one character at a time (for c in 'test': will give you c = 't', then c = 'e', etc.).

There are other solutions involving sets, but it turns out that your “plain language” statement is very nearly a Python statement :slight_smile:

1 Like

I’ve managed to come up with this for a test at this time, but there seems to be some issues with it that I stated earlier. Trying different combinations of ‘e’ ,‘g’ and ‘s’, it only works if the entire string appears in the word.

selected_word="eggs"
letters_guessed="egs"

if letters_guessed in selected_word:
    print("true")
else:
    print("false")

I looked into the all() function, but I believe the challenge is to do this with the tools available. It is an introductory course, so we are using simple for loops, while loops, and other basic tools.

I’ve since updated my test code to read this:

selected_word="eggs"
letters_guessed="gage"

for char in letters_guessed:
    if char in selected_word:
        print(char)
    else:
        print("false")

For each character in letters_guessed, if that character is in selected_word, print character, else print “False”. This lets me know if the guessed letter is in the selected word, but how would I then use this to see if all letters had been guessed without having to have the letters in the correct order? I could do a simple if selected_word in letters_guessed, but the entire string would need to appear which cannot work with characters being guessed out of order as well as duplicate characters.

Here’s a hint:

selected_word = "eggs"

guess = input("> ")
for ltr in selected_word:
    if guess == ltr:
        print(ltr, end='')
    else:
        print('-', end='')

I’m a little confused on the point of the end=’ ’ or the arrow in the input. This is also only the FINAL comparison to see if the letters of selected_word have been guessed, not the actual process of guessing the letters, but thank you for that as I can change the print command to add the letter to the string. (Yes, I know strings are immutable; I mean rebind the string to the value of the string + the guessed letter)

The > is simply to denote a input ‘prompt’ and can be anything of your choosing; it’s simply something that I use.

The end='' in the print() function call, is to override the newline (which is the default) character. If you leave that out and then run the script, you’ll see the difference.

A good builtin tool is help:

>>> help(print)
Help on built-in function print in module builtins:

print(...)
    print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
    
    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file:  a file-like object (stream); defaults to the current sys.stdout.
    sep:   string inserted between values, default a space.
    end:   string appended after the last value, default a newline.
    flush: whether to forcibly flush the stream.

Post up what you have, in full, so that we can see where you’re at and advise you some more.

This is the prompt:

"First, implement the function is_word_guessed that takes in two parameters ­ a
string, secret_word, and a list of letters (strings), letters_guessed. This function
returns a boolean ­ True if secret_word has been guessed (i.e., all the letters of
secret_word are in letters_guessed), and False otherwise. This function will be
useful in helping you decide when the hangman game has been successfully
completed, and becomes an end­test for any iterative loop that checks letters against
the secret word.
For this function, you may assume that all the letters in secret_word and
letters_guessed are lowercase.

Example Usage:

>>> secret_word = 'apple' 
>>> letters_guessed = ['e', 'i', 'k', 'p', 'r', 's'] 
>>> print(is_word_guessed(secret_word, letters_guessed)) 
False

The definition says:

def is_word_guessed(secret_word, letters_guessed):
    '''
    secret_word: string, the word the user is guessing; assumes all letters are
      lowercase
    letters_guessed: list (of letters), which letters have been guessed so far;
      assumes that all letters are lowercase
    returns: boolean, True if all the letters of secret_word are in letters_guessed;
      False otherwise
    '''

We can simplify that: we simply want to know whether “all characters of secret_word are in letters_guessed”. There’s no point in explicitly writing out conditional logic if we will just get a True result in one case and False in the other. The condition already represents what we want.

As it happens, Python allows us to express this view of the problem almost directly. We want to know whether all examples of a character (let’s call it c) are in letters_guessed, where we repeat the check for each of the c examples that is in secret_word.

The corresponding Python code is in that order:

all(c in letters_guessed for c in secret_word)

Another way is to construct some representation of “the distinct letters of” each side (letters_guessed and secret_word), and then check that one grouping encompasses the other. In mathematics, the natural representation for such a thing is a set, and that’s what we call it in Python as well. Thus:

set(secret_word).issubset(set(letters_guessed))

See also e.g.:

1 Like

Okay, I now see what you’re trying to do.

So, how far have you got with writing that function?

Thank you for the insight. I understand what you’re trying to do and I believe it would work as well, but the challenge is to do this with basic functions and definitions. I am very thankful for the resources you have provided though!

Since I’ve last uploaded my code, I have not changed it. I can see it comparing each letter individually and executing based on the result, but it still does not do the final compare that I am looking for.

Without seeing what you’ve coded, in your function (I’ve looked back, but it’s not there, so far as I can tell) we are left to guess at this: if you post that up, you’ll get a quicker solution.

I apologize, I was referencing my test code. I believe that I have skipped a step in the assignment as well so I will be returning to that at this moment. I will be active in this thread though if you are still willing to help later.

Of course: if I think I can help you (or anyone) I’ll try to do that.

Is there a way to upload files? It would be easier if I could send you the entire Python file + PDF of instructions.

I think we have enough information to be able to see what you’re trying to do (thank you for posting that) and your function should not be over long, so simply use a formatted code post, as you’ve already been doing. Or am I missing something?

I have no issue doing the formatted posts. The PDF file and Python file just have a lot of text and I felt it would be easier to understand if we were both looking at the same thing. I am also a very early beginner of Python and may use incorrect jargon and it would help with that as well.

Okay. Well you can 'dropbox, or ‘Google drive’, or use an anon service, such as https://anonfiles.com/