2014-11-29 5 views
-1

두 개의 카드를 무작위로 처리하는 프로그램을 만들려고합니다. 그러나, 오류 팝업 계속 :유형 객체 x에는 속성이 없습니다. y

AttributeError: type object `CardPack` has no attribute `suits` 

나는 잘 모르겠지만, 나는이 클래스 CardPack이 값 suits이없는 것을 의미합니다 생각합니다. 그러나 __init__ 함수에서 정의됩니다. 나는 완전히 난감한 처지입니다.

클래스 코드 : 실행

import random 

class CardPack: 
    def __init__(self): 
     self.cardsClubs = ["A C", "2 C", "3 C", "4 C", "5 C", "6 C", "7 C", "8 C", "9 C", "10 C", "J C", "Q C", "K C"] 
     self.cardsSpades = ["A S", "2 S", "3 S", "4 S", "5 S", "6 S", "7 S", "8 S", "9 S", "10 S", "J S", "Q S", "K S"] 
     self.cardsHearts = ["A H", "2 H", "3 H", "4 H", "5 H", "6 H", "7 H", "8 H", "9 H", "10 H", "J H", "Q H", "K H"] 
     self.cardsDiamonds = ["A D", "2 D", "3 D", "4 D", "5 D", "6 D", "7 D", "8 D", "9 D", "10 D", "J D", "Q D", "K D"] 
     self.cardsDealt = [] 
     self.suits = ["C", "S", "H", "D"] 

    def getRandomCards(self): 
     card = "" 
     if random.choice(self.suits) == "C": 
      card = random.choice(self.cardsClubs) 

     elif random.choice(self.suits) == "S": 
      card = random.choice(self.cardsSpades) 

     elif random.choice(self.suits) == "H": 
      card = random.choice(self.cardsHearts) 

     elif random.choice(self.suits) == "D": 
      card = random.choice(self.cardsDiamonds) 
     else: 
      pass 

     return card 

    def deal(self): 
     cards = 1 

     while cards != 3: 
      self.cardsDealt[cards] = self.getRandomCards(self) 

     return self.cardsDealt 

파일 생성 예 :

#DEALING TEST 
from DeckDealer import CardPack 

Dealer = CardPack 

cards = Dealer.deal(CardPack) 

print("Your cards are %s and %s!" % (cards[1], cards[2])) 
+1

난 당신이'의미 생각 판매점 = CardPack()' –

+0

'dict' 사용을 고려 셀프 카드 = { 'C': [ 'A C', '2 C', ...], 'S': [...],}'그리고 나중에'suit = random.choice (('C', 'S', 'H', 'D')); 카드 = random.choice (self.cards [suit])'. 또한, 동일한 카드를 두 번이나 (컴퓨터를 상대로 연주하는 경우에는 더 이상) 다루지 않는 코드는 없습니다. – gboffi

+0

또 다른 코드 검토 의견은 if-stack에서 무작위로 선택한 슈트를 반복하지 마십시오! 한 번 양복을 선택하고 if-stack에서 양복 값을 사용하고 싶습니다. – gboffi

답변

2
Dealer = CardPack 

이 줄을 당신의 CardPack 형식의 인스턴스를 생성하지 않습니다, 그것은 단지 복사에 대한 참조. 따라서 Dealer.deal()으로 전화를 걸면 본질적으로 인스턴스 속성에 액세스 할 수없는 CardPack.deal()을 수행하게됩니다.

대신, 인스턴스를 생성해야하고 해당 인스턴스에 메서드를 호출 : 그 맥락에서

dealer = CardPack() 
cards = dealer.deal() 

를,이 메소드를 호출하는 점에 유의하는 것도 중요합니다, 당신은 하지 통과 할 selfself은 인스턴스에서 메서드를 호출 할 때 암시 적으로 설정됩니다. 따라서 dealer.deal()을 입력하면 self이 자동으로 딜러 인스턴스로 설정됩니다. dealer.deal(dealer)에 전화 할 경우 메서드에없는 매개 변수를 전달하므로 오류가 발생합니다. 또한 getRandomCards 전화가 deal 인 경우 문제가 발생합니다. 은 두 번째 매개 변수로 설정되어 오류가 발생합니다. 그냥 self.getRandomCards()하고 싶은 일을하고 싶습니다. 당신이 한 cards 그대로 반복 유지로

말했다되고 그건

이, 당신의 deal 방법은 무한 루프가 않습니다 없습니다 3하지만 cards의 값을 변경하지 마십시오. 따라서 루프의 값을 증가 시키려고합니다. 그러나 심지어 빈 목록에 cardsDealt[cards]에 액세스하면 IndexError가 발생하므로 수정해야합니다. 먼저 목록을 재설정 한 다음 append 개의 새 카드를 새로 만들 수 있지만 3 개의 카드로 동시에 새로운 목록을 만드는 것이 더 좋습니다.이 간단하고 짧은 만들기 위해 지능형리스트를 사용할 수 있습니다

def deal(self): 
    self.cardsDealt = [self.getRandomCards() for card in range(3)] 
    return self.cardsDealt 

마지막으로, getRandomCards 당신이 그것을 할 것으로 예상 정확히 무엇을하지 않을 수 있습니다. 일반적으로 모든 카드가 동일한 기회를 가질 것으로 기대합니다. 그러나 클럽 카드는 1/4의 확률, 스페이드 카드의 확률은 3/16, 하트 카드는 9/64의 확률, 다이아몬드 카드의 확률은 27/256입니다. 이로 인해 카드가이 아닌 을 얻으려면 81/256의 기회가 남습니다. 이것은 분명히 정확하지 않습니다.

모든 테스트에 대해 임의의 선택을하는 이유입니다. 따라서 클럽 카드가 있는지 여부를 테스트하려면 선택하십시오 (1/4 기회). 만약 당신이 (3/4의 확률로) 얻지 못한다면, 스페이드 카드를 얻는 다른 선택을하게됩니다 (1/4 기회, 그래서 3/4 * 1/4 합계). 대신에, 선택 한 번만 다음 하위 카테고리에 대해 그 결과를 다시 사용 :이 또한 당신은 항상 네 벌 중 하나를 얻을 수 있기 때문에 당신이 방법에서 임의의 카드를하지 않는 것은 불가능 것을 만드는

def getRandomCards(self): 
    # only make *one* random choice for the suit 
    suit = random.choice(self.suits) 

    if suit == "C": 
     return random.choice(self.cardsClubs) 
    elif suit == "S": 
     return random.choice(self.cardsSpades) 
    elif suit == "H": 
     return random.choice(self.cardsHearts) 
    elif suit == "D": 
     return random.choice(self.cardsDiamonds) 

.


마지막으로 2 장의 설명에 언급 된 gboffi와 같이 여러 개의 동일한 카드를 가져올 수있는 보호 장치가 없습니다. 가능한 대부분의 게임에서 가능한 동일한 카드의 세 배를 getRandomCards()에서 얻을 수는 있지만 (여전히 가능하지는 않습니다) 가능하지 않습니다.

이 문제를 방지하려면 모든 카드 목록에 random.sample을 사용할 수 있습니다. 이렇게하면 명확하게 구별되는 세 개의 카드 (또는 임의의 수의 카드)를 얻을 수 있습니다. 또한 게임을 다시 시작할 때까지 데크에서 빠져 나오는 카드를 그릴 실제 "데크"를 가질 수 있습니다. 당신이 다음에서 그릴 수있는 새로운 하나를 만들어

self.deck = self.cardsClubs + self.cardsSpades + self.cardsHearts + self.cardsDiamonds 

이것은 본질적으로 모두 네 개의 카드 목록을 결합 :

당신의 설치와

,이 같은 새로운 데크 만들 수 있습니다. 그들로부터 세 가지를 그리려면이 같은 random.sample 사용할 수 있습니다

drawnCards = random.sample(self.deck, 3) 

을 그리고 당신은 갑판에서 그 카드를 제거 할 수 있습니다 :

for card in drawnCards: 
    self.deck.remove(card) 

또 다른 방법은 좀 더 실제 방법을 수행하는 것 면밀히. 임의의 카드를 드로잉하는 대신 (정렬 된) 데크에서 먼저 덱을 섞은 다음 상단에서 카드를 뽑을 수 있습니다. 목록, 당신은 random.shuffle을 사용할 수 있으며, 그릴 및 목록에서 카드를 제거 셔플하려면 list.pop 사용할 수 있습니다

# create the deck 
self.deck = self.cardsClubs + self.cardsSpades + self.cardsHearts + self.cardsDiamonds 

# shuffle the deck 
random.shuffle(self.deck) 

# and then draw three cards from it 
drawnCards = [self.deck.pop() for i in range(3)] 
+0

좋은 일, 멍청이. 내 대답을 게시하는 것은 아무런 의미가 없다고 생각합니다. :) –

+0

Welp, 그 대답은 예상보다 오래 걸렸습니다. 오 잘 : D 조 – poke

3

당신은 여기 예를 생성되지 않습니다

Dealer = CardPack 

받는 또 다른 기준이다 클래스 (유형), __init__ 메서드도 호출되지 않습니다.

전화 클래스는 인스턴스를 생성합니다 :

Dealer = CardPack() 
관련 문제