Limit the characters of a "newText"

@dodi_games, the more syntax a language has, the more it can be terrifying.

string.format is really powerful and you don’t have to know all the options. But basically the first parameter to the function is the formatting string in this case:

“%0.3f”

The % says insert a value from the list of parameters following the format string. In this example there is only one % so it’s only going to take one value, which is the “valueToFormat” variable nor number.  After the % it specifies how to format that value. In this case, it says any number of numbers before the . including a 0 if it’s less than 1. And at max 3 decimal places after the .  The “f” says to expect a floating point number.  %5d would say to take a number, chop off all decimal places and output a 5 digit digit number. But %05d would lead it with 0’s.   It’s pretty cool actually.  In my game I use this to format my score since I want the score to always be 7 digits long:  

local scoreText = display.newText(string.format("%07d", myScore), display.actualContentWidth - 50, 25, native.systemFontBold, 16)

Here is another cool example.

local levelCompleteTitle = display.newText( string.format("Level %d Complete", currentLevel), display.contentCenterX, display.contentCenterY - 180, "carbon", 32 )

In this case instead of doing “Level " … currentLevel … " Complete” I can just use this and have it insert the number in the middle of the string.

Rob

Thanks a lot @Rob. Now I understood the use of string.format well.

I have also tried

... elseif ( event.phase == "ended" ) then        local sum = tonumber( field\_1.text ) + tonumber( field\_2.text )        local mult = tonumber( field\_1.text ) \* tonumber( field\_2.text )        local step\_1 = sum / mult       local step\_2 = step\_1 \* tonumber( field\_3.text ) \* tonumber( field\_4.text ) \* 6.1        local finalStep = step\_2 \* tonumber( field\_5.text ) ​ myNum = 7 -- max characters if string.len(result) \> myNum then result = result:sub( 1, 7 ) end ​ result.text = finalStep ​ end ...

error

.lua:95 = if string.len(result) > myNum then

Is this what you are looking for?

https://forums.coronalabs.com/topic/33592-round-a-number-to-the-first-decimal/

Thanks for your fast response

Could use it but would not know how to implement it to “result.text”.

I have the “newText” created in the “scene create”, the “textFields” created in the “scene show” all the functions and the listeners are at the top where it says that the functions in the template scene go. In the “calcButton” function, after doing the math procedure, replaced the “finalStep” with the “result.text” and everything is fine. What I can not see is how to limit the number of characters that are displayed in the “result.text” on the screen not in the console. Try “string.len” but it does not give me result. “math.round” api only has a brief explanation and as examples only has “print statements” that I understand are only displayed in the console. I’m looking for how to solve this. This should be extremely easy for a good programmer, but for me being a graphic artist with little experience in programming is a rather difficult task. I am motivated with Corona and its new goals.

I guess all you missed was to assign finalStep to result.text?

[lua]

… 

  local finalStep = step_2 * tonumber( field_5.text )​ myNum = 7 – max characters

  result.text = finalStep

  if string.len(result.text) > myNum then

    result.text = result.text:sub( 1, 7 )

  end ​ 

    result.text = finalStep

  end 

[/lua]

Why I need to write 2 times result.text = “finalStep”? One before “if statement” and another after the end of it. I do it and receive an error saying “bad argument #1 to ‘len’ (string expected, got table)”

Why not just do this?

result.text = string.sub("1.33333333333333333333",1,7)

using your variables simply do this (only 1 line of code is needed)

result.text = string.sub(finalStep,1,myNum)

You don’t need the second assignment only the first one and, in case the string is longer than 7 chars, the one with the :sub() call.

In the code snippet where you got the bad argument error you used result as a parameter to string.len instead of result.text. I can only guess what your code does as the few lines don’t include f.i. what kind of object result is.

My guess is that it’s a Corona text object which is of type table but string.len expects a string.

That said, if you still get the same error when you use result.text instead of result, then you probably should post more of your code as the problem is something else then.

There is a much better way to do deal with this:

local someString = string.format("%0.3f", valueToFormat)

Done.

See: https://docs.coronalabs.com/api/library/string/format.html

Rob

Thanks to everyone for your replies

I’m sure what I have is a string management problem.

I’m reading a lot but I still do not see it​.

I’ll explain a little better​.

-- Scene event functions Here are all the functions and listeners of all buttons and textFields -- create() all scene image objects, buttons, scrollViews -- show my textFields -- hide removeSelf() nil my textFields -- destroy

ok

first image is an example of my app, second image is the problem and third image is what I want

my button

 local calcButton = widget.newButton( { width = 200, height = 200, defaultFile = "images/buttons/calc.png", overFile = "images/buttons/calc-over.png", onEvent = calcButtonTouch } ) calcButton.x = centerX+130 calcButton.y = centerY-280 sceneGroup:insert( calcButton )

the full function

-- calc button function local function calcButtonTouch( event ) if ( event.phase == "began" ) then audio.play( flick ) elseif ( event.phase == "ended" ) then if field\_1.text == "" or field\_1.text == "value" or field\_2.text == "" or field\_2.text == "value" or field\_3.text == "" or field\_3.text == "value" or field\_4.text == "" or field\_4.text == "value" or field\_5.text == "" or field\_5.text == "value" then result.text = "0" elseif tonumber( field\_1.text ) and tonumber( field\_2.text ) and tonumber( field\_3.text ) and tonumber( field\_4.text ) and tonumber( field\_5.text ) then local sum = tonumber( field\_1.text ) + tonumber( field\_2.text ) local mult = tonumber( field\_1.text ) \* tonumber( field\_2.text ) local step\_1 = sum / mult local step\_2 = step\_1 \* tonumber( field\_3.text ) \* tonumber( field\_4.text ) \* 6.1 local finalStep = step\_2 \* tonumber( field\_5.text ) myNum = 7 -- max characters ​ if string.len(result.text) \> myNum then result.text = result.text:sub( 1, 7 ) ​ end ​ result.text = finalStep ​ end end return true end

Do you want 3dp precision or to limit the calculation output to 7 characters?

Both have different answers…  If you want 7 chars then use my code, if you want 3dp then use Robs

@SGS:

Thanks for two reasons,

  1. with your code I could limit the “result.text” to 7 characters.

  2. explaining it that way now I understand the “string.sub”.

@Rob

I’m going to read the link you gave me. I do not lie to you if I tell you that seeing parentheses with percent signs scares me a bit.

you could combine both for 3dp but limited to 7 chars

local someString = string.format("%0.3f", valueToFormat) local someStringOnly7Chars = string.sub(someString ,1,7)

When you say “3dp presicion” you mean a rounded result that shows the thousands with commas?

If so I would love it.

@SGS

Sorry for the first impression did not recognize the 3dp … this is very interesting, I will use the combination.

One question, can you tell me what “string library” should study to insert characters between my result? I would like if the result is more than 1000 can put a comma so 1,000.

3dp = 3 decimal places

for thousands try something like this

function comma\_value(amount)         local formatted = amount         while true do                   formatted, k = string.gsub(formatted, "^(-?%d+)(%d%d%d)", '%1,%2')                 if (k==0) then                         break                 end         end         return formatted end

I have a function that handles standard notation.  May help you?

function comma\_value(amount,dontAddPlusSign) local suffix, formatted = "", 0 if dontAddPlusSign == nil then dontAddPlusSign = true end if amount == nil or amount == "" then amount = 0 else amount = tonumber(amount) end if mabs(amount) \> 1000000000000 then amount = amount / 1000000000000 suffix = "t" formatted = tonumber(string.format("%.1f", amount)) elseif mabs(amount) \> 1000000000 then amount = amount / 1000000000 suffix = "b" formatted = tonumber(string.format("%.1f", amount)) elseif mabs(amount) \> 1000000 then amount = amount / 1000000 suffix = "m" formatted = tonumber(string.format("%.1f", amount)) elseif mabs(amount) \> 100000 then amount = amount / 1000 suffix = "k" formatted = tonumber(string.format("%.1f", amount)) else formatted = mfloor(amount) end while true do formatted, k = string.gsub(formatted, "^(-?%d+)(%d%d%d)", '%1,%2') if (k==0) then break end end if dontAddPlusSign then return formatted..suffix else if (formatted == "0" or formatted == "-0") and dontAddPlusSign then formatted = "" end if amount \> 0 then return "+"..formatted..suffix else return formatted..suffix end end end

it returns things like 1.2k, 3.5m, etc