Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

DÚVIDA SOBRE FUNÇÕES

Boa noite, tenho uma dúvida a respeito do uso de parâmetros na função "marca_chute_correto(chute, letras_acertadas, palavra_secreta)", mas antes irei apresentar um trecho de código para melhor explicar a minha dúvida.

No código a seguir, estou definindo uma variável "nome" depois atribuo um novo valor a variável dentro da função. O valor da variável é impresso antes de chamar a função que muda o valor da variável e depois e o resultado é que a variável original passada como parâmetro não foi alterada.

def main():
    nome = 'eduardo'
    print('antes de chamar muda_nome()',nome)
    muda_nome(nome)
    print('depois de chamar muda_nome()',nome)


def muda_nome(nome):
    nome = 'joaquim'

if __name__ == '__main__':
    main()

Entendo que quando passamos uma variável para uma função, esta recebe uma cópia da variável então a variável original é preservada, porém isso não ocorreu no código do jogo.

Agora falando a respeito da dúvida no código do jogo, gostaria de destacar neste código o seguinte trecho:

            print('antes',letras_acertadas)
            marca_chute_correto(chute, letras_acertadas, palavra_secreta)
            print('depois', letras_acertadas)

No código final do jogo, apenas adicionei a impressão do valor da variável "letras_acertadas" antes e depois de chamar a função "marca_chute_correto", assim como fiz no exemplo anterior, porém desta vez a função alterou o valor da variavel original, não seguindo o padrão apresentado no exemplo anterior.

O que ocorreu no código de exemplo acima não se repetiu no código do jogo, porque???

import random


def jogar():
    imprime_mensagem_abertura()
    palavra_secreta = carrega_palavra_secreta()

    letras_acertadas = inicializa_letras_acertadas(palavra_secreta)
    print(letras_acertadas)

    enforcou = False
    acertou = False
    erros = 0

    while not acertou and not enforcou:

        chute = pede_chute()

        if chute in palavra_secreta:
            print('antes',letras_acertadas)
            marca_chute_correto(chute, letras_acertadas, palavra_secreta)
            print('depois', letras_acertadas)
        else:
            erros += 1
            desenha_forca(erros)

        enforcou = erros == 7
        acertou = '_' not in letras_acertadas

        print(letras_acertadas)

    if acertou:
        imprime_mensagem_vencedor()
    else:
        imprime_mensagem_perdedor(palavra_secreta)


def imprime_mensagem_abertura():
    print("*********************************")
    print("** Bem vindo ao jogo da Forca! **")
    print("*********************************")


def carrega_palavra_secreta():
    # palavra_secreta = 'banana'.upper()
    arquivo = open('palavras.txt', 'r')
    palavras = []

    for linha in arquivo:
        palavras.append(linha.strip())

    arquivo.close()

    numero = random.randrange(0, len(palavras))
    palavra_secreta = palavras[numero].upper()
    return palavra_secreta


def inicializa_letras_acertadas(palavra):
    return ["_" for letra in palavra]


def pede_chute():
    chute = input('Qual letra? ')
    chute = chute.strip().upper()
    return chute


def marca_chute_correto(chute, letras_acertadas, palavra_secreta):
    index = 0
    for letra in palavra_secreta:
        if chute == letra:
            letras_acertadas[index] = letra
        index += 1

...restante omitido.
3 respostas
solução!

Oi, Eduardo

Isso tem a ver com o dado que você está passando como parâmetro.

"nome" é uma string

"letras_acertadas" é uma lista

Quando uma string, número ou tupla é passada como parâmetro, seu valor é copiado para um novo espaço de memória, e as alterações feitas dentro da função não afetam o valor original da variável fora da função. A função recebe uma cópia do valor

Por outro lado, quando uma lista, dicionário ou conjunto é passado como parâmetro, é passada uma referência ao objeto na memória. Qualquer modificação feita dentro da função afetará o objeto original fora da função.

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓. Bons Estudos!

Luis, muito obrigado pelo retorno.

Essa informação é muito valiosa! Existe em Python uma forma de controlar o resultado que desejo, alterar o original ou uma cópia, ao passar uma variável como parâmetro?

Sei que em "C" posso utilizar o "&" no ínicio do nome da variável para que seja passado um ponteiro, o endereço da variável e não uma cópia e desta forma é alterado a variável original de forma controlada.

Eduardo,

O Python não permite passar variáveis como ponteiros da mesma maneira que em C

Apenas os "Objetos Mutáveis" (lista, dicionário ou conjunto) quando passados para uma função modificam a origem.

Os "Objetos Mutáveis" mantem o mesmo endereço de memória quando tem seu conteúdo mudado