1. We have added a Gift Upgrades feature that allows you to gift an account upgrade to another member, just in time for the holiday season. You can see the gift option when going to the Account Upgrades screen, or on any user profile screen.
    Dismiss Notice

Python Round woes.

Discussion in 'Civ4 - Creation & Customization' started by Goombaz, Nov 26, 2005.

  1. Goombaz

    Goombaz Warlord

    Joined:
    Sep 11, 2005
    Messages:
    297
    I am messing around with the python and so far, I have achieved the result I wanted. I modified the basic year display to display CurrentTurn/MaxTurns and the year instead of just the year.

    In addition to this, I am trying to make it display the percentage of the game that has elapsed. This is the code in-total for what I have done so far.

    This is in the CvMainInterface.py file(well, a copy of it in my mod directory anyhow).

    g_szTimeText = unicode(gc.getGame().getGameTurn()+1) + "/" + unicode(gc.getGame().getMaxTurns()) +" " + unicode(round(100*((1.00*(gc.getGame().getGameTurn()+1)) / gc.getGame().getMaxTurns())),2) + "% " + unicode(CyGameTextMgr().getInterfaceTimeStr(ePlayer))

    I know, it is horribly messy.

    This is the part I am concerned with:

    unicode(round(100*((1.00*(gc.getGame().getGameTurn()+1)) / gc.getGame().getMaxTurns())),2)

    It works fine if I type it as:

    unicode((100*((1.00*(gc.getGame().getGameTurn()+1)) / gc.getGame().getMaxTurns())))

    or as:

    unicode(int(100*((1.00*(gc.getGame().getGameTurn()+1)) / gc.getGame().getMaxTurns())))

    The problem is, however, that the former has like a 10 digit decimal and looks way too ugly, and the latter isn't quite as fine as I wanted, as whole percentages aren't helpful, and I don't like the idea of 2.99% being shown as 2%. When I attempt to do the round-to-two places as I show above, it simply no longer prints the line to the screen at all...

    Does anyone have any idea why it renders it unprintable?
     
  2. Bjornlo

    Bjornlo Deity

    Joined:
    Dec 22, 2004
    Messages:
    3,701
    Location:
    Hjørungavåg
    Wrong forum. You posted in the civ3 forum. I've let the mods know to move this thread.
     
  3. Goombaz

    Goombaz Warlord

    Joined:
    Sep 11, 2005
    Messages:
    297
    Oh, thanks. I must have misclicked, yes tell them right away.
     
  4. Padma

    Padma the Inbond Administrator Supporter

    Joined:
    Dec 10, 2001
    Messages:
    14,408
    Location:
    Omaha, Nebraska USA
    Moderator Action: Moved to Civ4 C&C.
     
  5. Goombaz

    Goombaz Warlord

    Joined:
    Sep 11, 2005
    Messages:
    297
    :bump:

    Sorry this has been moved/buried so I thought I would bump it once for another go at an answer. I realize I could check a bunch of python references directly, but this is really all I want right at the moment so a direct, simple answer would be preferred.
     
  6. Requies

    Requies Prince

    Joined:
    Nov 15, 2005
    Messages:
    381
    No clue. Though you could enable logging and then print out what that is using CvUtil.pyPrint. Just to see if it's actually calculating it correctly. Also, why are you multiplying by 1.00? To convert to float? If so, why not use the float() function?

    Req
     
  7. Bhruic

    Bhruic Emperor

    Joined:
    Nov 15, 2005
    Messages:
    1,457
    Well, unless you've typed it out differently here than in the script, it's merely a () problem.

    Ie, this should work:
    unicode(round(100*((1.00*(gc.getGame().getGameTurn()+1)) / gc.getGame().getMaxTurns()), 2))

    Bh
     
  8. Goombaz

    Goombaz Warlord

    Joined:
    Sep 11, 2005
    Messages:
    297
    When I made the change you suggested Bhuric, for some reason that I can't fathom it goes back to the 10ish place decimals :/
     
  9. snarko

    snarko DLLer

    Joined:
    Dec 9, 2003
    Messages:
    1,512
    Location:
    Sweden
    Not only does it show a weird result (~10 decimals), it shows a wrong one too!
    Try unicode(round(1.1111, 2))

    The result for me is 1.11000001431
     
  10. Goombaz

    Goombaz Warlord

    Joined:
    Sep 11, 2005
    Messages:
    297
    Well that definately isn't good, is it? I'll have to find a way around this.
     
  11. Bhruic

    Bhruic Emperor

    Joined:
    Nov 15, 2005
    Messages:
    1,457
    Well, a cheap way to get around the problem is to multiply the number by 100, change it to an int, then divide it by 100.

    Bh
     
  12. Goombaz

    Goombaz Warlord

    Joined:
    Sep 11, 2005
    Messages:
    297
    I actually tried that already Bhuric. Oddly enough dividing it by 100 results in a really really long number even AFTER it was chopped into a pure INT before dividing. It looks like it STARTS to work alright, like you get 1.25ish, but it is instead something like 1.25000000001441 or 1.249999999991441. It's like it's not *quite* accurate.

    I honestly think Civ 4 python has some kind of deep-seated floating point issue. Like there is some kind of garbage in the numbers you can't quite get past. I really hope I am being naive about this, because if that is the case it could be a nasty bug. I will go back and try that cheap solution again, I am fairly sure it won't work as I already tried it but perhaps the exact numbers involved would provide insight into the nature of the problem.
     
  13. Goombaz

    Goombaz Warlord

    Joined:
    Sep 11, 2005
    Messages:
    297
    Ok, here is the latest on the problem. I have posted the code I used to compute the percentage as well as a column of results showing the problem in detail in a real use scenario. I hope that perhaps this will be detailed enough to lead to a fix or a workaround. This is the code as per Bhurics suggestion and the unfortunate result.

    unicode((int(10000*(float(gc.getGame().getGameTurn()) / gc.getGame().getMaxTurns())))/100.0)

    is the code used.

    This is the result generated.



    Click thumbnail for detailed info.

    The essence of the problem seems to be the "trailing junk" that seems to result when dividing.
     
  14. Rayanth

    Rayanth Prince

    Joined:
    Sep 16, 2005
    Messages:
    303
    This may sound odd but... have you had anyone else test your code on another system to make sure it duplicates the issue for them?

    also, i know it's tricky to work with but try pumping the numbers through a short script that mimics what's going on in Civ4, in the Python environment and run it (without Civ4) in IDLE/debug mode.

    The reason i ask about trying it on another system is that there is still an occasional processor out there with the FLOP bug that Intel was notoriuos for in the older P3 line. The issue you are having is similar to that bug (but more frequent/reproducable than the hardwre FLOP bug... I doubt it's actually the case...)
     
  15. Goombaz

    Goombaz Warlord

    Joined:
    Sep 11, 2005
    Messages:
    297
    That is a good point. I will go grab the Python environment and fire it up.

    Tell you what, I will post the buggy version and see if you get the same result. Anyone who wants to is invited to give it a go and report back to me. If it IS a bug with Civ 4 Python specifically it could be important to get the word out, or at least find a workaround.

    If you (or anyone else reading this) feel like it download this version, fire it up, and tell me what you get.

    Also it is entirely possible that I am just a fool. Don't keep me hanging if I have made a downright stupid mistake.
     

    Attached Files:

  16. DeathCyclops

    DeathCyclops Chieftain

    Joined:
    Nov 12, 2005
    Messages:
    87
    Location:
    In the tree, next to your house
    I got the same exact thing as you did.:crazyeye:
     
  17. Goombaz

    Goombaz Warlord

    Joined:
    Sep 11, 2005
    Messages:
    297
    Ok situation update. I put this through IDLE on python 2.4.2

    >>> unicode((int(10000*(float(19) / 440)))/100.0)
    u'4.31'

    and this corresponds to the result for turn 19/440, which was

    4.30999994278

    which I think you will agree, is extremely close to 4.31.

    So for whatever reason the python within Civ 4 is not accurate with decimals.

    Can anyone more qualified than me (I am an intermediate programmer, but *very* new to Python) confirm or disconfirm this problem specific to Civ 4 Python? IDLE is rounding correctly, Civ 4 is not. Or I am doing something wrong I suppose:crazyeye:
     
  18. DeathCyclops

    DeathCyclops Chieftain

    Joined:
    Nov 12, 2005
    Messages:
    87
    Location:
    In the tree, next to your house
    Maybe i'll post what I did to the file... Now im getting 2%, 4%, 6% 9%!!!!!!

    Here: g_szTimeText = unicode(gc.getGame().getGameTurn()) + "/" + unicode(gc.getGame().getMaxTurns()) +" " + unicode((int(1000*(float(gc.getGame().getGameTurn()) / gc.getGame().getMaxTurns())))/1.0) + "%" + unicode(CyGameTextMgr().getInterfaceTimeStr(ePlayer))

    This new one is...perfect they are all whole numbers wooohoooo!!!!(um... just check to make sure so i dont embaress myself...) Just replace this with what you have and check if its the right scale and whatever stuff you need.
     
  19. DeathCyclops

    DeathCyclops Chieftain

    Joined:
    Nov 12, 2005
    Messages:
    87
    Location:
    In the tree, next to your house
  20. Goombaz

    Goombaz Warlord

    Joined:
    Sep 11, 2005
    Messages:
    297
    While I appreciate the effort, I already got that to work. The versions that I have up in the actual modpack thread work this way. Thank you for the attempt to help, however :)

    My current effort is to allow 2 decimal digits, which is not that much more clutter visually and allows for a much finer sense of the passage of time.
     

Share This Page