How do I get a random index of a table in Lua? - lua

How do I get a random question from qus, a table of four questions?
-- qus = table of questions
for i = 1 , 4 do
qus = {}
qus[i] = "what is your name?"
qus[i] = "how old are you?"
qus[i] = "where are you living?"
qus[i] = "what are you doing?"
local label = display.newText(qus[i],160,100)
end
print(qus[i])
-- Prints:
-- what are you doing
-- what are you doing
-- what are you doing
-- what are you doing
I tried this:
qus[1] = "what is your name?"
qus[2] = "how old are you?"
qus[3] = "where are you living?"
qus[4] = "what are you doing?"
label = all qus shows
Thank you for anyone who can help.

Use math.random() function:
local qus = {}
qus[1] = "what is your name?"
qus[2] = "how old are you?"
qus[3] = "where are you living?"
qus[4] = "what are you doing?"
math.randomseed(os.time ()) -- init generator
local index = math.random(#qus) -- between 1 and 4 (size of table)
print(qus[index])

Related

LUA - Most common item in the table

I have a table like below, I don't need to know which product sells how much, I just want to know which product is the most popular. Do you have any idea which method is the best way to do this?
Like in the example below, knowing that because 3 of the product "blue" have been sold, it is the most popular
local products = {}
products["430373bb5b7a40a04f9"] = "red"
products["0dce4263af4b5cfe0de"] = "red"
products["cf2559afb736c1eb1bc"] = "green"
products["abc4d248541c3386c88"] = "blue"
products["bb9386c65270948ebee"] = "blue"
products["b193fba741cd646a9c0"] = "blue"
this example will count the number of sales in a single pass.
local products = {}
products["430373bb5b7a40a04f9"] = "red"
products["0dce4263af4b5cfe0de"] = "red"
products["cf2559afb736c1eb1bc"] = "green"
products["abc4d248541c3386c88"] = "blue"
products["bb9386c65270948ebee"] = "blue"
products["b193fba741cd646a9c0"] = "blue"
local pop = {}
for k,v in pairs(products) do
pop[v] = (pop[v] or 0) + 1
end
-- if you need to sort by sales then:
local pop_s = {}
for k,v in pairs(pop) do
pop_s[#pop_s+1] = { item=k, sales=v}
end
table.sort(pop_s, function (a,b) return a.sales>b.sales end)
for k,v in pairs(pop_s) do
print(v.item,v.sales)
end
result:
blue 3
red 2
green 1
To expand on Mike's answer: You could even sort the counts in linear (vs. O(n log n)) time since you know that the counts range from 1 to n; thus you can use a "bucket" approach where you use an index of products by count sold:
local products = {
["430373bb5b7a40a04f9"] = "red",
["0dce4263af4b5cfe0de"] = "red",
["cf2559afb736c1eb1bc"] = "green",
["abc4d248541c3386c88"] = "blue",
["bb9386c65270948ebee"] = "blue",
["b193fba741cd646a9c0"] = "blue",
}
local counts = {}
for _, product in pairs(products) do
counts[product] = (counts[product] or 0) + 1
end
local prods_by_cnt = {}
local max_cnt = 0
for product, count in pairs(counts) do
prods_by_cnt[count] = prods_by_cnt[count] or {}
table.insert(prods_by_cnt[count], product)
max_cnt = math.max(max_cnt, count)
end
local prods_sorted = {}
for cnt = 1, max_cnt do
for _, prod in ipairs(prods_by_cnt[cnt]) do
table.insert(prods_sorted, prod)
end
end
Side note: There is no need to build tables {item = ..., sales = ...} as long as you have the counts table: You can just keep a table of item names and use the item names to index the counts table. This may be slightly slower in practice because the counts table is larger and thus presumably more expensive to index - on the other hand, it is more memory-efficient; in theory, both are equally fast and memory efficient, requiring a constant time for lookup of the sales / counts and constant space to store each count.
Try this:
local products = {}
products["430373bb5b7a40a04f9"] = "red"
products["0dce4263af4b5cfe0de"] = "red"
products["cf2559afb736c1eb1bc"] = "green"
products["abc4d248541c3386c88"] = "blue"
products["bb9386c65270948ebee"] = "blue"
products["b193fba741cd646a9c0"] = "blue"
function GetCommonItem(arr)
local Count = 0
local Product = null
for i, v in pairs(arr) do -- Loops through the table
local Temp = 0
for e, f in pairs(arr) do -- Loops again to count the number of common products
if f = v then
Temp += 1
if Temp >= Count then -- Picks the product if it's the most common one
Count = Temp
Product = f
end
end
end
end
return Product
end
print("Most Common Product: ".GetCommonItem(products))
Didn't test so not sure if it works! Let me know the results after u try it!

lua text-based fighting system

Ok, so I am trying to create a text-based adventure game. I am currently creating the attack system. Here is the code
start = io.read()
if start == "start" then
ma1 = "jab your opponent"
ma2 = "hook your oppenent"
fa1 = "kick your oppenent"
ha1 = "headbutt your oppenent"
--Melee weapon
mw1 = "fist1"
mw2 = "fist2"
foot = "Kick"
head = "headbutt"
--Magic attacks
ms1 = "none"
ms2 = "none"
ms3 = "none"
ms4 = "none"
--Gadgets
bow = "none"
gun = "none"
sg = "none"
function atk()
io.write("Do you use melee(1), magic(2), or tech(3)?", "\n")
ac = io.read()
if ac == "1" then
io.write("Do you", ma1,",", ma2, ",",fa1,",or",ha1"?", "\n")
end
end
end
print(atk())
Every time I run this it outputs this:
lua: jdoodle.lua:25: global 'ha1' is not callable (a string value)
stack traceback:
jdoodle.lua:25: in function 'atk'
jdoodle.lua:29: in main chunk
[C]: in ?
So if you have any solutions thank you.
You missed a comma:
start = io.read()
if start == "start" then
--body
if ac == "1" then
io.write("Do you", ma1, ", ", ma2, ", ", fa1, ", or", ha1, "?", "\n")
end
end
print(atk())

How do I use Pytorch's "tanslation with a seq2seq" using my own inputs?

I am following the guide here
Currently this is the model:
SOS_token = 0
EOS_token = 1
class Lang:
def __init__(self, name):
self.name = name
self.word2index = {}
self.word2count = {}
self.index2word = {0: "SOS", 1: "EOS"}
self.n_words = 2 # Count SOS and EOS
def addSentence(self, sentence):
for word in sentence.split(' '):
self.addWord(word)
def addWord(self, word):
if word not in self.word2index:
self.word2index[word] = self.n_words
self.word2count[word] = 1
self.index2word[self.n_words] = word
self.n_words += 1
else:
self.word2count[word] += 1
def unicodeToAscii(s):
return ''.join(
c for c in unicodedata.normalize('NFD', s)
if unicodedata.category(c) != 'Mn'
)
# Lowercase, trim, and remove non-letter characters
def normalizeString(s):
s = unicodeToAscii(s.lower().strip())
s = re.sub(r"([.!?])", r" \1", s)
s = re.sub(r"[^a-zA-Z.!?]+", r" ", s)
return s
def readLangs(lang1, lang2, reverse=False):
print("Reading lines...")
# Read the file and split into lines
lines = open('Scribe/%s-%s.txt' % (lang1, lang2), encoding='utf-8').\
read().strip().split('\n')
# Split every line into pairs and normalize
pairs = [[normalizeString(s) for s in l.split('\t')] for l in lines]
# Reverse pairs, make Lang instances
if reverse:
pairs = [list(reversed(p)) for p in pairs]
input_lang = Lang(lang2)
output_lang = Lang(lang1)
else:
input_lang = Lang(lang1)
output_lang = Lang(lang2)
return input_lang, output_lang, pair
MAX_LENGTH = 5000
eng_prefixes = (
"i am ", "i m ",
"he is", "he s ",
"she is", "she s ",
"you are", "you re ",
"we are", "we re ",
"they are", "they re "
)
def filterPair(p):
return len(p[0].split(' ')) < MAX_LENGTH and \
len(p[1].split(' ')) < MAX_LENGTH and \
p[1].startswith(eng_prefixes)
def filterPairs(pairs):
return [pair for pair in pairs if filterPair(pair)]
def prepareData(lang1, lang2, reverse=False):
input_lang, output_lang, pairs = readLangs(lang1, lang2, reverse)
print("Read %s sentence pairs" % len(pairs))
pairs = filterPairs(pairs)
print("Trimmed to %s sentence pairs" % len(pairs))
print("Counting words...")
for pair in pairs:
input_lang.addSentence(pair[0])
output_lang.addSentence(pair[1])
print("Counted words:")
print(input_lang.name, input_lang.n_words)
print(output_lang.name, output_lang.n_words)
return input_lang, output_lang, pairs
The difference between what I'm trying to do and the guide is that I'm trying to insert my input languages as list of strings instead of reading them from a file:
pairs=['string one goes like this', 'string two goes like this']
input_lang = Lang(pairs[0][0])
output_lang = Lang(pairs[1][1])
But I it seems like when I try to count the number of words input_lang.n_words in my string I always get 2.
Is there something I'm missing in calling the class Lang?
Update:
I ran
language = Lang('english')
for sentence in pairs: language.addSentence(sentence)
print (language.n_words)
and that gave me the number of words in pairs
Though, that doesn't give me input_lang and output_lang like the guide did:
for pair in pairs:
input_lang.addSentence(pair[0])
output_lang.addSentence(pair[1])
So first of all you are initialising the Lang object with calls to pairs[0][0] and pairs[1][1] which is the same as Lang('s') and Lang('t')
The Lang object is supposed to be an object that stores information about a language so I would expect you need to only initialise it once with Lang('english') and then add the sentences from you dataset to the Lang object with the Lang.addSentence function.
Right now you aren't loading your dataset into the Lang object at all so when you want to know language.n_words it is just the initial value it gets when the object is created self.n_words = 2 # Count SOS and EOS
None of what you are doing in your question makes any sense, but I think what you want is the following:
language = Lang('english')
for sentence in pairs: language.addSentence(sentence)
print (language.n_words)

How to remove a number from a table?

I have no idea why this is not working. I am trying to delete the numbers in the table one by one (the randomCheck picks a number from the table and I want to delete that exact number) when I press the button 'MyButton'
math.randomseed(os.time())
_X = display.contentCenterX
_Y=display.contentCenterY
local numbers = {1,2,3,4,5,6,7,8,9,10}
local randomCheck = numbers[ math.random( #numbers) ]
local text = display.newText(""..randomCheck.."",_X,_Y,"Helvetica",50)
function removeNumber()
for i = 1, 10 do
if(randomCheck == i ) then
table.remove(numbers,i)
text.text = (""..i.."")
end
end
end
myButton = display.newRect(_X,_Y+100,100,80 )
myButton:addEventListener("tap", removeNumber)
In your loop, instead of
if(randomCheck == i)
use
if(randomCheck == numbers[i])
But all of that work is really unnecessary.
Instead of
local randomCheck = numbers[math.random( #numbers)]
use
local randomIndex = math.random(#numbers)
local randomCheck = numbers[randomIndex]
Then you can just
table.remove(numbers, randomIndex)

Lua string.gsub inside string.gmatch?

I've created this simple example script to output a list of foods. If the food is a fruit then the color of the fruit will be displayed as well. The issue I'm having is in dealing with the irregular pluralization of 'strawberries.'
fruits = {apple = "green", orange = "orange", stawberry = "red"}
foods = {"potatoes", "apples", "strawberries", "carrots", "crab-apples"}
for _, food in ipairs(foods) do
for fruit, fruit_colour in pairs(fruits) do
duplicate = false
if (string.match(food, "^"..fruit) or string.match((string.gsub(food, "ies", "y")), "^"..fruit)) and not(duplicate) then -- this is where the troubles is!
print(food.." = "..fruit_colour)
duplicate = true
break
end
end
if not(duplicate) then
print(food)
end
end
Right now the program outputs:
potatoes
apples = green
strawberries
carrots
crab-apples
What I want is:
potatoes
apples = green
strawberries = red
carrots
crab-apples
I can't figure out why this doesn't work like I want it to!
Well for one thing, you miss-spelled strawberry here:
fruits = {apple = "green", orange = "orange", stawberry = "red"}
You can also work with lua tables as sets, which means that nested loop searching for duplicates is unnecessary. It can be simplified to something like:
fruits = {apple = "green", orange = "orange", strawberry = "red"}
foods = {"potatoes", "apples", "strawberries", "carrots", "crab-apples"}
function singular(word)
return word:gsub("(%a+)ies$", "%1y"):gsub("(%a+)s$", "%1")
end
for _, food in ipairs(foods) do
local single_fruit = singular(food)
if fruits[single_fruit] then
print(food .. " = " .. fruits[single_fruit])
else
print(food)
end
end
stawberry should be strawberry. The loop changes strawberries to strawberry and then tries to match strawberry against ^stawberry, but the typo causes it not to match.

Resources