This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
mistamadd001's profile picture

attempt to concatenate string and function

Started by mistamadd001, 12 February 2015 - 11:00 AM
mistamadd001 #1
Posted 12 February 2015 - 12:00 PM
Ok guys line 139 trying to get a percentage of total power remaining, spitting up the error. I obviously do have the parentheses so no idea what im doing wrong. using the Yogscast Complete Pack, connecting to a BigReactor computer port.

http://pastebin.com/C8QszcsH

helps appreciated.

Mistamadd001
KingofGamesYami #2
Posted 12 February 2015 - 02:14 PM
Please post the full error message.
Quintuple Agent #3
Posted 12 February 2015 - 07:21 PM
I am not sure if this is the cause of whatever error you are getting, but change your percentage calculation to

percent = math.floor(arg1/arg2*100)
or if you want to the second decimal place

percent = math.floor(arg1/arg2*10000)/100
The one you are using would give 100% if the full, however, when it should be 10% it would read as 1000%, 1% would be 10000% and zero would end up being inf
KingofGamesYami #4
Posted 12 February 2015 - 07:27 PM
I am not sure if this is the cause of whatever error you are getting, but change your percentage calculation to

percent = math.floor(arg1/arg2*100)
or if you want to the second decimal place

percent = math.floor(arg1/arg2*10000)/100
The one you are using would give 100% if the full, however, when it should be 10% it would read as 1000%, 1% would be 10000% and zero would end up being inf

No, what he has will give you 100 when full, 0 if not. math.floor( 0.99 ) = 0
Quintuple Agent #5
Posted 12 February 2015 - 07:30 PM
No, what he has will give you 100 when full, 0 if not. math.floor( 0.99 ) = 0

I tested it, it was giving me what I posted
The real problem is he is doing arg2/arg1 then when he calls it he is giving current/max, so it is then max/current
Edited on 12 February 2015 - 06:32 PM
lincore #6
Posted 12 February 2015 - 07:50 PM

percent = math.floor(math.floor(arg2/arg1)*100)
Check for division by zero (if arg == 0 then percent = 0 else your code end). I don't know if that's what causes your error, but it will eventually if you don't handle this.
Also, your percentage calculation is incorrect: It's current / max, not max / current. And if max > current (which seems to be the case most often), math.floor(current / max) * 100 is always zero, so only floor after multiplying by 100.
Edited on 12 February 2015 - 06:51 PM
Bomb Bloke #7
Posted 12 February 2015 - 11:25 PM
Line 139:

term.write(currentFuel..'mB / '..maxFuel..'mB = '..percentage(currentFuel,maxFuel)..'%')

Per the error, you're trying to concatenate a string with a function. Only, none of these values are a function…

Reading further up, on line 81 we see:

tickPower = reactor.getEnergyProducedLastTick

Since you forgot the brackets, you're not setting "tickPower" to the result of calling reactor.getEnergyProducedLastTick(), you're setting it to the actual function reactor.getEnergyProducedLastTick points to.

Thus on line 135:

term.write(currentPower..'RF / '..maxPower..'RF = '..percentage(currentPower,maxPower)..'%  '..tickPower..'RF/t')

… you produce the error.

Really, though, you don't want to use the tickPower variable at all. When you set it to the result of reactor.getEnergyProducedLastTick(), it'll stay on that value until you set it to something else - it won't automatically change as time goes by. So ditch the variable and perform the function call directly within the loop, so that you get an up-to-date result on every iteration.
Edited on 12 February 2015 - 10:25 PM
mistamadd001 #8
Posted 13 February 2015 - 12:38 AM
Line 139:

term.write(currentFuel..'mB / '..maxFuel..'mB = '..percentage(currentFuel,maxFuel)..'%')

Per the error, you're trying to concatenate a string with a function. Only, none of these values are a function…

Reading further up, on line 81 we see:

tickPower = reactor.getEnergyProducedLastTick

Since you forgot the brackets, you're not setting "tickPower" to the result of calling reactor.getEnergyProducedLastTick(), you're setting it to the actual function reactor.getEnergyProducedLastTick points to.

Thus on line 135:

term.write(currentPower..'RF / '..maxPower..'RF = '..percentage(currentPower,maxPower)..'%  '..tickPower..'RF/t')

… you produce the error.

Really, though, you don't want to use the tickPower variable at all. When you set it to the result of reactor.getEnergyProducedLastTick(), it'll stay on that value until you set it to something else - it won't automatically change as time goes by. So ditch the variable and perform the function call directly within the loop, so that you get an up-to-date result on every iteration.

BombBloke, thank you, I have moved all my variables that can change inside my while loop so they will be recalculated each time. I have also fixed the function call. I think the problem with CC is it wont produce any part of a line that has an error in it. If the computer wrote out everything up to the tickPower it would be much easier to see my error.

As for everything else, I have slightly changed my percentage calculation hoping it will fix it, otherwise ill have to figure something else out.


Cheers,

Mistamadd001
Bomb Bloke #9
Posted 13 February 2015 - 01:31 AM
I think the problem with CC is it wont produce any part of a line that has an error in it. If the computer wrote out everything up to the tickPower it would be much easier to see my error.

First, before it can even start to execute the term.write() call, it has to determine what you're passing to the function - and to do that, it's got to combine all the entries you're concatenating together into one string. Since this was the process triggering the error, it wasn't possible for it to start writing anything.

You could've worked around that by manually converting all the values in concern to strings. This wouldn't've fixed the actual problem with your script, but it would've at least allowed the interpreter to print something:

term.write(tostring(currentPower)..'RF / '..tostring(maxPower)..'RF = '..percentage(currentPower,maxPower)..'%  '..tostring(tickPower)..'RF/t')

Another option would've been to use multiple term.write() statements, rather than trying to concatenate everything together in one go.
mistamadd001 #10
Posted 13 February 2015 - 01:43 AM
hey guys, so ive got it working as intended, however Im working on the interface and I dont like that it spits out tons of numbers for the current power.

So i added in a simple if, elseif, else statement to trim off 3 zeros depending on the current total, if less than 1,000 say the total and the unit is RF, if > 1,000 but < 1,000,000 divide the total by 1000 and the unit is kRF, if >1,000,000 divide by 1,000,000 and the unit is MRF. However, by doing a math.floor on this it doesnt give me a decimal point, which i would like so if the current total is 17,345RF i would like the monitor to show 17.3kRF instead of 17kRF. Anyone got any ideas??

cheers,

mistamadd001
Bomb Bloke #11
Posted 13 February 2015 - 01:58 AM
I suppose you could do something like this:

local prefix = {"","k","M","G","T","P","E","Z","Y"}

local function condenseNum(num)
	local counter = 1
	
	while num > 1000 do
		counter = counter + 1
		num = num / 1000
	end
	
	return tostring(math.floor(num*10) / 10)..prefix[counter]
end

You'd then be able to do something like this:

term.write(condenseNum(reactor.getEnergyProducedLastTick()).."RF/t")
Edited on 13 February 2015 - 01:00 AM
mistamadd001 #12
Posted 13 February 2015 - 02:04 AM
I must have explained this badly, Ive made the 'function' to trim the number down, and add the k or M, but what i want is the trimmed number to show the first decimal place too, as per


17,376 --> 17.4k not 17k
or
25,204 --> 25.2k not 25k
or
26,752 --> 26.8k not 27k

hope this explains a bit better
Edited on 13 February 2015 - 01:06 AM
Bomb Bloke #13
Posted 13 February 2015 - 02:10 AM
Take another look, I ninja'd you with an edit. ;)/>
mistamadd001 #14
Posted 13 February 2015 - 02:53 AM
I suppose you could do something like this:

local prefix = {"","k","M","G","T","P","E","Z","Y"}

local function condenseNum(num)
	local counter = 1
	
	while num > 1000 do
		counter = counter + 1
		num = num / 1000
	end
	
	return tostring(math.floor(num*10) / 10)..prefix[counter]
end

You'd then be able to do something like this:

term.write(condenseNum(reactor.getEnergyProducedLastTick()).."RF/t")

Take another look, I ninja'd you with an edit. ;)/>

You sir are a legend, it works perfectly. THANKS