简体   繁体   中英

Python - char and index match

I can't figure out what I'm doing wrong. I want a simple way of matching the char and position in two strings. The error is that it's not recognizing what I'm intending as an index.

I'm new at this. :) I think experts can understand what I'm starting to try to do here. I don't want to copy a complicated bulls and cows code, I'm just trying to do this early part. Please advise:

def bulls_and_cows(real, guess):
    bulls = 0
    cows = 0
    for i in guess:
        if i == i in real:
            if i[x] == i[x]
            bulls = bulls + 1
            print ("Bullseye!")
            print(bulls)
    else:
        print("No")

bulls_and_cows("like", "brig")

In the line

for i in guess:

the variable i will be each char in the string guess, instead of index. If you intend to get both indices and chars, you need to use enumerate() .

Next I'm not sure what you intend to compare in

if i == i in real:

Also, x is not initialized anywhere before this line:

if i[x] == i[x]

You can use a lot of handy utils, most of all zip :

from collections import Counter
def bulls_and_cows(real, guess):
    # count bulls
    bulls = sum(x == y for x, y in zip(real, guess))

    # get letter counts separately for each string
    c1, c2 = map(Counter, (real, guess))

    # cows: sum min count for any letter, subtract bulls
    cows = sum(min(c1[x], c2[x]) for x in set(real) | set(guess)) - bulls

    print(bulls, cows)

For pure explicit iterative bulls counting:

def bulls_and_cows(real, guess):
    bulls = 0
    for r, g in zip(real, guess):
        if r == g:
            bulls += 1
    print(bulls)

I guess you are trying to do this:

def bulls_and_cows(real, guess):
    bulls = 0
    cows = 0
    for i in range(len(guess)):
        if guess[i] == real[i]:
            bulls = bulls + 1
            print ("Bullseye!")
        else:
            cows += 1

    if bulls == 0:
        print("No")
    else:
        print("Bulls: " , bulls, " Cows: ", cows)

bulls_and_cows("like", "brig")

Please let me know if it is not what you intend so I can help you more. This code Prints "Bullseye!" for every time a char in guess matches the char in real in the same place. and prints "No" if they do not match. I couldn't understand why you needed a cows = 0 at first because you never used it in your code.

Also please notice that indention is very important in python. So in your code at least one of the lines after the if should be indented. Also, in this code, I assumed that the length of the two input strings is the same. If not you may encounter out of bound error. To prevent such errors it is better to compare the length of the two strings at the start of the function:

if len(real) != len(guess):
    print("The strings Length does not match!")
    return

If you insist to compare the strings even though they are of different lengths, another option to prevent this error is to change the code like this:

def bulls_and_cows(real, guess):
    bulls = 0
    cows = 0
    real_len = len(real)
    guess_len = len(guess)
    for i in range(real_len):
        if i < guess_len and guess[i] == real[i]:
            bulls = bulls + 1
            print ("Bullseye!")
        else:
            cows += 1

    if bulls == 0:
        print("No")
    else:
        print("Bulls: " , bulls, " Cows: ", cows)

Hopefully the code below isn't too advanced for you. It uses the very handy enumerate function which lets us loop over a string and get both the index and the character. Actually, enumerate is a general function that can be used on any for loop when we need to get the item and its index.

def bulls_and_cows(real, guess):
    bulls = cows = 0
    for i, c in enumerate(guess):
        if c in real:
            # We have a match!
            if real[i] == c:
                # And it's in the correct position
                bulls += 1
            else:
                cows += 1

    print('Bulls', bulls, 'Cows', cows)

bulls_and_cows("like", "brig")

output

Bulls 0 Cows 1

My code doesn't produce the exact output you want, but I'm sure you can figure that out. ;)


If you can't quite understand how my code works, try putting

print(i, c)

as the first line in the for i, c in enumerate(guess): block, before the if c in real: line.

My teacher pointed out I should start with the "cows" section, and then for those results, narrow it to bulls. This is the working answer i put together. I appreciate the suggestions!

def bulls_and_cows(real, guess):
    bulls = 0
    cows = 0
    for i in guess:
        if i == i in real:
            cows = cows+1
            if guess.index(i) == real.index(i):
                cows = cows -1
                bulls = bulls +1
    print("Bulls: " + str(bulls))
    print("Cows: " + str(cows))

You can also go with a 1 liner for each of the cases:

real = "like"
guess = "brig"
print("Bulls", sum(1 for x in zip(real, guess) if x[0] == x[1])) # Bulls 0
print("Cows", sum(1 for x in real if x in guess and real.index(x) != guess.index(x))) # Cows 1

The first one "zips" the word and counts the tuples with similar characters. The second, looks for characters that are in both words but positioned in different indexes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM