Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

viciado

Erro função Len

Recommended Posts

#Espadas -> 3
#Copas -> 2
#Ouros -> 1
#Paus -> 0

class Carta:
   listaDeNaipes = ["Paus", "Ouros", "Copas", "Espadas"]
   listaDePosicoes = ["narf", "As", "2", "3", "4", "5", "6", "7",
                       "8", "9", "10", "Valete", "Rainha", "Rei"] #narf -> preencher o 0

   def __init__(self, naipe=0, posicao=0):
       self.naipe = naipe
       self.posicao = posicao

   def __str__(self):
       return (self.listaDePosicoes[self.posicao] + " de " +
               self.listaDeNaipes[self.naipe])

   #__cmp__ recebe self e other, retorna 1 se o primeiro for maior
   # e -1 se for menor, 0 se eles forem iguais
   def __cmp__(self, other):
       if self.naipe > other.naipe: return 1
       if self.naipe < other.naipe: return -1
       #msm naipe verifica a posicao
       if self.posicao > other.posicao: return 1
       if self.posicao < other.posicao: return -1
       #posicoes iguais
       return 0

class Baralho:
   def __init__(self):
       self.cartas = []
       for naipe in range(4):
           for posicao in range(1, 14):
               self.cartas.append(Carta(naipe,posicao))

   def imprimirBaralho(self):
       for carta in self.cartas:
           print carta

   def embaralhar(self):
       import random
       nCartas = len(self.cartas)
       for i in range(nCartas):
           j = random.randrange(i, nCartas)
           self.cartas[i], self.cartas[j] = self.cartas[j], self.cartas[i]

   def removerCarta(self, carta):
       if carta in self.cartas:
           self.cartas.remove(carta)
           return 1
       else:
           return 0

   #remover e devolver a carta do topo
   def distribuirCarta(self):
       return self.cartas.pop()

   #verifica se o baralho tem carta
   def ehVazio(self):
       return (len(self.cartas) == 0)

   def distribuir(self, maos, nCartas=999):
       nMaos = len(maos)
       for i in range(nCartas):
           if self.estahVazia(): break    # interromper se acabaram as cartas
           carta = self.pegarCarta()      # pegar a carta do topo
           mao = maos[i % nMaos]       # quem deve receber agora?
           mao.adicionarCarta(carta)   # adicionar a carta a mao

class Mao(Baralho):
   def __init__(self, nome=""):
       self.cartas = []
       self.nome = nome

   def adicionarCarta(self, carta):
       self.cartas.append(carta)

   def __str__(self):
       s = "Mao " + self.nome
       if self.estahVazia():
           return s + " esta vazia\n"
       else:
           return s + " contem\n" + Baralho.__str__(self)

baralho = Baralho()
baralho.embaralhar()
mao = Mao("Giovanni")
baralho.distribuir(mao, 5)
print mao.__str__()

 

O erro que está dando é:

nMaos = len(maos)
AttributeError: Mao instance has no attribute '__len__'

 

Eu tenho que instanciar a função len ? Como ? Ela jah nao é padrão do python ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

"mao" é um objeto. len() só funciona com strings ou listas (arrays)

 

Obrigado. Ahh, tenho uma dúvida, como eu posso retornar o elemento do topo de uma lista em python ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

P/ usar a função len diretamente em uma classe você precisa implementar __len__.

 

Não existe método estahVazia

Compartilhar este post


Link para o post
Compartilhar em outros sites

P/ usar a função len diretamente em uma classe você precisa implementar __len__.

 

Interessante. Não sabia disso.

 

isto esclarece melhor:

__len__ is called when you call len(instance). The len function is a built-in function that returns the length of an object. It works on any object that could reasonably be thought of as having a length. The len of a string is its number of characters; the len of a dictionary is its number of keys; the len of a list or tuple is its number of elements. For class instances, define the __len__ method and code the length calculation yourself, and then call len(instance) and Python will call your __len__ special method for you.

fonte: http://diveintopython.org/object_oriented_framework/special_class_methods2.html

 

 

Valeu, Isis! :)

Compartilhar este post


Link para o post
Compartilhar em outros sites

P/ usar a função len diretamente em uma classe você precisa implementar __len__.

 

Interessante. Não sabia disso.

 

isto esclarece melhor:

__len__ is called when you call len(instance). The len function is a built-in function that returns the length of an object. It works on any object that could reasonably be thought of as having a length. The len of a string is its number of characters; the len of a dictionary is its number of keys; the len of a list or tuple is its number of elements. For class instances, define the __len__ method and code the length calculation yourself, and then call len(instance) and Python will call your __len__ special method for you.

fonte: http://diveintopython.org/object_oriented_framework/special_class_methods2.html

 

 

Valeu, Isis! :)

 

Errei o nome o método é: ehVazio()

 

Tentei fazer a função pegarCarta() mais nao é assim q se pega o elemento do topo da lista

def pegarCarta()
   return self.cartas.top()

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não tinha nada p/ fazer hoje à tarde e resolvi mexer no teu código.

Provavelmente tem coisas que você ainda não viu, mas dá p/ ter uma ideia dos recursos da linguagem.

Detalhe: isso é Python 3.1, e não 2.6

 

 

# coding:utf-8

class Carta(object):
   Naipes = ["Paus", "Ouros", "Copas", "Espadas"]
   Valores = {1 : "As", 2 : "Dois", 3 : "Tres", 4 : "Quatro", 5 : "Cinco", 6 : "Seis", 7 : "Sete", 8 : "Oito", 9 : "Nove", 10 : "Dez", 11 : "Valete", 12 : "Dama", 13 : "Rei"}


   def __init__(self, naipe=0, valor=1):
       """
           Inicia o objeto Carta.
           @params naipe Índice do naipe da carta.
           @params valor Valor da carta.
       """

       self.naipe = naipe

       if valor not in Carta.Valores.keys():
           raise ValueError('Valor de carta inválido.')

       self.valor = valor




   def __str__(self):
       """
        	Retorna a descrição da carta.
       """
       return "{0} de {1}".format(Carta.Valores[self.valor], Carta.Naipes[self.naipe])



   def __cmp__(self, other):
       """
        	Realiza a comparação entre valores das cartas, sem considerar o naipe.
       """
       if self.valor > other.valor:
           return 1


       if self.valor < other.valor:
           return -1

       return 0




class Baralho(object):

   def __init__(self):
       self.cartas = []

       for naipe in range(4):
           self.cartas.extend([Carta(naipe, valor) for valor in range(1,14)])



   def embaralhar(self):
       import random
       random.shuffle(self.cartas)




   def removerCarta(self, carta = None):
       """
           Remove uma carta do baralho.
           @param carta Carta a ser removida do baralho. Opcional.
       """

       if carta is None:
           return self.cartas.pop()

       else:
           if carta in self.cartas:
               posicao = self.cartas.index(carta)
               return self.cartas.pop(posicao)

           else:
               raise ValueError('Não existe essa carta no baralho.')




   def __len__(self):
       return len(self.cartas)



   def __str__(self):
       return str([c.__str__() for c in self.cartas]) 





class Mao(object):


   def __init__(self, nome = None):
       """
           Inicializador do objeto Mao.
           @params nome Nome do jogador.
       """
       if nome is None or nome == "":
           raise ValueError('É necessário especificar um nome para o jogador.')

       self.cartas = []
       self.nome = nome



   def pegarCarta(self, carta):
       """
           Pega a carta retirada do monte.
           @params carta Carta pega do baralho.
    	"""

    	self.cartas.append(carta)



   def __str__(self):
       texto = "Jogador: {0}\nCartas:\n".format(self.nome)

       if len(self.cartas) != 0:
           texto = texto + "{0}"
           return texto.format([x.__str__() for x in self.cartas])

       return texto



   def __len__(self):
       return len(self.cartas)




class Jogo(object):

   def __distribuir__(self):
       """
           Distribui as cartas do baralho aos jogadores presentes.
       """

       for i in range(self.nCartas):
           for j in range(self.nJogadores):
               carta = self.baralho.removerCarta()
               self.jogadores[j].pegarCarta(carta)


   def __prepararJogo__(self):
       for i in range(self.nJogadores):
           while True:
               nomeJogador = input('Digite o nome do jogador #{0}: '.format(i+1))
               try:
                   self.jogadores.append(Mao(nomeJogador))

               except ValueError:
                   pass

               else:
                   break

       self.baralho.embaralhar()
       self.__distribuir__()




   def __init__(self, nJogadores = None, nCartas = None):
       if nJogadores is None or nJogadores < 1:
           raise ValueError('É necessário existir pelo menos 1 jogador.')

       self.nJogadores = nJogadores
       self.jogadores = []
       self.baralho = Baralho()

       if nCartas is None:
           raise ValueError('É necessário especificar o número de cartas a distribuir para cada jogador.')

       if nCartas * nJogadores > len(self.baralho):
           raise ValueError('Não é possível distribuir mais de {0} cartas.'.format(len(self.baralho)))

       if nCartas < 1:
           raise ValueError('É necessário distribuir alguma carta para os jogadores.')

       self.nCartas = nCartas
       self.__prepararJogo__()



   def retornarJogadores(self):
       for j in self.jogadores:
           yield j




if __name__ == '__main__':
   print('Criando jogo...')
   myGame = Jogo(3, 9)

   for player in myGame.retornarJogadores():
       print(player)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eu utilizo Windows Seven, com o NetBeans.

Aqui tah dando erro:

File "<string>", line None
SyntaxError: Illegal character in file 'D:\Projetos Python\ClassesPython\src\classespython.py' for encoding 'utf-8'

 

Acho que é por causa dos caracteres, mais não sei arrumar isso.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Viciado, você faz bem em procurar o que mudou nas strings entre as versões 2.6 e 3.1.

Na 2.6, p/ você usar caracteres especiais nas strings, era necessário utilizar o prefixo u. Na versão 3.1 todas as strings são utf8.

Veja se colocar o u na frente das strings resolve.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Viciado, você faz bem em procurar o que mudou nas strings entre as versões 2.6 e 3.1.

Na 2.6, p/ você usar caracteres especiais nas strings, era necessário utilizar o prefixo u. Na versão 3.1 todas as strings são utf8.

Veja se colocar o u na frente das strings resolve.

 

Eu utilizei

# -*- coding: ISO-8859-1 -*- 

e funcinou

 

Soh que estah dando o seguinte erro:

Traceback (most recent call last):
 File "D:\Projetos Python\ClassesPython\src\classespython.py", line 204, in <module>
   myGame = Jogo(3, 9)
 File "D:\Projetos Python\ClassesPython\src\classespython.py", line 191, in __init__
   self.__prepararJogo__()
 File "D:\Projetos Python\ClassesPython\src\classespython.py", line 157, in __prepararJogo__
   nomeJogador = input('Digite o nome do jogador #{0}: '.format(i+1))
AttributeError: 'str' object has no attribute 'format'

Compartilhar este post


Link para o post
Compartilhar em outros sites

Novamente: o código que eu escrevi funciona na versão 3.1 do Python.

Como já foi comentado em um tópico por aqui, a série 3 quebra compatibilidade com a série 2 da linguagem/interpretador. Não foi à toa que eu disse p/ você ir atrás das mudanças principalmente nas strings.

 

http://www.python.org/dev/peps/pep-3101/

 

Fica extremamente difícil dizer o que funciona e o que não funciona se você não informar a versão do interpretador.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Novamente: o código que eu escrevi funciona na versão 3.1 do Python.

Como já foi comentado em um tópico por aqui, a série 3 quebra compatibilidade com a série 2 da linguagem/interpretador. Não foi à toa que eu disse p/ você ir atrás das mudanças principalmente nas strings.

 

http://www.python.org/dev/peps/pep-3101/

 

Fica extremamente difícil dizer o que funciona e o que não funciona se você não informar a versão do interpretador.

 

Eu ja tinha dito, utilizo o python 3.1 com o NetBeans. Vcs recomendam outra IDE ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Viciado, eu não creio muito que você utilize a versão 3.1, pois aqui na 3.1.3, se eu digitar print 4 no interpretador, ele acusa erro de sintaxe. Isso também ocorreu com o Ctrl+C Ctrl+V do código, pois os prints usados não são funções. Se o PEP não estiver errado/mal-escrito, o print passou a ser uma função a partir da versão 3.0, ou seja, a série 3.x obriga você a usar os parênteses. Na versão 2.6, esse comportamento está disponível se você importar o módulo __future__, caso contrário, o print continua funcionando como "comando".

Além disso, o método format está presente na versão 3.1, então seria impossível o interpretador reclamar (esse método existe desde a versão 2.6, mas creio que nessa versão ainda é necessário explicitar que a string é Unicode colocando a letra u na frente dela)

O que você informou no tópico foi que utiliza o Netbeans no Windows Seven. Veja onde está instalado o binário do interpretador e execute num prompt de comando p/ ver a versão (acho isso mais fácil que tentar encontrar na IDE).

 

IDE é opcional. Na verdade eu acho desnecessário uma IDE p/ Python, já que, comparado a C#,C++ ou Java, é uma linguagem muito simples.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Veja onde está instalado o binário do interpretador e execute num prompt de comando p/ ver a versão (acho isso mais fácil que tentar encontrar na IDE).

 

Python 3.1.3

 

Eu uso IDE, pq nao sei como executar na linha de comando, eu crio o arquico .py e como faço para executar esse arquivo na linha de comando que vem junto com a instalação do python ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cara, a documentação do Python explica um pouco disso... Se o problema for inglês, executar programa python windows no Google resolve (tem até vídeo no youtube). E eu realmente aconselho você a largar mão de material de programação traduzido e ler em inglês, principalmente os livros.

 

Python 3.1.3? Certeza? você copiou e colou o código do primeiro post e nem apareceu um erro de sintaxe nos print? Se não apareceu é pq não é 3.1.3. O shell interativo também informa a versão do interpretador. Eu realmente estou estranhando você usar a 3.1.3 porque o código que eu fiz foi na 3.1.3, num Windows Seven. E funciona 100% aqui.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.