Yurtiel Posted August 25, 2014 Share Posted August 25, 2014 Been a while since I asked for help on here.I have been working on a translator to help me learn the dataserve stuff, but I seem to be having a problem with a crucial aspect of my script.As far as translating words that are in the notecard appropriately the script works fine.I'll explain what works and how it's SUPPOSED to work first of all.The script takes words that are put into channel 93, it then parses them to a list, takes out the punctuation and compares them to a notecard called "English" which has a list of words to be compared to and then fetches the equal line from another card labeled "Gorean" which is the word that it replaces the found word with.As far as finding words on the list and translating them it works fine, if it finds the word it translates it appropriately and continues on with it's job as it should, the problem I am having comes with if it does NOT find the word on the list labeled "English".What it should do in this instance, is add the word it couldn't find to the sentence and continue to translate the rest of the list before posting the sentence into chat, however the script isn't doing this, whenever it encounters a word that isn't in the list labeled "English" it instead seems to hiccup and completely forego's translating anything that's input.Example:When I put in the word above (A word in the list) it finds it and translates it correctly into Ia (Word in the translated word list). However if I put in the words above is or the word is by itself, nothing happens, and the script doesn't seem to be doing anything, I then have to reset the script before I can continue with the part that DOES translate. Can someone help with this please? I've been at it for a long time now and it's driving me insane, the script is below. list EnglishList = []; list Punctuation = [" ", "\"", "$", "(", ")", ".", ",", ";", ":", "-", "?", "!", "=", "*"]; //All Punctuation parsed away except ' and - These may be parts of English words string GSentence; //THIS will be the translated sentence in Gorean string word; //The Gorean word to be used in GSentence - will use XXXXX if word not in dictionary integer found; //The line in the Gorean notecard where the translation of the English word can be found integer foundLine= 0; //Counter on the number of wirds in the English sentence integer LL; //Length of parsed list generated from English sentence list PList; //The parsed list key reqNC_English; //Reading the English vocabulary into a list integer LineE = 0; //English NC line key reqNC_Gorean; //Reading the Gorean vocabulary, finding the right line integer LineG = 0; //Gorean NC line integer Consistency = FALSE; //Checking for same length of notecards key reqE_Length; //Finding the length of the E notecard key reqG_Length; //Finding the length of the G notecard integer ELength; integer GLength; integer limit = 64000; ParseMessage(string message) //Prsing the English sentence (said on /93) parsing away punctuations { PList = llParseString2List(message, Punctuation, []); LL = llGetListLength(PList); GSentence = ""; Translate(foundLine); //Go to translating the Parsed English sentence } Translate(integer line) { word = llList2String(PList, line); //take the word found = llListFindList(EnglishList, [word]); //Is that word in English vocabulary? found >=0 - if NOT found, found = -1 integer i; integer length = llGetListLength(EnglishList); for(i=0; i < length;i++) { if(found == -1 && word == llGetSubString(word, 0, -1)) //English word is NOT in dictionary { GSentence += word; //Add that to the G sentence ++foundLine; return line; } else if (found >=0) reqNC_Gorean = llGetNotecardLine("Gorean", found); //if English word is in vocabulary, find translation on G Notecard } } default { state_entry() { reqE_Length = llGetNumberOfNotecardLines("English"); //Get length of E notecard llSetMemoryLimit(limit); llScriptProfiler(PROFILE_SCRIPT_MEMORY); llScriptProfiler(PROFILE_NONE); } dataserver(key id, string data) { if(id == reqE_Length) //gets length of E notecard { ELength = (integer)data; reqG_Length = llGetNumberOfNotecardLines("Gorean"); //Now get length of G notecard } else if(id == reqG_Length) //Gets length of G notecard { GLength = (integer)data; if(GLength != ELength) //If they are NOT equally long (== inconsistent) { llOwnerSay("The Notecards do NOT have the same number of lines\n Fix that and try again!!"); } else if(GLength == ELength) //If they HAVE the same length { reqNC_English = llGetNotecardLine("English", LineE); //Get E notecard vocabulary into a list } } else if(id == reqNC_English) { if(data != EOF) //as long as we are NOT at the end of the NC { EnglishList += data; //add a new line ++LineE; // increase the line number reqNC_English = llGetNotecardLine("English", LineE); //and get that next line } else if(data == EOF) //If we are at the end of the E notecrd (all words are in our list now) { llListen(93, "", NULL_KEY, ""); //Open a listen on channel 93 } } else if(id == reqNC_Gorean) //THIS is the continuation of the above "Translate" function, when our E word had been on the list { //Find the Gorean translation and add a space to that word GSentence += data + " "; //Add the word to the Gorean sentence ++foundLine; //go to next English word in Parsed list if(foundLine < LL) //If there is another English word { Translate(foundLine); //translate that now } else if(foundLine == LL) //No more E word to translate { foundLine = 0; llSay(0,GSentence); //Say the Gorean Sentence llMessageLinked(LINK_THIS,0,GSentence,""); llResetScript(); } } } listen(integer channel, string name, key id, string message) //Listening on channel 93 { if(channel != 93 || id != llGetOwner()) return; else if(channel == 93 && id == llGetOwner()) //If said on correct channel { //llOwnerSay(message); ParseMessage(llToLower(message)); //Go parse that English sentence } } changed(integer change) { if(change & CHANGED_INVENTORY || change & CHANGED_OWNER) llResetScript(); //Reset if inventory is changed } } Link to comment Share on other sites More sharing options...
Rolig Loon Posted August 25, 2014 Share Posted August 25, 2014 I'm not sure what you intended by the test that says if(found == -1 && word == llGetSubString(word, 0, -1)) After all, it will always be TRUE that word == llGetSubString(word,0,-1) . That's a definition of identity. A quanity it equal to itself. So the only relevant test is if(found == -1) That's an aside, though. The real problem is that your Translate routine is supposed to return the value of line, an integer variable, yet the function Translate itself is untyped. You really want it to be integer Translate(integer line) Link to comment Share on other sites More sharing options...
Yurtiel Posted August 25, 2014 Author Share Posted August 25, 2014 Thanks, and yeah I didn't even notice that screw up, it's supposed to be telling it to recognize when it's at the end of that particular string. I'll change it integer translate and see how it works then post the results. Link to comment Share on other sites More sharing options...
Yurtiel Posted August 26, 2014 Author Share Posted August 26, 2014 This didn't help at all, changing it to integer translate actually started giving me a "Not all code paths return a vlue" error and won't let me save the script. Link to comment Share on other sites More sharing options...
Rolig Loon Posted August 26, 2014 Share Posted August 26, 2014 Ah, that's true. With a user defined function you do need to have a way to get out of the routine no matter what path you take. So you doi need to provide a return for your other if test as well. else if (found >=0){ reqNC_Gorean = llGetNotecardLine("Gorean", found); return;} Link to comment Share on other sites More sharing options...
Yurtiel Posted August 26, 2014 Author Share Posted August 26, 2014 integer Translate(integer line) { word = llList2String(PList, line); //take the word found = llListFindList(EnglishList, [word]); //Is that word in English vocabulary? found >=0 - if NOT found, found = -1 integer i; integer length = llGetListLength(EnglishList); for(i=0; i < length;i++) { if (found >=0) { reqNC_Gorean = llGetNotecardLine("Gorean", found); ++foundLine; return; } //if English word is in vocabulary, find translation on G Notecard else if(found == -1) //English word is NOT in dictionary { GSentence += word; //Add that to the G sentence ++foundLine; return; } } } still getting an error when that all paths are not returning a value. Link to comment Share on other sites More sharing options...
Rolig Loon Posted August 26, 2014 Share Posted August 26, 2014 Well, yeah. You changed the code. Earlier, you had the routine returning the value of the variable line. The reason the routine was bombing then was that you didn't declare it's own type. So you changed it to integer Translate (integer line) But now you have removed the variable line from the return statements, so it doesn't know what to return. So, if you don't want it to return a value, forget about setting a type for the routine. Otherwise, pass line again. return line; Link to comment Share on other sites More sharing options...
Yurtiel Posted August 26, 2014 Author Share Posted August 26, 2014 I see where the confusion coming in is at, I should have taken that out when I posted the script up, here's the original version I was using, it works fine, except for what I was explaining up there. It won't place the "Word" into the sentence as it should when it doesn't find it in the list, instead it just completely cuts out and does nothing, but it will translate words that ARE in the list if yout ry to translate a sentence again with just those words, as I explained above. integer Translate(integer line){ word = llList2String(PList, line); //take the word found = llListFindList(EnglishList, [word]); //Is that word in English vocabulary? found >=0 - if NOT found, found = -1 integer i; integer length = llGetListLength(EnglishList); for(i=0; i < length;i++) { if (found >=0) reqNC_Gorean = llGetNotecardLine("Gorean", found); //if English word is in vocabulary, find translation on G Notecard else if(found == -1) //English word is NOT in dictionary GSentence += word; //Add that to the G sentence }} Link to comment Share on other sites More sharing options...
Yurtiel Posted August 26, 2014 Author Share Posted August 26, 2014 (Sorry, I also removed the integer translate bit so it's back to translate(integer line) ) Link to comment Share on other sites More sharing options...
Rolig Loon Posted August 26, 2014 Share Posted August 26, 2014 That's OK. It's not surprising that it has taken you a while to tease out the problem. There's more than one, and the integer business was a red herring that had us both going for a while. You got my curiosity going, though, so I poked at it for a bit. Compare this working version with yours and see if you can find what I did..... list EnglishList = [];list Punctuation = [" ", "\"", "$", "(", ")", ".", ",", ";", ":", "-", "?", "!", "=", "*"];//All Punctuation parsed away except ' and - These may be parts of English wordsstring GSentence; //THIS will be the translated sentence in Goreanstring word; //The Gorean word to be used in GSentence - will use XXXXX if word not in dictionaryinteger found; //The line in the Gorean notecard where the translation of the English word can be foundinteger foundLine= 0; //Counter on the number of wirds in the English sentenceinteger LL; //Length of parsed list generated from English sentencelist PList; //The parsed listkey reqNC_English; //Reading the English vocabulary into a listinteger LineE = 0; //English NC linekey reqNC_Gorean; //Reading the Gorean vocabulary, finding the right lineinteger LineG = 0; //Gorean NC lineinteger Consistency = FALSE; //Checking for same length of notecardskey reqE_Length; //Finding the length of the E notecardkey reqG_Length; //Finding the length of the G notecardinteger ELength;integer GLength;integer limit = 64000; ParseMessage(string message) //Prsing the English sentence (said on /93) parsing away punctuations{ PList = llParseString2List(message, Punctuation, []); LL = llGetListLength(PList); GSentence = ""; Translate(foundLine); //Go to translating the Parsed English sentence }Translate(integer line){ word = llList2String(PList, line); //take the word found = llListFindList(EnglishList, [word]); //Is that word in English vocabulary? found >=0 - if NOT found, found = -1 if (~found) { reqNC_Gorean = llGetNotecardLine("Gorean", found); //if English word is in vocabulary, find translation on G Notecard } else //English word is NOT in dictionary { GSentence += word + " "; //Add that to the G sentence if (foundLine < LL) { Translate(++foundLine); } else { llSay(0,GSentence); //Say the Gorean Sentence llMessageLinked(LINK_THIS,0,GSentence,""); llResetScript(); } }}default{ state_entry() { reqE_Length = llGetNumberOfNotecardLines("English"); //Get length of E notecard llSetMemoryLimit(limit); llScriptProfiler(PROFILE_SCRIPT_MEMORY); llScriptProfiler(PROFILE_NONE); } dataserver(key id, string data) { if(id == reqE_Length) //gets length of E notecard { ELength = (integer)data; reqG_Length = llGetNumberOfNotecardLines("Gorean"); //Now get length of G notecard } else if(id == reqG_Length) //Gets length of G notecard { GLength = (integer)data; if(GLength != ELength) //If they are NOT equally long (== inconsistent) { llOwnerSay("The Notecards do NOT have the same number of lines\n Fix that and try again!!"); } else if(GLength == ELength) //If they HAVE the same length { reqNC_English = llGetNotecardLine("English", LineE); //Get E notecard vocabulary into a list } } else if(id == reqNC_English) { if(data != EOF) //as long as we are NOT at the end of the NC { EnglishList += llToLower(data); //add a new line ++LineE; // increase the line number reqNC_English = llGetNotecardLine("English", LineE); //and get that next line } else if(data == EOF) //If we are at the end of the E notecrd (all words are in our list now) { llListen(93, "", NULL_KEY, ""); //Open a listen on channel 93 } } else if(id == reqNC_Gorean) //THIS is the continuation of the above "Translate" function, when our E word had been on the list { //Find the Gorean translation and add a space to that word GSentence += data + " "; //Add the word to the Gorean sentence ++foundLine; //go to next English word in Parsed list if(foundLine < LL) //If there is another English word { Translate(foundLine); //translate that now } else if(foundLine == LL) //No more E word to translate { foundLine = 0; llSay(0,GSentence); //Say the Gorean Sentence llMessageLinked(LINK_THIS,0,GSentence,""); llResetScript(); } } } listen(integer channel, string name, key id, string message) //Listening on channel 93 { if(channel != 93 || id != llGetOwner()) return; else if(channel == 93 && id == llGetOwner()) //If said on correct channel { ParseMessage(llToLower(message)); //Go parse that English sentence } } changed(integer change) { if(change & CHANGED_INVENTORY || change & CHANGED_OWNER) llResetScript(); //Reset if inventory is changed }} Link to comment Share on other sites More sharing options...
Yurtiel Posted August 26, 2014 Author Share Posted August 26, 2014 Oh wow, now that I look at it it seemed so obvious. Isn't having the recursion in the translate function bad though? I was doing that before and it was causing it to have stack heap crashing errors. Link to comment Share on other sites More sharing options...
Rolig Loon Posted August 26, 2014 Share Posted August 26, 2014 Recursion is not bad in itself. Only if it leads to an endless spiral of hopelessness. In this case, we want to be sure that we won't go through the routine after we run out of words to check. If we always check to see when we have sampled that last word, we're OK. Now, you could still have a serious memory issue if you try saving too many words in memory. One way to avoid that is to read through both the English card and the Gorean card every time you have to translate each word, but that is painfully slow. In the end, there's no way to get around the limitations of LSL, which was never intended to do this sort of job. Link to comment Share on other sites More sharing options...
Yurtiel Posted August 26, 2014 Author Share Posted August 26, 2014 Ah I see, thanks a ton, you've helped me more in less than 30 minutes than others did in an entire three days. I understand that, this was mainly just a way for me to experiment with data serve and take it in, it is rather ridiculous that script memory is limited so low, and that it breaks with such stupid reasons. SL is about as poorly optimized as you'd expect though require a ton of byte data for something that should be stupidly simple to process. Anyway, thank you for the help, it's much appreciated, and I gained a lot of new knowledge from it. Link to comment Share on other sites More sharing options...
Rolig Loon Posted August 26, 2014 Share Posted August 26, 2014 YW. Don't be too hard on LSL, though. It's the Little Engine That Could, not the Orient Express. Scripters moan and groan about its limitations, but the fact is that LSL was designed basically to move objects around and handle simple communications. It does that pretty well. It was never meant for doing scientific calculations or translation problems that require a large amount of memory. If you really want to do that stuff, do it on an external server and pass the results in world when you finish. Link to comment Share on other sites More sharing options...
Recommended Posts
Please take a moment to consider if this thread is worth bumping.
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now