Home > database >  Remove characters from a string upon user input
Remove characters from a string upon user input

Time:11-14

I am creating a hangman game and I am displaying the letters that have not yet been guessed so if no letters have been guessed it displays all the abc's. And what I am trying to figure out is how to get rid of the letter the user inputted from the letters remaining and return the string of the remaining letters.

def get_available_letters(letters_guessed):
    """
    Returns a string of letters that have not yet been guessed.

    :param: letters_guessed: letters that have been guessed so far by the player
    :type letters_guessed: str
    :return: letters that have not been guessed
    :rtype: str
    """
    ALL_LETTERS = 'abcdefghijklmnopqrstuvwxyz'
    letters_guessed = letters_guessed.lower()
    for ch in ALL_LETTERS:
        if ch in letters_guessed:
            letters_left = ALL_LETTERS.replace(letters_guessed, '')
            return letters_left
        else:
            return ALL_LETTERS

CodePudding user response:

You don't need the else in the for loop, because as soon as a ch is not in letters_guessed you return the full list. Do this instead:

def get_available_letters(letters_guessed):
    """
    Returns a string of letters that have not yet been guessed.

    :param: letters_guessed: letters that have been guessed so far by the player
    :type letters_guessed: str
    :return: letters that have not been guessed
    :rtype: str
    """
    ALL_LETTERS = 'abcdefghijklmnopqrstuvwxyz'
    letters_guessed = letters_guessed.lower()
    for ch in ALL_LETTERS:
        if ch in letters_guessed:
            letters_left = ALL_LETTERS.replace(letters_guessed, '')
            return letters_left

    return ALL_LETTERS

CodePudding user response:

You can just subtract letters_guessed from ALL_LETTERS, the available letters remains.

This function returns the subtracted letters by replacing letters_guessed in ALL_LETTERS to be empty. So what remains is the remaining available letters.

def get_available_letters(letters_guessed):
  ALL_LETTERS = 'abcdefghijklmnopqrstuvwxyz'
  return ALL_LETTERS.replace(letters_guessed.lower(), '')

Example:

letters_guessed = "abc"
ALL_LETTERS.replace(letters_guessed, '')
# abc will be removed from abcdefghijklmnopqrstuvwxyz
# -> defghijklmnopqrstuwxyz

However, there are some edge cases.

  • letters_guessed is not sorted, since replace replaces the exact substring.
  • Some letters are not included in ALL_LETTERS, same reason.

This can be fixed by just looping letters_guessed letters one by one and then removing then from ALL_LETTERS

def get_available_letters(letters_guessed):
  ALL_LETTERS = 'abcdefghijklmnopqrstuvwxyz'
  for letter in letters_guessed.lower():
    ALL_LETTERS = ALL_LETTERS.replace(letter, '')
  return ALL_LETTERS
  1. You can refactor your code so that available_letters is a variable outside of the function (either global or as a property of a class)
available_letters = 'abcdefghijklmnopqrstuvwxyz'

when a letter is guessed, just remove a letter from available_letters

CodePudding user response:

str.replace(old, new[, count]) repalces the old string with new string, not each character in the old string.

Example:

'abc'.replace('ba', '')  # return 'abc', because string 'ba' is not in 'abc'
'abc'.replace('ab', '')  # return 'c', string 'ab' is replaced with ''

Therefore, one solution is to iterate each character in the letters_guessed, and replace it with the null character.

def get_available_letters(letters_guessed):
    ALL_LETTERS = 'abcdefghijklmnopqrstuvwxyz'
    letters_guessed = letters_guessed.lower()
    for ch in letters_guessed:
        ALL_LETTERS = ALL_LETTERS.replace(ch, '')
    return ALL_LETTERS

CodePudding user response:

This function returns a string with all the letters from abc that are not in letters_guessed.

def get_available_letters(letters_guessed):
    abc = "abcdefghijklmnopqrstuvwxyz"

    for ch in abc:
        if ch in letters_guessed.lower():
            abc = abc.replace(ch, "")

    return abc

BTW, I recommend using lists instead of strings for cases such as this one.

Here's how this function could be written if lists were used:

def get_available_letters(letters_guessed):
    abc = "abcdefghijklmnopqrstuvwxyz"

    return [ch for ch in abc if ch not in letters_guessed.lower()]

CodePudding user response:

I think it is better to store available letters as a list and pop values out of it when player makes a guess. Have a look at this implementation.

from string import ascii_lowercase

ALL_LETTERS = list(ascii_lowercase)
LETTERS_LEFT = ALL_LETTERS

def guess():
    letter = str(input("Enter letter: ")).lower()
    if letter in LETTERS_LEFT:
        LETTERS_LEFT.pop(LETTERS_LEFT.index(letter))  # Remove letter from list
    elif letter in ALL_LETTERS:
        print("This letter was already used!")
    else:
        print("Wrong input! Use one of:", "".join(ALL_LETTERS))
    return get_available_letters()


def get_available_letters():
    return LETTERS_LEFT


while True:
    print(guess())

Actually I believe you should use all this stuff inside of a class, as OOP is better for game development (IMHO)

  • Related