views:

300

answers:

6

I receive

TypeError: Can't convert 'float' object to str implicitly

while using

Gambler.pot += round(self.bet + self.money * 0.1)

where pot, bet, and money are all doubles (or at least are supposed to be). I'm not sure if this is yet another Eclipse thing, but how do I get the line to compile?

Code where bet and money are initialized:

class Gambler:
    money = 0
    bet = 0

Test case:

number = 0
print("Here, the number is a {0}".format(type(number)))
number = input("Enter in something: ")
print("But now, it has turned into a {0}".format(type(number)))

Output from test case:

Here, the number is a <class 'int'>
Enter in something: 1
But now, it has turned into a <class 'str'>

Apparently, input() is changing it to a string.

EDIT: Finally fixed the problem (I think) with

self.bet = int(self.bet.strip())

after the user inputs the value. Though I dunno if that's the best way to fix the problem :)

A better solution by Daniel G.:

self.bet = float(input("How much would you like to bet? $"))
+2  A: 

If any of Gambler.pot, self.bet or self.money have somehow become strings (because they were set to a string at some point), + will be taken to mean string concatenation which causes the error message you see.

rjh
It seems self.bet has after input :(
wrongusername
+2  A: 

Python3.2 (py3k:77602) gives these error messages:

>>> "1.2" * 0.1                                                #1
Traceback (most recent call last):
  File "", line 1, in 
TypeError: can't multiply sequence by non-int of type 'float'
>>> "3.4" + 1.2 * 0.1                                          #2
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't convert 'float' object to str implicitly
>>> n = "42"
>>> n += round(3.4 + 1.2 * 0.1)                                #3
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't convert 'int' object to str implicitly

I suspect your error message is because one of your actual values is a string instead of the expected float in a scenario similar to #2, which is an exact match for your exception.

If you could write a test case, that would be a big help.


Remember that Py3.x's input is identical to Py2.x's raw_input, and Py2.x's input is gone (it's equivalent to using evai, which you don't want to do). Because of this, input in 3.x will always return a string. Use int to convert:

n = int(input("Enter a number: "))

If you want to handle input errors, then catch ValueError, which is what int raises on errors:

try:
  n = int(input("Enter a number: "))
except ValueError:
  print("invalid input")
else:
  print("squared:", n*n)
Roger Pate
I'm using 3.1.1. I'll write the test case asap if I can :)
wrongusername
I did it... the problem seems to be that inputting something turns it into a string
wrongusername
Thanks for adding the extra information!
wrongusername
A: 

As was said in a comment, what you've shown is initializing local variables to 0. Instead try something like:

class Gambler:
    def __init__(self):
        self.bet = 0.0
        self.money = 0.0

    def calc_pot(self):
        self.pot = round(self.bet  + self.money * 0.1)

g = Gambler()
g.bet = 2.0
g.money = 5.0
g.calc_pot()

print "Pot = %f" % (g.pot)

Also, make sure there's nothing that might be turning those members into strings.

GreenMatt
+4  A: 

input() in 3.x only returns strings. It is the programmer's job to pass it to a numeric constructor in order to turn it into a number.

Ignacio Vazquez-Abrams
Yes... thank you!
wrongusername
I believe `input()` in 3.x is the same as `raw_input()` in 2.x
MatrixFrog
@MatrixFogg: I get `NameError: global name 'raw_input' is not defined` when trying that out. Am I doing something wrong?
wrongusername
@wrongusername: 3.x doesn't have `raw_input()`, only `input()`.
Ignacio Vazquez-Abrams
Oh! No wonder. Silly me :P
wrongusername
+2  A: 

In Python 3.x, input() replaces Python 2.x's raw_input(). Therefore, the function input() returns the exact string that the user input (as raw_input() did in previous versions).

To get Python 2.x behavior, you can just do

number = eval(input("Please enter a number: "))

However, I wouldn't recommend using "eval" since the user can put any line of Python they want in there, which is probably not what you want. If you know you want a float, just tell Python that's what you want:

number = float(input("Please enter a number: "))
Daniel G
Thanks! This worked for me too!
wrongusername
+4  A: 

Are you initializing pot? Have you tried storing intermediate results to track down here the problem is coming from? And finally, do you know about pdb? That may be a big help.

class Gambler:
    pot = 0.0
    def __init__(self, money=0.0)
        self.pot = 0.0
        self.bet = 0.0
        self.money = money

    def update_pot(self):
        import pdb; pdb.set_trace()
        to_pot = self.bet + self.money * 0.1
        to_pot = round(to_pot)
        Gambler.pot = Gambler.pot + to_pot

You will get a prompt when the set_trace() line is executed. Try looking at the current values when you get there.

(Pdb) h    # help
(Pdb) n    # go to next statement
(Pdb) l    # list source code
...
(Pdb) to_pot
...
(Pdb) self.bet
...
(Pdb) self.money
...
(Pdb) Gambler.pot
...
(Pdb) c    # continue
istruble
+1. Debuggers are under-used.
Roger Pate
+1 didn't know about the debugger
wrongusername