Jump to content




performing a sum that's stored in a string


11 replies to this topic

#1 Hydrotronics

  • Members
  • 131 posts
  • LocationThe hall of 1000 monkeys and only 1 typewriter

Posted 12 June 2016 - 01:29 PM

So, I'm trying to create a calculator which allows you to say the sum in chat and then it works it out for you and replies in chat

I have the detect and reply system working, using Computronics. I dont have the middle bit where it calculates the sum. Is there a way of doing this?

So far my code looks something like this:

-- The code to break down the message to just the sum is up here
-- sum is the variable name given to the string
if string.find(sum, "+") then
  symbolLoc = string.find(sum, "+")
  symbol = +
elseif string.find(sum, "-" then
 symbrolLoc = string.find(sum, "-")
  symbol = -
end
if string.find(sum, "?") then
questionLoc = string.find(sum, "?")
else
sum = sum.."?"
questionLoc = string.find(sum, "?")
no1 = tonumber(string.sub(sum, 1, symbolLoc - 2))
no2 = tonumber(string.sub(sum, symbolLoc + 2, questionLoc))
answer = math.floor(no1 symbol no2)

The error it's giving is "Trying to add nil and nil" or something along those lines.
I have confirmed it is receiving the message properly, so that's not the problem

#2 TheRockettek

  • Members
  • 547 posts
  • LocationRem is best girl

Posted 12 June 2016 - 01:38 PM

Try puting the + and - as strings

#3 KingofGamesYami

  • Members
  • 3,002 posts
  • LocationUnited States of America

Posted 12 June 2016 - 03:19 PM

print( loadstring( "1 + 1" ) )

On mobile, sorry for lack of explanation.

#4 Incinirate

  • Members
  • 216 posts
  • LocationDanktown, Memeland

Posted 12 June 2016 - 04:06 PM

Towards KingofGamesYami

First of all, when you are detecting the symbol, you cannot simply say this:
symbol = +
This is because the '+' (or the '-') token is an operator, and you cannot set a variable to an operator, only to constants or other variables.
What you can do is something like this:
symbol = "+"
This sets the variable symbol to the string "+", allowing you to perform equality checks later on in the logic.

At the bottom where you calculate the answer, you cannot just have the different variables together without some sort of stitch.
There are two ways to do this, use loadstring as KingofGamesYami suggested, which is not the most efficient solution, but it works.
It is not very efficient because using loadstring triggers the Lua interpreter on the supplied string, which is not fast.
The better solution is to use an if/elseif block like so:
if symbol == "+" then
	answer = math.floor(no1 + no2)
elseif symbol == "-" then
	answer = math.floor(no1 - no2)
end
You can then extend this for other operators such as the multiplicative token '*', or the divisor token '/', or even applying powers with '^'.

NOTE: The reason you got the error "Trying to add nil and nil" is because of the "symbol = +" line, it expected operands on either side of the '+' and the '-', since you supplied none, it assumed both were nil, and you cannot add nil to anything.

Edited by Incinirate, 18 June 2016 - 02:47 AM.


#5 Hydrotronics

  • Members
  • 131 posts
  • LocationThe hall of 1000 monkeys and only 1 typewriter

Posted 16 June 2016 - 04:45 PM

I'll look into Inc's answer later, but what does loadstring do? I tried it but it didn't work :/ Also, I want it to be more than just addition and subtraction, those were just examples :P
I was gonna add factorial, roots, powers, multiplication and division, but your way would work either way, but it's long and takes time to type so I was kinda hoping for a shorter method

Edited by LemonJelly, 16 June 2016 - 04:48 PM.


#6 valithor

  • Members
  • 1,050 posts

Posted 16 June 2016 - 04:50 PM

View PostLemonJelly, on 16 June 2016 - 04:45 PM, said:

I'll look into Inc's answer later, but what does loadstring do? I tried it but it didn't work :/

The loadstring example should have actually been something like this.
print(loadstring("return 1+1")())

You can think of the string that is being passed to loadstring as being converted to a function. In the example right there it is essentially saying:
(function()
  return 1+1
end)()


#7 Incinirate

  • Members
  • 216 posts
  • LocationDanktown, Memeland

Posted 18 June 2016 - 02:47 AM

View PostLemonJelly, on 16 June 2016 - 04:45 PM, said:

I'll look into Inc's answer later, but what does loadstring do? I tried it but it didn't work
--snip--

Yeah, sorry, the fix for the loadstring was in the "towards kingofgamesyami" spoiler, should have put it outside as well (and thanks for catching my mistake val), but as valithor said, the correct way to use loadstring is as follows:
print(loadstring("return 1+1")())
This is because loadstring basically wraps the code you input as a function and gives you that function as its return argument, for example:
local myFunc = loadstring("return 1+1")
-- This becomes
local myFunc = function()
     return 1+1
end
Then, you have to call it to actually get the answer.

#8 Hydrotronics

  • Members
  • 131 posts
  • LocationThe hall of 1000 monkeys and only 1 typewriter

Posted 16 July 2016 - 07:04 AM

Ah! Thank you!! I'll have a shot at it! Thank you for help! :)

Edit: Ok, so I'm getting an error that is trying to do math on a number and a nil?

This is my code:
message you say to trigger this piece of code: "What is 1+1"
--Somewhere up here I'm converting the message to caps
if string.find(message,"WHAT IS") then
if tonumber(string.find(message, 8, 9)) then
  sleep(1)
  chat.say("Beginning Calculations")
  if string.find(message, "?") then
	chat.say("Please don't add a question mark to the sum")
	os.reboot()
  end
  local sumRaw = string.sub(message,7)
  local calculate = loadstring("return "..sumRaw)
  chat.say(sumRaw.." = "..calculate)
end
end

Second Edit: Oops! I put string.find instead of string.sub! My bad :P Thx Bomb Bloke for pointing this out

Edited by LemonJelly, 21 July 2016 - 04:30 PM.


#9 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 16 July 2016 - 09:13 AM

Can't see how that code could give that error. It's got other issues.

string.find(message, 8, 9)

Here you're passing the number 8 where you should be passing in a string to look for. Lua will translate that automatically, but your string doesn't contain the character "8", so find will still return nil.

I think you meant string.sub(message, 9, 11), but "1+1" won't tonumber(), and even if it did - what if the user enters more than two digits, or adds additional spaces, etc?

local sumRaw = string.sub(message,7)

Assuming this line were reached, sumRaw would end up as "S 1+1". You presumably meant 9.

chat.say(sumRaw.." = "..calculate)

loadstring assigned calculate a function pointer. Here you meant to call that function, using "calculate()".

Really you should be checking that "calculate" is a function before you attempt to call it (what if loadstring() failed to make any sense of the expression?), and pcall'ing it if it compiled (in case it fails to execute). Even then you should really be applying patterns to make sure the expression is purely mathematical - while loadstring() probably is the simplest way to do this, what you don't want is people asking "what is fs.delete("startup") os.reboot()".

#10 The Crazy Phoenix

  • Members
  • 136 posts
  • LocationProbably within 2 metres of my laptop.

Posted 17 July 2016 - 03:06 PM

The correct way of doing this would be to declare a function for each operator.
local operations = {
    ["+"] = function(a, b) return a + b end,
    ["-"] = function(a, b) return a - b end
    --# Etc
}
Then you can call them using operations[op](a, b), where op is the string of the operation, such as "-".

Edited by The Crazy Phoenix, 17 July 2016 - 03:07 PM.


#11 Hydrotronics

  • Members
  • 131 posts
  • LocationThe hall of 1000 monkeys and only 1 typewriter

Posted 21 July 2016 - 04:34 PM

View PostBomb Bloke, on 16 July 2016 - 09:13 AM, said:

-snip-

I think you meant string.sub(message, 9, 11), but "1+1" won't tonumber(), and even if it did - what if the user enters more than two digits, or adds additional spaces, etc?

local sumRaw = string.sub(message,7)
-snip

just to clarify, what I'm attempting to do there is just check the first digit of the first number is infact a number, which isn't a bullet proof method of checking but I honestly couldn't be bothered to improve upon it. I just wanted a program that could answer maths question for you XD

#12 Lupus590

  • Members
  • 1,985 posts
  • LocationUK

Posted 21 July 2016 - 05:00 PM

View PostLemonJelly, on 21 July 2016 - 04:34 PM, said:

View PostBomb Bloke, on 16 July 2016 - 09:13 AM, said:

-snip-

I think you meant string.sub(message, 9, 11), but "1+1" won't tonumber(), and even if it did - what if the user enters more than two digits, or adds additional spaces, etc?

local sumRaw = string.sub(message,7)
-snip

just to clarify, what I'm attempting to do there is just check the first digit of the first number is infact a number, which isn't a bullet proof method of checking but I honestly couldn't be bothered to improve upon it. I just wanted a program that could answer maths question for you XD

once you have separated it you could use tonumber(string) if the string/char didn't have a number than it returns nil

Edited by Lupus590, 21 July 2016 - 05:01 PM.






1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users