Yes - that Jake.
Yes - that Jake.

Reputation: 17119

Why does concatenation work differently in these two samples?

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])

Upvotes: 1

Views: 3257

Answers (5)

Andrew Jaffe
Andrew Jaffe

Reputation: 27087

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???)

Upvotes: 8

mluebke
mluebke

Reputation: 8819

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.')

Upvotes: 4

Jaime Soriano
Jaime Soriano

Reputation: 7359

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...

Upvotes: 1

codelogic
codelogic

Reputation: 73622

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

Upvotes: 0

James Orr
James Orr

Reputation: 5135

"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.')

Upvotes: 6

Related Questions