How do I format values in my lua table to be: t = {['foo'] = true, ['bar'] = true}? - dictionary

This is in relation to a previous question: Checking values across multiple location and returning a match only if the sources are unique.
Essentially, the function relys on the data being in the format:
local vendors = {
Asda = {Kellogg = true, Cadbury = true, Nestle = true, Johnsons = true, Pampers = true, Simple = true},
Tesco = {Kellogg = true, Cadbury = true, Nestle = true, Johnsons = true},
Spar ={Nestle = true, Johnsons = true, Pampers = true, Simple = true}
}
However, I am collecting the data by cycling through path locations and adding them into a table, which just creates a list such as:
Asda = {"Kellogg", "Cadbury", "Nestle", "Johnsons", "Pampers", "Simple"}
There is another way I can add them:
local Asda = {}
for index = 1, 9 do
local pathAsda = factReference -- some path location which changes by index increasing
if pathAsda ~= "" then
Asda[#Asda+1] = {[Asda] = true} -- table.insert(Asda, pathAsda), for the previously mentioned format
end
Which would leave me with:
Asda= {{Kellogg = true}, {Cadbury = true}, {Nestle = true}, {Johnsons = true}, {Pampers = true}, {Simple = true}}
I'd then use:
table.insert(vendorSources,Asda)
Neither of these formats work with the function in the answer and I can't seem to figure out how to amend any section to enable this to work.
function intersection(s1, s2) -- finds out if two sets (s1 & s2) overlap
local output = {}
for key in pairs(s1) do
output[#output + 1] = s2[key]
end
return output
end
Is there a way to edit either list (Asda) to be in the correct format?

You'd need to use Asda[pathAsda] = true instead of Asda[#Asda+1] = {[pathAsda] = true}, but keep in mind that the order elements is not guaranteed in this case.

Related

Send json-body with array in it

I need to send post-request with json-body
The body contains a parameter cart, which is actually an array
"cart": [{"nid": "123","groupId": "123","price": "200.00","priceWithDiscount": "200.00","amount": "1.0"}]
To assemble cart i have this code (double list is for square brackets):
args <- list(list(price="200.00",priceWithDiscount="200.00",amount="1.0",nid="123",groupId="123"))
x <- jsonlite::toJSON(args, pretty = TRUE,auto_unbox = T)
And full request:
answer <- content(POST("https://url.com",
body = list(
sum = '200',
sumDiscount = '200',
guid = 'test_26112021',
number = 'test_26112021',
date = paste0(Sys.time()),
bonusAdd = '0',
bonusWriteOff = '0',
depositAdd = '0',
depositWriteOff = '0',
cart = x
),encode="json"))
This request responds an error "The cart field must be a array." so I guess I was mistaken in this part of the code
Thanks to #deschen's comment, the solution is:
args1<-list(list(price="200.00",priceWithDiscount="200.00",amount="1.0",nid="123",groupId="123"))
args2<-list(guid='test_26112021',sum='200',sumDiscount='200',number='test_26112021',date=paste0(Sys.time()),bonusAdd='0',bonusWriteOff='0',depositAdd='0',depositWriteOff='0',cart=args1)
body <- jsonlite::toJSON(args2, pretty = TRUE, auto_unbox = T)
answer <- content(POST("https://url.com", content_type_json(),body = body, encode="json"))

Getting the output of a script in Matlab called from R

I am trying to call a very simple script in Matlab from RStudio. However, whenever I run the following code, without getting any error, it will return 0 to me. Would you please let me know how I can call Matlab scripts in R and get their outputs?
run_matlab_script("C:/Users/XXX/Desktop/Sum.m", verbose = TRUE, desktop = FALSE, splash = FALSE,
display = TRUE, wait = TRUE, single_thread = FALSE)
Note that to use the above function, I am using "matlabr" package in r. Moreover, my simple script in Matlab includes the below code:
b=1+2
Thanks in advance!
matlab::run_matlab_script uses system to call matlab. As of today, that function (current commit is c01d310) looks like:
run_matlab_script = function(
fname,
verbose = TRUE,
desktop = FALSE,
splash = FALSE,
display = FALSE,
wait = TRUE,
single_thread = FALSE,
...){
stopifnot(file.exists(fname))
matcmd = get_matlab(
desktop = desktop,
splash = splash,
display = display,
wait = wait,
single_thread = single_thread)
cmd = paste0(' "', "try, run('", fname, "'); ",
"catch err, disp(err.message); ",
"exit(1); end; exit(0);", '"')
cmd = paste0(matcmd, cmd)
if (verbose) {
message("Command run is:")
message(cmd)
}
x <- system(cmd, wait = wait, ...)
return(x)
}
Noteworthy (to me) is that run_matlab_script includes ... in its formals, and passes that unchanged to system. In fact, its help documentation specifically says that is what it does:
#' #param ... Options passed to \code{\link{system}}
Because of this, we can try to capture its output by looking at system. From ?system,
intern: a logical (not 'NA') which indicates whether to capture the
output of the command as an R character vector.
which suggests that if you change your call to
ret <- run_matlab_script("C:/Users/XXX/Desktop/Sum.m", verbose = TRUE, desktop = FALSE,
splash = FALSE, display = TRUE, wait = TRUE, single_thread = FALSE,
intern = TRUE)
you will get its output in out.

I need to write this data to a .csv file

I'm using the following query and trying to write the results to a .csv file:
.libPaths("G:/R/R-3.6.1/library")
library(mongolite)
library(data.table)
library(dplyr)
###Path to list of search terms
#------------------------------------------------------------------------------------------------------------#
#Input the words you want to search in a text file, and call the text file below in place of ".txt"
#-------------------------------------------------------------------------------------------------------------#
searchStrings = readLines("//int/elm/Work/Text Analytics/Opportunities/New Folder/terms.txt")
searchCounts = data.table(searchString = searchStrings, count = 0)
db <- mongo(collection = "2020Emails", db = "textAnalytics", verbose = TRUE,
url = "mongodb://user:m0ng0b0ng0#interactionsprojection:7999/textAnalytics")
firstQuery = TRUE
#Update this JSON if if you want different fields returned
fieldsjson = '{"DocEid" : true,
"RequestType" : true,
"FromEmailAddress" : true,
"ReceiptTime" : true,
"RawBodyText" : true,
"CMF" : true,
"ReplyTo" : true,
"InboundMode" : true,
"PartNumbers" : true,
"_id": false}'
for (term in searchStrings) {
queryString = paste0('{"$text" : { "$search" : "\\"',term,'\\"" }}')
if (firstQuery == TRUE) {
results = NULL
results = data.table(db$find(query = queryString, fields = fieldsjson))
if (nrow(results) > 0) {
results[, searchString := term]
searchCounts[searchString == term, count := nrow(results)]
firstQuery = FALSE
}
} else {
tempdt = data.table(db$find(query = queryString, fields = fieldsjson))
if (nrow(tempdt) > 0) {
tempdt[, searchString := term]
results = rbind(results,tempdt, fill= TRUE)
searchCounts[searchString == term, count := nrow(tempdt)]
}
}
}
View(results)
#------------------------------------------------------------------------------#
# Specify the location and new file name where the results will be stored below
#------------------------------------------------------------------------------#
fwrite(results, "C:/Results/terms.csv")
I am getting the following error when trying to write this to a .csv. file.
Error in fwrite(results, "C:/Results/terms.csv") :
Row 1 of list column is type 'list' - not yet implemented. fwrite() can write list columns containing items which are atomic vectors of type logical, integer, integer64, double, complex and character.

How can I substitute one dictionary's missing contents with content from another dictionary?

So, I'm doing translations for a game, and I have different dictionaries. If a translation doesn't exist in one language, I want to set it to the English translation. Every method I've tried to combine the dictionaries has ended up incredibly inefficient.
Here are some cut down examples
local translation-sr = {
Buttons = {
Confirm = "Потврди";
Submit = "Унеси";
};
Countries = {
Bloxell = "Блоксел";
USA = "Сједињене Америчке Државе";
};
Firearms = {
Manufacturers = {
GenMot = "Џенерални Мотори";
Intratec = "Интратек";
TF = "ТФ Оружје";
};
};
};
local translation-en = {
Buttons = {
Confirm = "Confirm";
Purchase = "Purchase";
Submit = "Submit";
};
Countries = {
Bloxell = "Bloxell";
USA = "United States";
};
Firearms = {
Manufacturers = {
GenMot = "General Motors";
Intratec = "Intratec ";
TF = "TF Armaments";
};
};
Languages = {
Belarusian = "Belarusian";
English = "English";
French = "French";
German = "German";
Italian = "Italian";
Russian = "Russian";
Serbian = "Serbian";
Spanish = "Spanish";
};
};
I guess you want to do something like this
setmetatable(translation_sr.Buttons,{__index=translation_en.Buttons})
for all leaf subtables. You can do this by hand if there are only a few subtables.
I believe you should use a metatable to accomplish what you need.
I assume that you will always index by the English default word. With that true you can do the following.
local function default(t,k)
return k
end
local translation_sr = {
Button = setmetatable({
Confirm = "Потврди",
Submit = "Унеси",
},
{ __index = default }),
Countries = setmetatable({
["Bloxell"] = "Блоксел",
["United States"]= "Сједињене Америчке Државе",
},
{ __index = default }),
Firearms = {
Manufacturers = setmetatable({
["General Motors"] = "Џенерални Мотори",
["Intratec"] = "Интратек",
["TF Armaments"] = "ТФ Оружје",
},
{ __index = default }),
},
}
This function simply returns your key that was not present in the table.
local function default(t,k)
return k
end
With this key being assumed to be the English word you would use as the default the returned value for "Purchase" you would get "Purchase" back from the translation_sr. This method requires no translation_en table

Slice bounds out of range when trying to pass slices as arguments to a recursive function (Go)

I'm trying to pass slices as arguments to a recursive function. Since slices are passed as reference, I believe that the recursive function that I'm passing it to should be able to perform the manipulations without any problem. I'm only using append() and therefore shouldn't have a problem with slices having inadequate capacity right?
package main
import "fmt"
func allPossiblePaths(arrGraph [8][8]bool, src int, dest int) [][]int {
var visited []bool //a slice that marks if visited
var path []int //a slice to store a possible path
var paths [][]int //a slice to store all paths
visited = make([]bool, 8) //set all nodes to unvisited
dfs(arrGraph, src, dest, visited, path, paths)
return paths
}
func dfs(myGraph [8][8]bool, src int, dest int, visited []bool, path []int, paths [][]int) {
//add current node to path
path = append(path, src)
//mark current node as visited
visited[src] = true
//if the current node is the destination
//print the path and return
if src == dest {
//make a copy of path slice
buffer := make([]int, len(path))
copy(buffer, path)
//append the copy of path slice into the slice of paths
paths = append(paths, buffer)
fmt.Println(path) //Just for debugging purpose
return
}
for i := 1; i <= 7; i++ { //loop through all nodes
//if ith node is a neighbour of the current node and it is not visited
if myGraph[src][i] && visited[i] == false {
// call dfs on the current node
dfs(myGraph, i, dest, visited, path, paths)
//mark the current node as unvisited
//so that we can other paths to the final destination
visited[i] = false
//re-slice the slice - get rid of the current node
path = path[:len(path)-1]
}
}
}
func main() {
var myGraph [8][8]bool //the graph
//creating the graph
myGraph[1] = [...]bool{false, false, true, true, false, false, true, false}
myGraph[2] = [...]bool{false, true, false, true, false, true, false, false}
myGraph[3] = [...]bool{false, true, true, false, true, false, true, false}
myGraph[4] = [...]bool{false, false, false, true, false, false, true, false}
myGraph[5] = [...]bool{false, false, true, false, false, false, true, false}
myGraph[6] = [...]bool{false, true, false, true, true, false, false, true}
myGraph[7] = [...]bool{false, false, false, false, false, false, true, false}
fmt.Println(allPossiblePaths(myGraph, 1, 7))
}
OUTPUT:
[1 2 3 4 6 7]
[1 2 7]
[1 7]
[3 2 5 7]
[4 6 7]
panic: runtime error: slice bounds out of range
goroutine 1 [running]:
panic(0x4dc300, 0xc82000a0b0)
/usr/local/opt/go/src/runtime/panic.go:481 +0x3e6
main.dfs(0x0, 0x1000001010000, 0x10001000100, 0x1000100010100, 0x1000001000000, 0x1000000010000, 0x100000101000100, 0x1000000000000, 0x3, 0x7, ...)
/home/nitrous/src/test2b/main.go:52 +0x480
main.dfs(0x0, 0x1000001010000, 0x10001000100, 0x1000100010100, 0x1000001000000, 0x1000000010000, 0x100000101000100, 0x1000000000000, 0x1, 0x7, ...)
/home/nitrous/src/test2b/main.go:45 +0x41f
main.allPossiblePaths(0x0, 0x1000001010000, 0x10001000100, 0x1000100010100, 0x1000001000000, 0x1000000010000, 0x100000101000100, 0x1000000000000, 0x1, 0x7, ...)
/home/nitrous/src/test2b/main.go:12 +0x150
main.main()
/home/nitrous/src/test2b/main.go:71 +0x423
Expected output: (achieved when using global variables instead of passing variables to a function)
[[1 2 3 4 6 7] [1 2 3 6 7] [1 2 5 6 7] [1 3 2 5 6 7] [1 3 4 6 7] [1 3 6 7] [1 6 7]]
Any idea what I'm doing wrong?
The error message is telling exactly what is the issue:
panic: runtime error: slice bounds out of range
Since you are calling the same function iteratively and re-slicing the slice you need to check each time if you reached the slice capacity range, in other terms if the slice pointer is pointing to a valid address (index), otherwise you get the out of range error message.
And since you are making a recursive iteration, by decreasing the path length each time, you have to check if the slice index is within a valid range.
//re-slice the slice - get rid of the current node
if len(path) > 0 {
path = path[:len(path)-1]
}
https://play.golang.org/p/pX2TlAP-bp
I solved it by using a pointer to my slice 'path' as an argument to the recursive function. It works now! Thanks anyway.
package main
import "fmt"
func allPossiblePaths(arrGraph [8][8]bool, src int, dest int) [][]int {
var visited []bool //a slice that marks if visited
var path []int //a slice to store a possible path
var paths [][]int //a slice to store all paths
visited = make([]bool, 8) //set all nodes to unvisited
dfs(arrGraph, src, dest, visited, &path, paths)
return paths
}
func dfs(myGraph [8][8]bool, src int, dest int, visited []bool, path *[]int, paths [][]int) {
//add current node to path
*path = append(*path, src)
//mark current node as visited
visited[src] = true
//if the current node is the destination
//print the path and return
if src == dest {
//make a copy of path slice
buffer := make([]int, len(*path))
copy(buffer, *path)
//append the copy of path slice into the slice of paths
paths = append(paths, buffer)
fmt.Println(*path) //Just for debugging purpose
return
}
for i := 1; i <= 7; i++ { //loop through all nodes
//if ith node is a neighbour of the current node and it is not visited
if myGraph[src][i] && visited[i] == false {
// call dfs on the current node
dfs(myGraph, i, dest, visited, path, paths)
//mark the current node as unvisited
//so that we can other paths to the final destination
visited[i] = false
//re-slice the slice - get rid of the current node
*path = (*path)[:len(*path)-1]
//fmt.Println(path)
}
}
}
func main() {
var myGraph [8][8]bool //the graph
//creating the graph
myGraph[1] = [...]bool{false, false, true, true, false, false, true, false}
myGraph[2] = [...]bool{false, true, false, true, false, true, false, false}
myGraph[3] = [...]bool{false, true, true, false, true, false, true, false}
myGraph[4] = [...]bool{false, false, false, true, false, false, true, false}
myGraph[5] = [...]bool{false, false, true, false, false, false, true, false}
myGraph[6] = [...]bool{false, true, false, true, true, false, false, true}
myGraph[7] = [...]bool{false, false, false, false, false, false, true, false}
fmt.Println(allPossiblePaths(myGraph, 1, 7))
}

Resources