Bug when adding elements to the list and transforming it into a string

Asked

Viewed 64 times

-3

I’m trying to headache in the course of a mini-project to develop a hangman game, in the function that would return the string containing the hidden word, showing only the guessed letters. I’ve tried everything, I’ve already researched about turning it into a string with the str() and Join() function, if you have another suggestion for the code, it will also help a lot. Follows the code:

def char_check(char, word):
    newWord_list = []
    newWord_ = ''
    for i in range(0, len(char)-1):
        if char == word[i]:
            newWord_list.append(char)
        else:
            newWord_list.append('_'))
    newWord_ = ''.join(newWord_list)
    return newWord_
  • 1

    char is only supposed to be a letter, right? If yes, the function is not entering the loop since len(char)-1=0

2 answers

2

In addition to the already explained iteration loop...

for i in range(0, len(char) - 1):

...which should be modified to...

for i in range(0, len(word) - 1):

... your code is disproportionately verbose the difficulty of the task to be performed.

Use a regular expression to hide the undiscovered letters of a string.

The function re.sub(pattern, repl, s, count=0, flags=0) replaces in the string s of the characters found by the matching pattern pattern by string repl.
The matching pattern [^caracteres] instructs the expression to match all characters except the characters between [^ and ].
The flag re.IGNORECASE executes a match that does not differentiate between upper and lower case.

The function re.escape(pattern) escapes special characters in the pattern pattern used to prevent the injection of metacharacters standard to avoid cheating.

import re

def char_check(char, word):
    return re.sub(fr"[^{re.escape(char)}]", "_", word, flags=re.IGNORECASE)

Example:

>>> print(char_check("p","Paralelepipedo"))
P_______p_p___

Test the example below on ideone.

import re
import random

def char_check(char, word):
    return re.sub(fr"[^{re.escape(char)}]", "_", word, flags=re.IGNORECASE)
    
    
palavra = random.choice(["Python", "Haskell", "Javascript", "Scheme", "Lisp", "Visual Basic", "Clipper", "Assembly", "Cobol", "Forth" ])
tentativas = " "

print("Você tem cinco tentativas.\n")
print(char_check(tentativas, palavra))
print("\n")
for i in range(1,6):
    tentativas += input(f"Tentativa {i}: ")
    jogada = char_check(tentativas, palavra)
    print(jogada)
    if jogada == palavra:
        print("!!!TEMOS UM VENCEDOR!!!")
        break
else:
    print("Você morreu enforcado")

#Você tem cinco tentativas.

#_____
   
#Tentativa 1: p
#_____
#Tentativa 2: m
#_____
#Tentativa 3: o
#_o___
#Tentativa 4: frth
#Forth
#!!!TEMOS UM VENCEDOR!!!

1

Your code problem is in the repeat block. You are using the string size char - which theoretically must contain only one character - in the function range() as a stop point, when you should be using the string size word.

for i in range(0, len(word) - 1):
    ...

Also, another problem of your code, still on the same line, is the use of subtraction -1 at the stop point of the function. You must not subtract the value of the stop, because the function defines this value as its "definitive" limit. See the example below:

list(range(5))      # [0, 1, 2, 3, 4]
list(range(5 - 1))  # [0, 1, 2, 3]

That said, your code should look like this:

def char_check(char, word):

    newWord_list = []
    newWord_ = ''
    
    # O valor padrão de "start" é zero. Sendo assim, não precisa especificá-lo.
    for i in range(len(word)): 

        if char == word[i]:
            newWord_list.append(char)
        else:
            newWord_list.append('_')

    newWord_ = ''.join(newWord_list)
    return newWord_

In addition, you can further improve your role without having to create a new list. To do this, traverse each character of your string through the loop for and check that the letter is the same as char. If yes, add it to the new string. If not, add the string "_". See how it would look:

def char_check(char, word):

    new_word = ""

    for letter in word:
        if char == letter: new_word += char
        else: new_word += "_"

    return new_word

It is also possible to do all this in just one line, using comprehensilist on, as follows:

 def char_check(char, word):

    return "".join([char if char == letter else "_" for letter in word])

Browser other questions tagged

You are not signed in. Login or sign up in order to post.