String error in a Python 3 function

Asked

Viewed 639 times

1

When I try to rotate the def gives a mistake on the part of texto[x][y-1], giving the following:

erro:TypeError: 'str' object does not support item assignment

Could someone please help me?

def moveJogador(mapa, mov):
    if mov == "c":
        for y in range(len (mapa)-1):
            for x in range(len(mapa[0])-1):
                if texto[x][y] == JOGADOR_NA_MARCA:
                    texto[x][y-1] = ("@")  #Aqui está o erro de string
                    texto[x][y] = " "
                    print(mapa)   
    return None

movimento = input("Digite d | e | c | b | v | s [dir, esq, cima, baixo, voltar, sair]: ")

moveJogador(texto, movimento)
  • You are trying to add an item, not a string, into a string. Try putting only "@" or "(@)" to assign the value to the string.

  • You can display the'text definition'?

1 answer

3

The error shows exactly what is happening: in Python, strings are immutable objects - this is in contrast to C, for example where "strings" are just a convenient name for a memory region that is treated as a data sequence the size of a byte. (Then you can do char *a = "abcde"; a[0] = 'f'; in C, it changes the byte in the first position of the pointed memory by variable "a")

In Python there is another type of data that can be used in the same way which strings in C: changeable, and with a more or less mapping convenient and direct between numbers in the range 0-255 and objects string length "1" (this in Python 2.x - in Python 3.x, mapping to text must be explicit) is the bytearray.

So instead of creating your lines on the map using something like:

text.append(" @ ") use: text.append(bytearray("") and you can address and change individual values inside.

This is the fastest solution to the coigo you’ve ever had - in fact, the best solution for your project is to create a new class for contain your map (instead of having a map composed of lists and strings, in which external functions act to check the content and make changes).

With a class itself, and implementing the methods __getitem__ and __setitem__ you can have a "smart" map that knows itself locate the player, if delete, fill with a value.

Just take care to assume that the addresses passed to get and set/item are sequences of two values, and you can do something straight like this:

TAMANHO = (80, 25)
class MeuMapa(object):
    def __init__(self, tamanho=TAMANHO):
        # estrutura de dados interna, composta de listas de listas, pré-preenchidas com espaços
        self.dados_internos = ([" ",] * tamanho[0]) * tamanho[1]
        self.tamanho = tamanho
    def __getitem__(self, index):
        return self.dados_internos[index[0]][index[1]]
    def __setitem__(self, index, valor):
        return self.dados_internos[index[0]][index[1]] = valor


texto = MeuMapa()
texto[10,10] = "@"

Note that with this minimal implementation, you can already reference objects on the map using a single search by index, rather than two in sequence - leaving your access code to the map much cleaner - a "find_player" or "player_find" method can be written equally simply, and be re-used for each comparison of your "move player" - the code that Voce posted implies making two "for" nested to each motion option - with the above class plus a method like:

def encontra_jogador(self):
    for y, linha in enumerate(self.dados_internos):
        for x, valor in enumerate(linha):
            if valor == JOGADOR_NA_MARCA:
                return x, y

What will allow you to do:

x, y = texto.encontra_jogador()
print (x, y)
(10,10)

Browser other questions tagged

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