Python Round woes.

First sorry bout the repeat reply looked under mod thread to see if it posted. Anyway here it is

g_szTimeText = unicode(gc.getGame().getGameTurn()+1) + "/" + unicode(gc.getGame().getMaxTurns()) +" " + unicode(int(100*((1.00*(gc.getGame().getGameTurn()+1)) / gc.getGame().getMaxTurns()))) + "." + unicode((int(10000*((1.00*(gc.getGame().getGameTurn()+1)) / gc.getGame().getMaxTurns()))) - (100*(int(100*((1.00*(gc.getGame().getGameTurn()+1)) / gc.getGame().getMaxTurns()))))) + "% " + unicode(CyGameTextMgr().getInterfaceTimeStr(ePlayer))

Even more messy, tried setting new variables to but could never get it right.
So I stuck to the originals. Basic breakdown is

unicode(int(100*((1.00*(gc.getGame().getGameTurn()+1)) / gc.getGame().getMaxTurns()))) sets the Whole Digits.

The ".' puts a period on the screen beside the whole digits.

unicode((int(10000:goodjob: *((1.00*(gc.getGame().getGameTurn()+1)) / gc.getGame().getMaxTurns()))) - (100:goodjob: *(int(100*((1.00*(gc.getGame().getGameTurn()+1)) / gc.getGame().getMaxTurns()))))) sets the two decimals.

The part after the minus sign is important or the percentage at turn#5 would look like this: 1.113. It takes the extra decimal place of and voila you have what you are looking for which is 1.13

There probaly is a simpler way of doing this but this will definately get the job done. Hope you find this useful. To get an extra decimal place simply add another zero where The green faces are.

Parenthesis tracking is pure hell
 
dlordmagic said:
First sorry bout the repeat reply looked under mod thread to see if it posted. Anyway here it is

g_szTimeText = unicode(gc.getGame().getGameTurn()+1) + "/" + unicode(gc.getGame().getMaxTurns()) +" " + unicode(int(100*((1.00*(gc.getGame().getGameTurn()+1)) / gc.getGame().getMaxTurns()))) + "." + unicode((int(10000*((1.00*(gc.getGame().getGameTurn()+1)) / gc.getGame().getMaxTurns()))) - (100*(int(100*((1.00*(gc.getGame().getGameTurn()+1)) / gc.getGame().getMaxTurns()))))) + "% " + unicode(CyGameTextMgr().getInterfaceTimeStr(ePlayer))

Even more messy, tried setting new variables to but could never get it right.
So I stuck to the originals. Basic breakdown is

unicode(int(100*((1.00*(gc.getGame().getGameTurn()+1)) / gc.getGame().getMaxTurns()))) sets the Whole Digits.

The ".' puts a period on the screen beside the whole digits.

unicode((int(10000:goodjob: *((1.00*(gc.getGame().getGameTurn()+1)) / gc.getGame().getMaxTurns()))) - (100:goodjob: *(int(100*((1.00*(gc.getGame().getGameTurn()+1)) / gc.getGame().getMaxTurns()))))) sets the two decimals.

The part after the minus sign is important or the percentage at turn#5 would look like this: 1.113. It takes the extra decimal place of and voila you have what you are looking for which is 1.13

There probaly is a simpler way of doing this but this will definately get the job done. Hope you find this useful. To get an extra decimal place simply add another zero where The green faces are.

Parenthesis tracking is pure hell

Well, that DOES solve the problem.... It just seems so...... inelegant :lol:.

Oh, BTW float() is your friend :D.

Req
 
That actually is accurate. The problem is because they're using floats instead of doubles; floats are less accurate and will lead to 4.99999998 instead of 5, etc. There's probably a function to truncate floating point numbers; I'd look for that. It'll have the desired result (or if not, just add 0.5 then truncate; that rounds up).
 
Zurai said:
That actually is accurate. The problem is because they're using floats instead of doubles; floats are less accurate and will lead to 4.99999998 instead of 5, etc. There's probably a function to truncate floating point numbers; I'd look for that. It'll have the desired result (or if not, just add 0.5 then truncate; that rounds up).

Ah, so THAT is the problem. Thanks Zurai. I will read up more on Python anyhow so I can do more detailed Civ 4 changes. I must confess I had never run accross that kind of issue before with rounding, but I suppose there is always the first time. The confusing thing is, however, that it DOES work as I have written it in IDLE. So Civ 4 Python has differance/limitations when compared to stand-alone Python?

Also thanks to dlordmagic, I'll try that and if it works I'll post it up in the main thread with props to ya :goodjob:

EDIT: Ok, it's all up in the main thread.
 
dlordmagic said:
Inelagent is so harsh.

I like to think of it as jury-riggin the code.:lol:

Heh. True.

BTW, here's the "elegant" solution. I knew that there was a way similar to C. I just couldn't remember it at the time:

g_szTimeText = unicode(gc.getGame().getGameTurn()) + "/" + unicode(gc.getGame().getMaxTurns()) + " %2.2f" % (100 *(float(gc.getGame().getGameTurn()) / float(gc.getGame().getMaxTurns())))+ "% " + unicode(CyGameTextMgr().getInterfaceTimeStr(ePlayer))

Note, that it doesn't actually round the number, but since you just want to FORMAT the data, it allows you to do that.

Basically the format's like a printf (if you've done C programming).

But remember this way is ONLY for formatting, it won't actually round.

Req
 
Ahh, so the %2.2f does it? For people who aren't sure what that means:

% - indicates that what follows it is formatting, not actual text to be displayed
2.2 - 2 digits in front of the decimal, two digits after the decimal
f - floating point number


Now, if you only wanted to display the whole percent and wanted it to round, you'd do " %2.0f" and add 0.5 to the number you got from all the getTurns stuff. Adding that 0.5 effectively rounds the number; if you have 1.49, it'll go to 1.99 and get truncated to 1, but if you have 1.5 it'll go to 2 and there you go.
 
Zurai said:
Ahh, so the %2.2f does it? For people who aren't sure what that means:

% - indicates that what follows it is formatting, not actual text to be displayed
2.2 - 2 digits in front of the decimal, two digits after the decimal
f - floating point number


Now, if you only wanted to display the whole percent and wanted it to round, you'd do " %2.0f" and add 0.5 to the number you got from all the getTurns stuff. Adding that 0.5 effectively rounds the number; if you have 1.49, it'll go to 1.99 and get truncated to 1, but if you have 1.5 it'll go to 2 and there you go.

So it's done like a formatted print then. I never thought about it, but I bet that is supported in the Unicode function itself. I'll take some time here in the next day or so and put that version into the code just for the sake of completeness/cleanness.
 
This is the good post.

Here's my six part solution to the issue. Each of these functions was built ad hoc for some specific purpose. By the time I made irrationalize(), I found that I had a devised a pretty handy way of formating numbers with as many or as few significant digits as my heart desired.

Here are some examples.

roundize(number, significantDigits=0, leadZero=1)

>>> roundize(123.546)
'124'
>>> roundize(123.546, 2)
'123.55'

sumize(number1, number2, significantDigits=-1, leadZero=1)

>>> sumize(12.6, .09)
'12.69'
>>> sumize(12.6, .09, 1)
'12.7'
>>> sumize(12.6, .09, 0)
'13'

multiplize(number1, number2, significantDigits=-1, leadZero=1)

>>> multiplize(23.4, 6.23)
'145.782'
>>> multiplize(23.4, 6.23, 1)
'145.8'

irrationalize(numerator, denominator, significantDigits=0, leadZero=1)

>>> irrationalize(20, 3)
'7'
>>> irrationalize(23211, 43, 9)
'539.790697674'
>>> irrationalize(656, 43224, 5)
'0.01518'
>>> irrationalize(656, 43224, 5, 0) #Include the 0 at end if you do not want a lead zero
'.01518'


(QUOTE THIS POST TO COPY THESE FUCTIONS WITH CORRECT TAB STOPS!)

def roundize(number, significantDigits=0, leadZero=1):
number=float(number)*10**significantDigits
rounded = decimalize(int(round(number)), significantDigits, leadZero)
return rounded

def sumize(number1, number2, significantDigits=-1, leadZero=1):
number1=str(number1)
number2=str(number2)
sig1=0
sig2=0
if significantDigits<0:
if number1.count('.')==1:
sig1=(len(number1)-1)-number1.find('.')
if number2.count('.')==1:
sig2=(len(number2)-1)-number2.find('.')
if sig1>=sig2:
significantDigits=sig1
else:
significantDigits=sig2
number1=float(number1)*10**significantDigits
number2=float(number2)*10**significantDigits
summed=decimalize(int(round(number1 + number2)), significantDigits, leadZero)
return summed

def multiplize(number1, number2, significantDigits=-1, leadZero=1):
number1=str(number1)
number2=str(number2)
sig1=0
sig2=0
if significantDigits<0:
if number1.count('.')==1:
sig1=(len(number1)-1)-number1.find('.')
if number2.count('.')==1:
sig2=(len(number2)-1)-number2.find('.')
significantDigits=sig1 + sig2
number1=float(number1)*10**sig1
number2=float(number2)*10**sig2
else:
number1=float(number1)*10**significantDigits
number2=float(number2)
multiplied=decimalize(int(round(number1 * number2)), significantDigits, leadZero)
return multiplied

def irrationalize(numerator, denominator, significantDigits=0, leadZero=1):
numerator=float(numerator)*10**significantDigits
denominator=float(denominator)
irrationaled = decimalize(int(round(numerator/denominator)), significantDigits, leadZero)
return irrationaled

def decimalize(number, significantDigits, leadZero=1):
significantDigits=int(significantDigits)
sign=""
if number < 0:
number = number * -1
sign = "-"
if number == 0:
return "0"
else:
number=str(number)
if len(number)<=significantDigits:
zeros = []
for i in range((significantDigits+leadZero)-len(number)):
zeros.append("0")
number=stringize(zeros) + number
prefix=len(number)-significantDigits
result = []
for i in range(prefix):
result.append(number)
result.append(".")
for i in range(significantDigits):
result.append(number[i+prefix])
decimaled = sign + stringize(result)
if decimaled.count('.')==1:
if decimaled.find('.')==len(decimaled)-1:
decimaled=decimaled.replace('.','')
return decimaled

def stringize(sequence):
linkChar = ""
for i in range(len(sequence)):
sequence=str(sequence)
strung = linkChar.join(sequence)
return strung
 
Top Bottom