Python Float Division problem

OK, I’m trying to calculate ‘hit percentage’ for my game. The script below does what I want it to but the problem is I get the error “ZeroDivisionError: float division.” How do I get rid of the error and what is the ‘correct’ way to use float division with BGE?

import GameLogic as GL
cont = GL.getCurrentController()
own = cont.getOwner()

shots = GL.getCurrentScene().getObjectList()["OBShots"]
hits = GL.getCurrentScene().getObjectList()["OBHits"]

if own. ini == 1:

    shots.a = shots.Text
    hits.b = hits.Text
    percent = round((shots.a / hits.b) * 100.0, 1)  #the error points to this line, of course
    own.Text = str(percent)
    
    own.ini = 0

Hmm, that doesn’t look like it would work at all, because:

If “shots.Text” and “hits.Text” are string variables you use to display text in game (as I suspect they are), then “shots.a” and “hits.b” are both set to strings.

What do you think happens when you try to perform division on strings?

You shouldn’t be getting the right result that way (if you are, then please post the .blend, so that I can see how this is working out). Instead of creating “shots.a” and “hits.b” and then setting them to strings, just use those source integers from which your “.Text” variables get their values in the first place, and typecast them to floats “float(hits)/float(shots) * 100” (because regular python division just truncates).

Also notice that hits are divided by shots, not the other way around as you have it (which I think is wrong - assuming that shots are “shots taken” and hits are “shots that hit target”).

To stop “division by zero” errors…you have to stop division by zero. So, if shots are equal to 0, then you didn’t fire yet, and therefore you don’t run the percentage code, instead you just set percentage to 100 or 0, depending on what you want to start at.

…I feel dirty for some reason.

Thank you Social! It’s good to know we have some Python help here. Now I don’t feel as ‘dirty’ as I did earlier.

Actually, the script in question gets it’s property values from a ‘load’ script (menu). The hit and shot properties were not strings (but neither float or int worked) The error (I think) was occurring before it loaded as I had zeros for properties…like you said… Oh, and thanks for catching my backwards-ness. I never even realized it. I had the math right, but the names wrong.

…long story short…no more error…

But now I have another quick question: How do I get rid of all those annoying zeros? I only need 1 decimal, NOT seven. Here’s my new script:

percent = float(hit) / float(shot) * 100
  own.Text = round(percent, 1)
  • I know I can make “own.Text” a string to get rid of the zeros, but I want to keep it a real number.
  • Make your Text property an integer. This will get rid of the trailing zeros, but at the cost of being only able to display integers (not much of a loss in my view - I would go with this)
  • Make an additional property that will hold your “real number” as you call it, and have your text property set to string -> then you can format it however you see fit with either strip() or rstrip() or whatever else. So if that single decimal space really needs to be there, this is the way to go.

Yeah, I thought there might be a convenient way to turn off some decimal places that I didn’t know about. Not sure exactly how to use the strip() method. I did figure out you can use “round” and then “str(x)” for the same affect.

It’s not that I care really if the decimal is there, it’s more about learning Python and the BGE.

Thanks again.