Python Forum
random.choice Sensing Nonexistent Argument
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
random.choice Sensing Nonexistent Argument
#1
Hello again lol. As I continue my journey through learning the wonderful language of Python, I've made it to the point where I've started to learn classes. To practice and demonstrate my knowledge and learning of classes, I decided to make a random playing card generator, mostly because a friend I have who is learning Java made one. Below I've listed my code, and below the code I've listed the error statement my IDE prints out when I attempt to run it. 
import random

suits = ['Spade', 'Heart', 'Club', 'Diamond']
values = [2, 3, 4, 5, 6, 7, 8, 9, 10, 'Jack', 'Queen', 'King', 'Ace']

class card:
    'Common base class for all cards'
    def __init__(self, suit, value):
        self.suit = suit
        self.value = value

def drawnCard():
    'Common base function for drawn card'
    suitname = suits[random.choice(0, len(suits))] # here is where I think the error in the code is
    valuename = values[random.choice(0, len(values))] # here as well
    cardDrawn = card(valuename, suitname)
    print cardDrawn

drawnCard()
Error:
/System/Library/Frameworks/Python.framework/Versions/2.6/bin/python2.6 "/Users/Milli/PycharmProjects/untitled1/Classy Card Generator.py" Traceback (most recent call last):   File "/Users/Milli/PycharmProjects/untitled1/Classy Card Generator.py", line 19, in <module>     drawncard()   File "/Users/Milli/PycharmProjects/untitled1/Classy Card Generator.py", line 14, in drawncard     suitname = suits[random.choice(0, len(suits))] # works like typename[position], but instead of you setting the positon, random.choice chooses the position for you TypeError: choice() takes exactly 2 arguments (3 given) Process finished with exit code 1
The second to last line in the error statement is the one I have trouble understanding, and struggle to find the problem and solve it. 
Error:
TypeError: choice() takes exactly 2 arguments (3 given)
Last time I checked my code, I only inputted 2 arguments to both of my uses of random.choice(), unless len() turns out to be two arguments and not one. Any help that you can give is much appreciated.
Reply
#2
You're right that the problem is on this line
suitname = suits[random.choice(0, len(suits))] # here is where I think the error in the code is
It looks like what you're trying to do is say, get a random number in the range [0, len(suits)) (using math notation here), then take that number and use it to get the string at that index in the suits list. But random.choice takes in a sequence, not two arguments (I'll come back to this)
The Docs Wrote:Return a random element from the non-empty sequence seq.
So it looks like what you meant was
suits[random.choice(range(0, len(suits)))]
which can be simplified by leaving out the 0 in range() (which is implied) and better yet, skipping indexes all together
random.choice(suits)
Ok, all that said, you're right that the error message was confusing.

The reason for this, it turns out, is that choice (as an implementation detail) is a method, not a function. So it's coupled to a class, not free-floating. We can introspect on this
Output:
>>> import random >>> type(random.choice) <type 'instancemethod'> >>> import heapq >>> type(heapq.merge) <type 'function'>
Now you might ask why random.choice is a method instead of a function, and the reason is that the method is stateful and the designer of the implementation chose to encapsulate that state in a class rather than a global variable. That's actually a pretty advanced thing, so if you are not sure about it now feel free to come back to it later. But you can just as easily as they did create a module and make available for import a method on an instance rather than a regular function.

As to why Python does not give you a better error message... it would be easy to wrap the function, but that would slow things down. I verified that Python 3 does not give a better error message either, which is unfortunate, but it is definitely the kind of thing that you could request a feature for improving.
Reply
#3
You might also want to look at this thread: http://python-forum.io/Thread-Card-Deali...n-code-2-7
Reply
#4
I should have mentioned as well, there's no need for a class here. Java forces OOP when it isn't needed. There are times when it's reasonable, of course, but for what you have here I think procedural is fine.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  combobox_callback(choice choice part of openfile name (kind of dependency) janeik 9 1,455 Sep-10-2023, 10:27 PM
Last Post: janeik
  random.choice HELP samuelbachorik 4 2,281 Aug-18-2021, 03:24 PM
Last Post: naughtyCat
  Unable to use random.choice(list) in async method spacedog 4 3,449 Apr-29-2021, 04:08 PM
Last Post: spacedog
  Help with a random.randint choice in Python booponion 5 2,814 Oct-23-2020, 05:13 PM
Last Post: deanhystad
  trying to input a variable using random.choice python63 9 3,651 Aug-13-2020, 05:37 PM
Last Post: python63
  Random Choice Operations Souls99 6 2,950 Jul-31-2020, 10:37 PM
Last Post: Souls99
  random.choice() takes two positional arguments, but three were given. ShakeyPakey 5 11,726 May-31-2020, 03:13 PM
Last Post: deanhystad
  SyntaxError: positional argument follows keyword argument syd_jat 3 5,847 Mar-03-2020, 08:34 AM
Last Post: buran
  Using Force Sensing Resistors and sould files with Python learnercoder 1 2,681 Apr-01-2018, 06:45 PM
Last Post: Larz60+

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020