views:

547

answers:

5

I am raising exceptions in two different places in my Python code:

holeCards = input("Select a hand to play: ")
try:
    if len(holeCards) != 4:
        raise ValueError(holeCards + ' does not represent a valid hand.')

AND (edited to correct raising code)

def __init__(self, card):
  [...]

  if self.cardFace == -1 or self.cardSuit == -1:
    raise ValueError(card, 'is not a known card.')

For some reason, the first outputs a concatenated string like I expected:

ERROR: Amsterdam does not represent a valid hand.

But, the second outputs some weird hybrid of set and string:

ERROR: ('Kr', 'is not a known card.')

Why is the "+" operator behaving differently in these two cases?

Edit: The call to init looks like this:

  card1 = PokerCard(cardsStr[0:2])
  card2 = PokerCard(cardsStr[2:4])
+5  A: 

"card" probably represents a tuple containing the string "Kr." When you use the + operator on a tuple, you create a new tuple with the extra item added.

edit: nope, I'm wrong. Adding a string to a tuple:

>> ("Kr",) + "foo"

generates an error:

TypeError: can only concatenate tuple (not "str") to tuple

It would probably be helpful to determine the type of "card." Do you know what type it is? If not, try putting in a print statement like:

if len(card) != 2:
    print type(card)
    raise ValueError(card + ' is not a known card.')
Barry Fandango
I thought it was a string and, when I output type(card), I get <class 'str'>
Jekke
A: 

Have you overloaded the __add__() somewhere in the code, that could be causing it to return a tuple or something?

codelogic
No. I don't understand why the question is germane either.
Jekke
Because it's possible to modify the behavior of the '+' operator dynamically.
codelogic
I understand the question, but I'm not touching the definition of __add__.
Jekke
+1  A: 

In the second case card is not a string for sure. If it was a string then len('2') would be equal to 2 and the exception wouldn't be raised, so check first what are you trying to concatenate, it seems something that added to a string returns something represented as a tuple.

I recommend you to use string formatting instead of string concatenation to create the error message. It will use the string representation (__repr__) of the object.

With string formatting:

>>> "%s foo" % (2)
'2 foo'

With string concatenation:

>>> 2 + " foo"
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: unsupported operand type(s) for +: 'int' and 'str'

And other question... what python version/implementation are you using? My cpython interpreter on Linux reports ValueErrors as ValueError, not ERROR...

Jaime Soriano
Whoops. Wrong raiser. I corrected in the original question.
Jekke
I'm using Python 3.0 for Windows with IDLE.
Jekke
(And, I should have added that the 'ERROR: ' is something I concatenated on the front, not the result of the exception raised.
Jekke
You are not using concatenation in one of the cases :)
Jaime Soriano
+7  A: 

Um, am I missing something or are you comparing the output of

raise ValueError(card, 'is not a known card.')

with

raise ValueError(card + ' is not a known card.')

???

The second uses "+", but the first uses ",", which does and should give the output you show!

(nb. the question was edited from a version with "+" in both cases. Perhaps this question should be deleted???)

Andrew Jaffe
Yup, in the original code snippet, he was using '+' in both cases.
codelogic
+4  A: 

This instantiates the ValueError exception with a single argument, your concated (or added) string:

raise ValueError(holeCards + ' does not represent a valid hand.')

This instantiates the ValueError exception with 2 arguments, whatever card is and a string:

raise ValueError(card, 'is not a known card.')
mluebke