string.find() Problem

Okay so I have been working on this little test for a bit. I’ve ran into a problem where {speech:reset} doesn’t work. After string.find finds the pattern, the true function doesn’t execute. Here’s what I mean

  if key == RETURN then
            local setSpeedMax = string.find(words, "{speed=max}")
        if setSpeedMax then
    speechSpeed = 1.0
            sayWords() -- this one works
            else
            sayWords()

end
        return speechSpeed
    end

            if key == RETURN then
            local resetSpeed = string.find(words, "{speed:reset}")
            if resetSpeed then
                speechSpeed = 0
            sayWords() -- this one doesnt
            else
            sayWords()
 end
        
        end                 
   

Please help. It's quite annoying because everything seems in perfect order.

Here's the full code:




function setup()
speechSpeed = 0.5
    words = ""
    dependables = {}
    language = "EN-GB"
end

function draw()
    
    background(36, 36, 36, 255)
      
    pushStyle()
    font("Arial-BoldMT")
    fontSize(25)
    fill(0, 161, 255, 255)
    textWrapWidth(WIDTH - 10) 
    text(words, WIDTH/2, HEIGHT/2 + 250)  
       
end

function touched(touch)
    
  if touch.state == ENDED then
        showKeyboard()
    end
    
end

function keyboard(key)
      
    words = words..key
    if key == BACKSPACE then
       words = string.sub(words, 1, -2)
       
    end
    
        local beginSearch = string.find(words, "{")
    if beginSearch then
        output.clear()
        print("SPEED:MAX\
function (speed=max) (sets the speech speed to maximum)\
 type: {speed=max} (sets the speed to max)")
          print("SPEED:RESET\
function (speed:reset) (resets the speech speed to default)\
 type: {speed:reset} (resets the speed to default)")
        print("SPEED:MIN\
function (speed=min) (sets the speech speed to the minimum speed)\
 type: {speed=min} (sets the speed to minimum)")
        else
        output.clear()
    end
        
    
    
  if key == RETURN then
            local setSpeedMax = string.find(words, "{speed=max}")
        if setSpeedMax then
    speechSpeed = 1.0
            sayWords()
            else
            sayWords()

end
        return speechSpeed
    end

            if key == RETURN then
            local resetSpeed = string.find(words, "{speed:reset}")
            if resetSpeed then
                speechSpeed = 0
            sayWords()
            else
            sayWords()
 end
        
        end                 
    if key == BACKSPACE and words == "" then
        output.clear()
    end 

end     
    
function sayWords()

    speech.language = language
    speech.volume = 1.0
    speech.rate = speechSpeed
    speech.say(words)
  words = ""
    
end

Thanks

For some reason the things all messed up. I can’t fix it

@LL_Phoenix456 For starters, learn how to format your code so it’s easier to read. Remove blank lines so you can see more of the code at the same time. When you format the code correctly, you’ll be able to see what goes with the if and what goes with the else. Your problem is in the first if RETURN. You look for {speed=max} which calls sayWords() whether you find something or not. The function sayWords() sets words to “” which means the next if wont have anything to search. Also in your first if Return, you do a return speechSpeed which means you won’t get to the second if RETURN to look for speed:reset.

EDIT: string.find actually returns 2 values, the start and end position in the string where the pattern is found. In your code above, you’re treating it like a true/false response. It works, but may be a problem at some point.

@dave1707 How would I fix it then?

Look at the keyboard function for changes. Also look at the formatting. That makes it easy to see what goes with the if and what goes with the elseif. But then everyone has their own style.

function setup()
    speechSpeed = 0.5
    words = ""
    dependables = {}
    language = "EN-GB"
end

function draw()
    background(36, 36, 36, 255)
    pushStyle()
    font("Arial-BoldMT")
    fontSize(25)
    fill(0, 161, 255, 255)
    textWrapWidth(WIDTH - 10) 
    text(words, WIDTH/2, HEIGHT/2 + 250)  
end

function touched(touch)
  if touch.state == ENDED then
        showKeyboard()
    end
end

function keyboard(key)
    words = words..key
    if key == BACKSPACE then
       words = string.sub(words, 1, -2)
    end
    if string.find(words, "{") then
        output.clear()
        print("SPEED:MAX\
function (speed=max) (sets the speech speed to maximum)\
 type: {speed=max} (sets the speed to max)")
        print("SPEED:RESET\
function (speed:reset) (resets the speech speed to default)\
 type: {speed:reset} (resets the speed to default)")
        print("SPEED:MIN\
function (speed=min) (sets the speech speed to the minimum speed)\
 type: {speed=min} (sets the speed to minimum)")
    else
        output.clear()
    end    
    if key == RETURN then
        if string.find(words, "{speed=max}") then
            speechSpeed = 1.0
        elseif string.find(words, "{speed:reset}") then
            speechSpeed = 0
        end
        sayWords()
    end                 
    if key == BACKSPACE and words == "" then
        output.clear()
    end 
end     

function sayWords()
    speech.language = language
    speech.volume = 1.0
    speech.rate = speechSpeed
    speech.say(words)
    words = ""
end

Okay. Let me just say I am a pretty good programmer. I feel idiotic for not thinking like that. Sorry about all this. Stupid me forgetting that way of coding.

@dave1707 okay. But two things, I’m trying to make it so I feel I type {speech=repeat} then it will repeat it. If I try to use any type of for loop, it only ways it once. Do I use return? What does return even do?

return exits the function, returning control flow to whatever called the function, and optionally sending a value (or values) back to whatever called the function.

I don’t get it. Functions only call once when you call them? Why would you need to exit them when they’ve been executed?

@LL_Phoenix456 - you are asking very basic Lua questions which can be answered by simple googling, which would avoid wasting people’s time explaining stuff on this forum, which is for Codea questions.

When you type speech=repeat, do you want whatever you type after that to repeat until you type speech=norepeat. How many time do you want it to repeat, once, twice, 3 times. Or do you want to type something like speech=repeat3 for it to repeat everything 3 times until you type speech=repeat1. Your question can lead to more questions. return is used to exit a function before the normal exit. If you have a function that prints the numbers 1 to 100, then you could have an if statement that will return (exit) the function at a certain value before it reaches 100. See the example below.

function print100(val)
  for v=1,100 do
       if v==val then
             return
       end
       print(v)
  end
end

Why would you need to exit them when they’ve been executed?

Well, you might want to exit them early. That was the problem you were having above, and why the code after the return statement wasn’t running.

Or, most commonly, you want to get a value back from them. Returning a value from a function is very, very useful indeed.

There is a whole school of programming called functional programming. A “pure” function doesn’t modify any variables. It takes some variables in as parameters. And it returns some new, modified variables as return values. The advantage of this style is that the pure function has no unexpected side effects. It has no side effects at all in fact. This makes the function a lot more reusable across different programs. It makes the function a lot easier to reason about. You can look at it and understand exactly what it does without needing to know about any other context, because there is no other context. Just what it takes in, and then what it returns.

return is essential for functional programming.