1

So i have this line of code:

fc = round((1+5*100)/100, 3) if fc_no_rocks == None else round(fc_no_rocks/100, 3)

that takes in a variable, whose type should be float. When I test the variable type using type(), it returns:

>>>type(fc_no_rocks)
<type 'float'>

but i keep getting an error that says "unsupported operand types for /: str and int.

15
  • 1
    Are you 100% sure the error is coming from this line? Commented Jul 18, 2013 at 20:43
  • 1
    The code works fine for e.g., fc_no_rocks = 1.1. So the error is somewhere else ;-) Commented Jul 18, 2013 at 20:44
  • 7
    Unrelated, but worth mentioning: You don't test against the None singleton using == but using is. Commented Jul 18, 2013 at 20:46
  • 1
    For the record, by "self-contained example" he meant "an example we can copy and paste into a fresh interpreter and see the problem". See this useful reference for more on what a "short self-contained correct example" is and why it matters. Commented Jul 18, 2013 at 20:51
  • 1
    Dylansq, the only way to get through this is if you post your relevant code (from where you create fc_no_rocks to that fc=blabla call) Commented Jul 18, 2013 at 21:01

4 Answers 4

3

Obviously, fc_no_rocks is a string in your case. That bug is on you. Better to check for several cases:

  1. fc_no_rocks is a number
  2. fc_no_rocks is a string indicating a number
  3. fc_no_rocks is neither of the above

You check to make sure that fc_no_rocks isn't None, but it could be anything. So it's better to check more exclusively at first, and then let your else case be the catch-all, i.e. neither/none of the above.

In one big mess of a ternary chain, it's this:

fc = round(float(fc_no_rocks)/100.0, 3) if isinstance(fc_no_rocks, str) and unicode(fc_no_rocks.replace('.','',1)).isnumeric() else round(fc_no_rocks/100.0, 3) if isinstance(fc_no_rocks, float) or isinstance(fc_no_rocks, int) else round((1+5*100)/100.0, 3)

Better to write it out in multiple lines, imo, but one-liners are such fun to write. It's like putting a bucket of water on top of a door that you know someone else is going to walk through. It sucks to be the person maintaining your code...! (By the way, make sure that you quit your job after writing this sort of stuff so that you don't have to be the one maintaining it.)

Anyway, output:

>>> fc_no_rocks = "2.3"
>>> fc = ...
>>> fc
0.023
>>> fc_no_rocks = "foobar"
>>> fc = ...
>>> fc
5.01
>>> fc_no_rocks = 1.3
>>> fc = ...
>>> fc
0.013
>>> fc_no_rocks = 6340
>>> fc = ...
>>> fc
63.4

If you want to debug right in the middle of that statement, I have good news:

>>> import sys
>>> fc_no_rocks = "foobar"
>>> fc = round(float(fc_no_rocks)/100.0, 3) if sys.stdout.write(str(type(fc_no_rocks))+"\n") or isinstance(fc_no_rocks, str) and unicode(fc_no_rocks.replace('.','',1)).isnumeric() else round(fc_no_rocks/100.0, 3) if isinstance(fc_no_rocks, float) or isinstance(fc_no_rocks, int) else round((1+5*100)/100.0, 3)
<type 'str'>
>>> fc
5.01

You can abuse the boolean or operator's behavior and the fact that the write() method always returns None! Hooray! You can also write repr(fc_no_rocks) instead if you want to see its representation - useful for getting both the contents of a string and an indication that yes, it is a string.

Edit: I'm running Python 2.7.2, so I had to add the decimal points to divide correctly. Woops!

Sign up to request clarification or add additional context in comments.

Comments

1

Why not just make sure fc_no_rocks is a float?

fc = round((1+5*100)/100, 3) if fc_no_rocks == None else round(float(fc_no_rocks)/100, 3)

7 Comments

If his fc_no_rocks holds a non-numeric value, this won't do any good
but the error says otherwise :) And, with a more critic eye, all I'm saying is don't force typecasts unless you really know what's going on .
@SamueleMattiuzzo: Hhm...good points. However, if that is the case, then he has something fundamentally wrong with his script. He says it should be a float, but the error says it is a string. This means that it is most likely something like '1.0', which float will fix. If it isn't--and is instead something like 'string'--then he has a major problem that has nothing to do with the line of code he gave.
It's still something you want to avoid, it may result in shadowing that "fundamentally wrong" bit in your script.
@2rs2ts: I understand that. My philosophy is this: fc_no_rocks should be a float. If it isn't a float, then the next most likely thing that it is is something like this: '1.0', which float will fix. However, if it is neither (and is a bool, or a list, or whatever), then the line of code he gave is not the problem. Instead, he has something seriously wrong in another part of his script. Hence, he should go and fix the part of his script that defines fc_no_rocks so that it makes it a float or something like "1.0". See where I'm going?
|
1

There was a for loop that had changed the variables so the fc_no_rocks was set to None. This made the logic when setting the fc variable switch to the left, where one of the variables i had replaces was also a string. sorry for the mixup

Comments

0

There is one other thing. round((1+5*100)/100, 3) there is nothing to round, because the numeric literals are all integers and the result of this integer equation (1+5*100)/100 which includes a division is 5, not 5.01 as you would expect. To repair it you have to use all decimal literals in every of your decimal calculations:

round((1.0+5.0*100.0)/100.0, 3)

EDIT: The repaired statement would result in 5.01, so you should be careful in other parts of your code.

5 Comments

Unless this is python3, in which case floats are returned on division
"i removed other int variables to clear it up a little;" Uhu... could it be possible that the problem is with these other (supposed) "int" variable ? Given the error message, the answer is very very certainly "yes".
I think he meant "value" not variable
@SamueleMattiuzzo: I think he really means "variable" and just replaced these other variables with int litterals in the snippet he posted.
The result is not 5.0, it is in fact 5.01... at least on my machine. Running 2.7.2.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.