3

This post has been answered, read it if you like.

I have been attempting to write a card-game in python 3, and I have been using a for loop to transfer cards from a deck list to hand list. I'm attempting to put this into a function, but command prompt crashes. help?

from random import *
print("Sam's Casino")
cards = ['1','2','3','4','5','6','7','8','9','10','J',
'Q','K','1','2','3','4','5','6','7','8','9','10','J',
'Q','K','1','2','3','4','5','6','7','8','9','10','J',
'Q','K','1','2','3','4','5','6','7','8','9','10','J',
'Q','K']
shuffle(cards)
print(cards)
hand1 = []
hand2 = []
count = 0
def deal(cards):
    for card in cards:
        if count < 4:
            hand1.append(card)
            count += 1
        if count > 3 and count < 8:
            hand2.append(card)
            count += 1

deal(cards)
print(hand1)
print(hand2)
input('>')

Edit: No error is recieved, it simply closes.

  • Are you seeing some error? – Patrick Haugh Jun 14 '18 at 22:26
  • Where's your `shuffle()` function? – Michael Swartz Jun 14 '18 at 22:26
  • @MichaelSwartz `shuffle()` is part of `random` – JacobIRR Jun 14 '18 at 22:27
  • Command prompt may require more than one blank line to declare the end of loops, functions, etc. – JacobIRR Jun 14 '18 at 22:28
  • Which line is causing the error? – Chris Jun 14 '18 at 22:28
  • The shuffle() function is part of random, and I get no error – The Samstro Jun 14 '18 at 22:29
  • 1
    @JacobIRR .... it should not ... its indentation not endline that determines nesting in python – Joran Beasley Jun 14 '18 at 22:29
  • Put the `count` variable inside the `deal()` function. – Michael Swartz Jun 14 '18 at 22:29
  • 1
    I already answered but I have a question. Don't your cards also need suites? – Attersson Jun 14 '18 at 22:30
  • @JoranBeasley - no. It throws a syntax error in Windows 10 command prompt because it needs two blank lines before `deal(cards)` – JacobIRR Jun 14 '18 at 22:30
  • @JacobIRR ... nope it does not ... you need no blank lines in python ... you maybe using some strange flavor of python... but in general that is 100% not a true statement ... perhaps your ide corrected some tabs to spaces or something when you added your blank lines – Joran Beasley Jun 14 '18 at 22:32
  • 2
    @JoranBeasley No, the interactive interpreter (command prompt) does raise a `SyntaxError` if you finish a block and try to start a new statement in the same `...` prompt. – abarnert Jun 14 '18 at 22:34
  • lol ok i see ... yes if you paste it into the interactive interpretter, thanks for clarifying @abarnert – Joran Beasley Jun 14 '18 at 22:34
  • @JoranBeasley https://ibb.co/dHs2ud – JacobIRR Jun 14 '18 at 22:34
  • command prompt != python interactive interpretter – Joran Beasley Jun 14 '18 at 22:35
  • 1
    @JoranBeasley Yes, I assume that's what JacobiRR meant. (What he actually said was "throws a syntax error in Windows 10 command prompt", which… I guess is true, because `cmd` isn't a Python interpreter, but I don't think he meant that to be interpreted that literally…) – abarnert Jun 14 '18 at 22:35
  • 2
    Anyway, when you run this code, it does raise an exception. If you're seeing the program just exit with no error, you must not have pasted the same code here that you're running, which means all of the answers you're getting about fixing the code you pasted here are probably irrelevant to you, and your question is unanswerable. Please make sure you have a [mcve]. – abarnert Jun 14 '18 at 22:36

4 Answers4

5

UnboundLocalError: local variable 'count' referenced before assignment

Put count inside the function deal

def deal(cards):
    count = 0
    for card in cards:
        if count < 4:
            hand1.append(card)
            count += 1
        if count > 3 and count < 8:
            hand2.append(card)
            count += 1

This works.

Attersson
  • 4,755
  • 1
  • 15
  • 29
4

I don't know how to play this game, but I believe its crash is caused by naming scope problem(Python "assumes" that we want a local variable due to the assignment to count inside of deal(), so the first print statement throws this error message. Any variable which is changed or created inside of a function is local, if it hasn't been declared as a global variable), following is the code that works fine

from random import *
print("Sam's Casino")
cards = ['1','2','3','4','5','6','7','8','9','10','J',
'Q','K','1','2','3','4','5','6','7','8','9','10','J',
'Q','K','1','2','3','4','5','6','7','8','9','10','J',
'Q','K','1','2','3','4','5','6','7','8','9','10','J',
'Q','K']
shuffle(cards)
print(cards)
hand1 = []
hand2 = []
count = 0
def deal(cards):
    global count
    for card in cards:
        if count < 4:
            hand1.append(card)
            count += 1
        if count > 3 and count < 8:
            hand2.append(card)
            count += 1
deal(cards)
print(hand1)
print(hand2)
input('>')

more details regarding naming scope, please reference https://www.programiz.com/python-programming/global-local-nonlocal-variables or https://www.python-course.eu/global_vs_local_variables.php

Stephen Fong
  • 697
  • 5
  • 17
  • 1
    Also, putting `global` inside a loop, while legal, it a little confusing. – abarnert Jun 14 '18 at 22:37
  • 2
    its actually incorrect (at least the second time you have to deal) ... but that said i think this answer is just fine – Joran Beasley Jun 14 '18 at 22:38
  • 2
    Actually, that reference is kind of crap. Besides not being very good English, It talks about functions being "declared", which isn't a thing in Python, spends multiple paragraphs failing to explain shadowing, becomes complete gibberish by the time it gets to nonlocal variables, and never gets around to mentioning builtins, mutating values from globals/nonlocals without reassigning them, etc. (And it's also not even attempting to be a reference; it's a tutorial.) – abarnert Jun 14 '18 at 22:45
1

The reason why your code is crashing is because you're not defining count as global inside your deal function, read this thread to learn more about it.

Here's a possible fix of your code:

import random

print("Sam's Casino")
cards = ([str(i) for i in range(1, 10)] + ['J', 'Q', 'K']) * 4
random.shuffle(cards)
print(cards)
hand1 = []
hand2 = []
count = 0


def deal(cards):
    global count
    for card in cards:
        if count < 4:
            hand1.append(card)
            count += 1
        if count > 3 and count < 8:
            hand2.append(card)
            count += 1


deal(cards)
print(hand1)
print(hand2)
input('>')

That said, couple of advices, try to avoid global variables as much as possible and don't pollute the global namespace by using the star operator using statements such as from random import *. Here's a small refactoring of your code:

import random


class Game:

    def __init__(self):
        self.cards = ([str(i) for i in range(1, 10)] + ['J', 'Q', 'K']) * 4
        self.count = 0
        self.hand1 = []
        self.hand2 = []

    def deal(self):
        for card in self.cards:
            if self.count < 4:
                self.hand1.append(card)
                self.count += 1
            if self.count > 3 and self.count < 8:
                self.hand2.append(card)
                self.count += 1

    def run(self):
        print("Sam's Casino")
        random.shuffle(self.cards)
        print(self.cards)
        self.deal()
        print(self.hand1)
        print(self.hand2)
        input('>')


if __name__ == "__main__":
    Game().run()
BPL
  • 9,632
  • 9
  • 59
  • 117
0

Another option:

from random import *
print("Sam's Casino")
cards = ['1','2','3','4','5','6','7','8','9','10','J',
'Q','K','1','2','3','4','5','6','7','8','9','10','J',
'Q','K','1','2','3','4','5','6','7','8','9','10','J',
'Q','K','1','2','3','4','5','6','7','8','9','10','J',
'Q','K']
shuffle(cards)
print(cards)
hand1 = []
hand2 = []
count = 0
def deal(cards,count):
    for card in cards:
        if count < 4:
            hand1.append(card)
            count += 1
        if count > 3 and count < 8:
            hand2.append(card)
            count += 1

deal(cards,count)
print(hand1)
print(hand2)
input('>')

Output:

Sam's Casino
['1', '4', 'K', '5', '9', '3', 'J', '10', '8', '7', '8', 'J', 'Q', 'J', '5', '5', '10', 'K', '1', '8', '6', '9', '6', '5', '3', '1', 'Q', '2', '6', 'K', '10', '7', '1', 'Q', 'Q', '8', '7', '2', '3', '3', '6', '9', 'K', '7', 'J', '9', '2', '10', '4', '2', '4', '4']
['1', '4', 'K', '5']
['5', '9', '3', 'J']
>
U13-Forward
  • 69,221
  • 14
  • 89
  • 114