I am trying to get character matching when comparing two strings. The result would display the two words side by side with the matching (and non-matching) characters displayed. This would be similar to mastermind. Example:

(test word) - HALE (sample word) - HELP

This would be displayed as:

    H?L?          HELP

and with each subsequent test word, it would update for matches:

    H?L?          HELP
    HEL?          HELP
    HELP          HELP

The code would register each test and display success or failure at the end of the line. I can do that part and even compare the two words. I just need to get the display part working. Here is my code so far:

import string, random, datetime

now  = datetime.datetime.now()
tries = 0
result = ""
numchars = 0

def id_generator(size = numchars, chars=string.ascii_uppercase):    # size = 6
    return ''.join(random.choice(chars)
        for _ in range(size))

numchars = int(raw_input("Enter the number of characters in the word : "))
testword = raw_input("What is the word you are testing for? ")
word = id_generator()
while word != testword:
    print tries, "tries and word =", word, " test word is ", testword
    tries = tries + 1
    word = id_generator(numchars)
tries = tries + 1
print tries, "tries and word =", word, " test word is ", testword
now1 = datetime.datetime.now()
print "We have a match! And, it only took ", tries, " attempts!"
print "Total run time:", str(now1 - now)

The current results look like this:

877663 tries and word = GLIS test word is HELP
877664 tries and word = DBAJ test word is HELP
877665 tries and word = NAIF test word is HELP
877666 tries and word = NHVI test word is HELP
877667 tries and word = ZDIZ test word is HELP
877668 tries and word = THCL test word is HELP
877669 tries and word = LMQE test word is HELP
877670 tries and word = OIMU test word is HELP
877671 tries and word = HXGB test word is HELP
877672 tries and word = OGIY test word is HELP
877673 tries and word = BSTG test word is HELP
877674 tries and word = UELJ test word is HELP
877676 tries and word = HELP test word is HELP
We have a match! And, it only took 877676 attempts!
Total run time: 0:07:44.332000

I don't mind the overall output, though I might want to pipe it to a text file later. I don't even mind seeing the test word in full, but character matching is my goal.

You start with a list full of ? and replace each ? with a letter when guessed correctly.

## assumes both words are the same length

def display_matches(matches, test_word, sample_word):
    """     H?L?          HELP
            HEL?          HELP
            HELP          HELP
    """
    for ctr in range(len(test_word)):
        if test_word[ctr] == sample_word[ctr]:
            matches[ctr] = test_word[ctr]
    print "%s   %s  %s" % ("".join(matches), sample_word, test_word)
    return matches

test_word="HALE"
sample_word="HELP"
matches = ["?" for ctr in range(len(sample_word))]

matches=display_matches(matches, test_word, sample_word)
matches=display_matches(matches, "WXYZ", sample_word)
matches=display_matches(matches, "KEEN", sample_word)
matches=display_matches(matches, "HERO", sample_word)
matches=display_matches(matches, "STOP", sample_word)

""" results
H?L?   HELP  HALE
H?L?   HELP  WXYZ
HEL?   HELP  KEEN
HEL?   HELP  HERO
HELP   HELP  STOP
"""

Edited 2 Years Ago by woooee

Okay, I see what you did there, but the results aren't what I was expecting. The test_word should be tested each time so that the result would match the compare between the sample_word and the test_word. As such, using your test_words, the result should be:

H?L? HELP HALE
???? HELP WXYZ
?E?? HELP KEEN
HE?? HELP HERO
HELP HELP STOP

I will say that you have moved closer to my next question. After being able to complete the match, I would like to have my program 'remember' matched letters and not retry them. But, I want this to be a word match, not character match. This means that subsequent words that don't match the previous 'partial' match, would be discarded.

As you can see from my original code, the sample_word length and the test_word length would be the same. I am working towards a word match that would eventually move to a sentence or even paragraph match. Understanding the complexity and growth needed. Ultimately the "test" (word, sentence, paragraph) would check the length of "sample" then work to match.

I have tried adding your code segment to my program

import string, random, datetime

def id_generator(size = numchars, chars=string.ascii_uppercase):    # size = 6
    return ''.join(random.choice(chars)
        for _ in range(size))

def display_matches(matches, testword, word):
    for ctr in range(len(testword)):
        if testword[ctr] == word[ctr]:
            matches[ctr] = testword[ctr]
    print "%s   %s  %s" % ("".join(matches), word, testword)
    return matches

now  = datetime.datetime.now()
tries = 0
result = ""
numchars = 0
numchars = int(raw_input("Enter the number of characters in the word : "))
testword = raw_input("What is the word you are testing for? ")
word = id_generator()

while word != testword:
    print tries, "tries and word =", word, " test word is ", testword
    tries = tries + 1
    matches = ["?" for ctr in range(len(word))]
    matches=display_matches(matches, testword, word)
    word = id_generator(numchars)
tries = tries + 1
print tries, "tries and word =", word, " test word is ", testword
now1 = datetime.datetime.now()
print "We have a match! And, it only took ", tries, " attempts!"
print "Total run time:", str(now1 - now)

But get IndexError: string index out of range

Correction on previous post, it does work, just not with the intended results. I updated output formatting and now get this:

65251 tries and result ??L? word: NFLZ test word is: HELP
65252 tries and result ???? word: WZXL test word is: HELP
65253 tries and result ???? word: ARID test word is: HELP
65254 tries and result ???? word: YVMQ test word is: HELP
65255 tries and result ???? word: TBRS test word is: HELP
65256 tries and result ???? word: ITHM test word is: HELP
65257 tries and result ???? word: LGNL test word is: HELP
65258 tries and result H??? word: HVCA test word is: HELP
65259 tries and result ???? word: QUGQ test word is: HELP
65260 tries and result H?L? word: HPLQ test word is: HELP

This is the original intended output. Thank you wooee for your input. Now, however, I am on to the next step, to discard unmatched attempts and retain matched characters. I know this will provide a reduced output which is why I have the timer running. How do I give subsequent results, like this:

65251 tries and result ??L? word: NFLZ test word is: HELP
65258 tries and result H?L? word: HVLA test word is: HELP
65260 tries and result HEL? word: HELQ test word is: HELP
75821 tries and result HELP word: HELP test word is: HELP

Thanks for your input!

Send the list named matches to the function id_generator. If the element in the list equals "?" then generate a random letter. If not then append the letter from matches to the list to be returned. You don't want to update matches because you want it to remain as the control list, although you could copy it and update the copy but read how to copy from the link below if you do this as you can not just use a=b.. Traversing a list http://www.greenteapress.com/thinkpython/html/thinkpython011.html#toc108

Edited 2 Years Ago by woooee

Thank you woooee, I have had to move on to another project so will not be pursuing this one for now. I will repost when I return but will mark this one solved for now.

This question has already been answered. Start a new discussion instead.