Lua: How to execute different blocks depending on conditions? - function

I have this table:
no_table ={
{a="3", b="22", c="18", d="ABC"},
{a="4", b="12", c="25", d="ABC"},
{a="5", b="15", c="16", d="CDE"},
}
This function:
function testfoo()
i = 1
while no_table[i] ~= nil do
foo(no_table[i])
i = i + 1
end
end
and the foo function:
function foo(a,b,c,d)
if no_table[i][4] ~= no_table[i-1][4]
then
print (a+b)
elseif no_table[i][4] == no_table[i-1][4]
then
print (b+c)
end
end
Can you help me find? :
A way to be able to check if the two tables are or not equal (currently it gives me cannot index nil)
A way to execute only the "print (b+c)" code if the equality is true, or if is not true then both "print (a+b)" first and "print (b+c) secondly without duplicating the code.

Lots of problems I'm seeing in this. First, I'd never rely on i being set in an external function, it really should be a local variable and passed as a parameter if you need it. That said, you need to check if no_table[x] exists before trying to access no_table[x][y]. So, for foo you'd have:
function foo(a,b,c,d)
if not (no_table[i] and no_table[i-1] and no_table[i][4] == no_table[i-1][4])
then
print (a+b)
elseif no_table[i] and no_table[i-1] and no_table[i][4] == no_table[i-1][4]
then
print (b+c)
end
end
Also, for numbers in the table, if you want to do arithmetic, you need to remove the quotes:
no_table ={
{a=3, b=22, c=18, d="ABC"},
{a=4, b=12, c=25, d="ABC"},
{a=5, b=15, c=16, d="CDE"},
}
Next, in testfoo, you're passing a table, so you either need to split out the values of a, b, c, and d on your function call, or you can just pass the table itself and handle that in foo:
function foo(t)
if not (no_table[i] and no_table[i-1] and no_table[i][4] == no_table[i-1][4])
then
print (t.a+t.b)
elseif no_table[i] and no_table[i-1] and no_table[i][4] == no_table[i-1][4]
then
print (t.b+t.c)
end
end
This results in:
> testfoo()
25
37
31
Edit: One final cleanup, since the conditions are the same, you can use an else rather than an elseif:
function foo(t)
if no_table[i] and no_table[i-1] and no_table[i][4] == no_table[i-1][4]
then
print (t.b+t.c)
else
print (t.a+t.b)
end
end

Related

How can I run through all these ifs in python?

When I run the program It will only run the first If and make those specific changes. Noticed when i switched them around and only the first one gives me what I want... Thanks for the help.
if SW1 != r['SW1']: #check the received value of SW1 & change it on the App if there is a mismatch
print("Changing SW1 status to the value in the database.")
if self.sw1.active == True:
self.sw1.active = False
else:
self.sw1.active = True
else:
return
if LED1 != r['LED1']: #check the received value of led1 & change it on the App if there is a mismatch
print("Changing LED1 status to the value in the database.")
if self.led1.active == True:
self.led1.active = False
else:
self.led1.active = True
else:
return
if LED2 != r['LED2']: #check the received value of led2 & change it on the App if there is a mismatch
print("Changing LED2 status to the value in the database.")
if self.led2.active == True:
self.led2.active = False
else:
self.led2.active = True
else:
if LED3 != r['LED3']: #check the received value of led3 & change it on the App if there is a mismatch
print("Changing LED3 status to the value in the database.")
if self.led3.active == True:
self.led3.active = False
else:
self.led3.active = True
else:
return
You should not return in else after every if. This will make the function to close after the first if is failed. I will explain it further with one example.
Take this function which checks if a number is even.
def foo_bar(n):
if n%2==0:
print("Even")
else:
return
print("I have been reached")
If an even number is passed, you will see the below output
>>> foo_bar(10)
Even
I have been reached
If the Odd number is passed, you will not see any output as the function is returning None and Terminated in else.
Now if you have multiple ifs in the function,
def foo_bar(n):
if n%2==0:
print("Even")
else:
return
if n%3==0:
print("Divisible by 3")
print("I have been reached")
If you pass 9 as an argument, the above function prints nothing. It is because after one condition is checked , you are returning None which terminates the function.
Hope this answers your question.

Substring question on mips assembly language

Please help as soon as possible...
Write a MIPS assembly language program that prompts the user to input two strings (each should be no longer than 50 characters including the null terminator). Your program should determine whether the second string is a substring of the first. If it is, then your program should print out the first index in which the second string appears in the first. For example, if the first string is “Hello World” and the second string is “lo”, then the program should print out 3, i.e. the starting index of “lo” in “Hello World.” If the second string is not contained in the first string, then your program should print out -1.
To be able to understand what you have to implement at assembly level, the first thing you should do, is understanding the high-level algorithm. Why?
It's easier for you to see all the cases and edge-cases in time!
To look back at what have I been trying to do again? in the middle of programming the Assembly version.
To quickly see which variables you (certainly) need.
I wrote following program (forgive me, python has been a while for me):
def is_in_string_1(string, substring):
"""
aaba: a, b, ab, ba, aba (last one will fail)
"""
length = len(string)
sublength = len(substring)
if (sublength == 0):
return True
j = 0
for i in range(0, length):
if string[i] != substring[j]:
j = 0
else:
j += 1
if j == sublength:
return True
return False
def is_in_string_2(string, substring):
"""
aaba: a, b, ab, ba, aba
"""
length = len(string)
sublength = len(substring)
for i in range(0, length + 1 - sublength): # string: aabc; substring: c; length: 4; sublength: 1; indexes: 0,1,2,3;
is_substring = True
for j in range(0, sublength): # for the sake of the algorithm, no slicing here
if string[i+j] != substring[j]:
is_substring = False
break
if is_substring:
return True
return False
stringTuples = [
("aaa", "aa"),
("aaa", "aaa"),
("aaa", "aab"),
("abc", "bc"),
("abc", "a"),
("abc", "abc"),
("aaa", ""),
("aaa", "b")
]
for stringTuple in stringTuples:
print(
stringTuple[0],
stringTuple[1],
':',
is_in_string_1(stringTuple[0], stringTuple[1]),
is_in_string_2(stringTuple[0], stringTuple[1]),
sep='\t'
)
I first thought I could optimize the standard solution (is_in_string_2), leaving out the second for-loop (is_in_string_1), but after some thinking I already found out it would fail (the edge-case wasn't even in any of my test-data!) - so I left it as an example for how important it is that you use a correct algorithm.
The program produces the following output:
aaa aa : True True
aaa aaa : True True
aaa aab : False False
abc bc : True True
abc a : True True
abc abc : True True
aaa : True True
aaa b : False False
aaba aba : False True
Notice how all output was correct, except for the last line, where the first algorithm is wrong.
Before you continue:
You have to make your own len() function in MIPS; note that all string are (if I remember correctly) null terminated, so you'll have to count all non-null characters of a string, or in other words, count how many characters precede the null-terminator.
You should use j, $ra and jr calls to go to a "function" or subroutines. (Search)
While in one, you can call other functions using the stack. (Search)

Lua - Concatinate several arguments passed into a function, until condition is met, then pass string to next function

pvMessage is sent from another function, the message often comes in a few parts almost instantly. I am looking to store the pvMessages and concatinate the message to the last. Therefore a master string is created with all parts.
Example.
pvMessage #1 = thisispart1msg
pvMessage #2 = now part two is being received
pvMessage #3 = Part 3
MasterMessage = thisispart1msgnow part two is being receivedPart 3
I have tried several attempts at solving this issue. The storing of the message outside the function is proving harder then I though, I keep overwriting the previous message.
function ProcessClientMessage( pvMessage )
if StartMessage == "" then
StartMessage = pvMessage
pvMessage = ""
end
if pvMessage ~= "" then
if MiddleMessage == "" then
MiddleMessage = pvMessage
pvMessage = StartMessage .. MiddleMessage
pvMessage = ""
end
end
if pvMessage ~= "" then
if EndMessage == "" then
EndMessage = pvMessage
pvMessage = StartMessage .. MiddleMessage .. EndMessage
pvMessage = ""
end
end
if pvMessage ~= "" then
ProcessClientMessageReset()
end
end
If there are always three parts that you want to concatenate, something like this may work:
local buffer = {}
local function ProcessClientMessage(pvMessage)
if #buffer < 3 then
table.insert(buffer, pvMessage)
else
--ProcessClientMessageReset(table.concat(buffer, ""))
print(table.concat(buffer, ""))
buffer = {}
end
end
ProcessClientMessage("thisispart1msg")
ProcessClientMessage("now part two is being received")
ProcessClientMessage("Part 3")
ProcessClientMessage("more thisispart1msg")
ProcessClientMessage("some now part two is being received")
ProcessClientMessage("Part 4")
This should print:
thisispart1msgnow part two is being receivedPart 3
more thisispart1msgsome now part two is being receivedPart 4
This problem also be solved with coroutines:
local function consumer(consume)
print(consume()..consume()..consume())
return consumer(consume)
end
local process = coroutine.wrap(consumer)
process(coroutine.yield)
process('foo')
process('bar')
process('baz')
process('hello')
process('world')
process('test')
EDIT: As Egor pointed out, the order of evaluation isn't technically defined (although it's left to right in every Lua implementation I'm aware of) so here's an alternative that would work even if your interpreter was doing gcc -O3-like optimizations:
local function consumer(consume)
local a = consume()
local b = consume()
local c = consume()
print(a .. b .. c)
return consumer(consume)
end
You can make use of the "or" assignment to simplify initialization of the global variable and then concatenate the string to the result. Consider:
function ProcessClientMessage(msg)
msg_global_ = (msg_global_ or "")..msg
print(msg_global_) -- Just for debug purposes so we can print each step
end
do
ProcessClientMessage("thisispart1msg")
ProcessClientMessage("now part two is being received")
ProcessClientMessage("Part 3")
end
The variable msg_global_ contains the string being built. If it has not been added too yet, then it will be nil. In this case the or "" will be executed and default the string empty.
We then simply append the string msg.
The output looks like:
thisispart1msg
thisispart1msgnow part two is being received
thisispart1msgnow part two is being receivedPart 3
When you actually process the message, just set the global variable to nil and you are good to go again.

mysql-proxy result field manipulation

I have a MYSQL server and MYSQL-PROXY and I am trying to manipualte the results I send to the client as a response to a SELECT query. I have writen this code in lua:
function string.starts(String,Start)
return string.sub(String,1,string.len(Start))==Start
end
function read_query_result(inj)
local fn = 1
local fields = inj.resultset.fields
while fields[fn] do
fn = fn + 1
end
fn = fn - 1
print("FIELD NUMBER: " .. fn)
for row in inj.resultset.rows do
print ("--------------")
for i = 1, fn do
if (string.starts(fields[i].name,"TEST")) then
row[i]="TESTED"
end
print ("DATA: " .. fields[i].name .. " -> " .. row[i])
end
end
return proxy.PROXY_SEND_RESULT
end
I can correctly read the field names and values. I can detect the condition where I want the result modified, but I can not get the data sent to the client.
I see two problems:
I am setting the value in the local row variable, but I have not found the way to set the real resultset (inj.Resultset.row[i] or something similar).
There is something wrong with return proxy.PROXY_SEND_RESULT, because I am seeing that whenever I comment that sentence I see the results, and If I uncomment it I get an error.
I have not found example code as a reference.
Ok. Solved.
Data has to be inserted in a table
PROXY_SEND_RESULT requires proxy.response.type to be set.
This is the correct module:
function read_query_result(inj)
local fn = 1
local fields = inj.resultset.fields
proxy.response.resultset = {fields = {}, rows = {}}
while fields[fn] do
table.insert(proxy.response.resultset.fields, {type = proxy.MYSQL_TYPE_STRING, name = fields[fn].name})
fn = fn + 1
end
fn = fn - 1
for row in inj.resultset.rows do
for i = 1, fn do
if (string.starts(fields[i].name,"TEST")) then
row[i]="TESTED"
end
end
table.insert(proxy.response.resultset.rows, row )
end
proxy.response.type = proxy.MYSQLD_PACKET_OK
return proxy.PROXY_SEND_RESULT
end

How to obtain a random word using function and dictionary? (Python 3)

The user has to select a category. And from there, the program has to generate a random word from the category list. If the user selected an invalid category, the program will prompt the user to choose a category again (loop the askCat function again).
import random
#Make word dictionary
wordDict = {'Animals':['Giraffe','Dog','Dolphin','Rabbit','Butterfly'], \
'Fruits': ['Apple','Pineapple','Durian','Orange','Rambutan'], \
'Colours': ['Red','Blue','Yellow','Green','Purple'], \
'Shapes': ['Heart','Circle','Rectangle','Square','Diamond']}
#Determine word category and random word
def askCat (wordDict):
category = str( input ("To start the game, please choose a category: \n Animals (a), Fruits (f), Colours (c), Shapes (s) "))
print()
if category == 'a':
print ("You chose the Animals category.")
cat = (wordDict['Animals'])
elif category == 'f':
print ("You chose the Fruits category.")
cat = (wordDict['Animals'])
elif category == 'c':
print ("You chose the Colours category.")
cat = (wordDict['Animals'])
elif category == 's':
print ("You chose the Shapes category.")
cat = (wordDict['Animals'])
else:
print ("You entered an invalid category. Try again!")
print()
askCat(wordDict)
return random.choice(cat)
#Print random word
randWord = askCat(wordDict)
print (randWord)
When on the first try, the user enter a valid category, the program works just fine. However, the problem I'm facing is that, when the user enter an invalid category the first time, and when he enter a valid category the second time, the program don't work anymore.
Please do help! Thanks (:
else:
print ("You entered an invalid category. Try again!")
print()
askCat(wordDict)
return random.choice(cat)
In the else branch, you are recursively calling the function again—which is okay—and then you discard its return value and return cat instead which, in this call of the function, was never set.
Instead, you should return the value from the recursive call:
else:
print ("You entered an invalid category. Try again!")
print()
return askCat(wordDict)
return random.choice(cat)
That way, when you call it recursively, the result from that call will be used, and not the one you tried to get from the current cat.
Furthermore, in each of your branches, you are doing cat = (wordDict['Animals']); you probably want to change that so you actually get fruits for f etc.
And finally, while using recursion is okay, it’s not the best way to handle this. Recursion always has a maximum depth it can into, so in the worst case, a user could keep answering the wrong thing increasing the recursion stack further, until the program errors out. If you want to avoid that, you should use a standard loop instead:
cat = None
while not cat:
# You don’t nee to use `str()` here; input always returns a string
category = input("To start the game, please choose a category: \n Animals (a), Fruits (f), Colours (c), Shapes (s) ")
print()
if category == 'a':
print("You chose the Animals category.")
cat = wordDict['Animals'] # no need to use parentheses here
elif category == 'f':
# ...
# and so on
else:
print("You entered an invalid category. Try again!")
# the loop will automatically repeat, as `cat` wasn’t set
# when we reach here, `cat` has been set
return random.choice(cat)
In your function askCat, if the user first enter a wrong category, you call again askCat. However, you don't return the value returned by that call.
Replace (in the function askCat):
askCat(wordDict)
to:
return askCat(wordDict)
However, I would strongly recommend you to use a while loop instead.