Insert randomly generated strings as nested table - string

These days I am working on a small example/project of myself. What I am doing is creating n set of random strings of variable lengths. Here is what I want to obtain:
Two names of length from 3 to 25 characters.
A message ranging from 40 to 300 characters.
In my C example, I create a struct and kept inserting into this table as list. In my LUA example, I want a nested table like this:
tTableName = {
[1] = {
"To" = "Name 1",
"From" = "Name 2",
"Message" = "The first message generated"
}
[2] = {
"To" = "Name 3",
"From" = "Name 4",
"Message" = "The second message generated"
}
}
So, basically my structure goes like this:
struct PM {
char *sTo, *sFrom, *sMessage;
} PMs;
I want a similar structure/table in LUA so that I can use a table.insert method. I currently am doing it like this:
tTempTable = {
"To" = "Name 1",
"From" = "Name 2",
"Message" = "The first message generated"
}
table.insert( tTableName, tTempTable )
but I am thinking it as a wastage of a lot of processing time. Currently I am only generating a sample of 30 such PMs; but later I shall be generating *1000*s of them. Please advice.

i think you're falling into the trap of pre-maturely optimizing your code before you even know where a bottleneck is... but the following document contains a bunch of optimization info about lua in general, including tables. The guy who wrote it is one of the head architects for Lua.
http://www.lua.org/gems/sample.pdf

First of all, this isn't really a question. I'll guess you're asking if there's a more efficient way to do this? In general you want to write for clarity and don't sweat small performance gains at all unless you run into issues. But here are some notes about your code, including a few notes about efficiency:
The table constructor posted isn't valid. Either of the following fixes would work:
tTempTable = {
["To"] = "Name 1",
["From"] = "Name 2",
["Message"] = "The first message generated"
}
tTempTable = {
To = "Name 1",
From = "Name 2",
Message = "The first message generated"
}
You don't need to specify numerical indexes when constructing an array. You can replace this:
tTableName = {
[1] = { To = "Name 1", From = "Name 2", Message = "The first message generated" },
[2] = { To = "Name 3", From = "Name 4", Message = "The second message generated" },
}
With this, which means the exact same thing but is more succinct:
tTableName = {
{ To = "Name 1", From = "Name 2", Message = "The first message generated" },
{ To = "Name 3", From = "Name 4", Message = "The second message generated" },
}
This also happens to be more efficient; Lua can preallocate the array size it needs, whereas it's not smart enough to do that with the previous constructor.
As for a better way to write this in general, it's hard to say without knowing more about your application. If you're just trying to test some PM code, why not just generate the strings you need on the fly at the point of use? Why preallocate them into a table at all?
If you must preallocate, you don't have to store them as structured data. You could just have three arrays: ToNames, FromNames, Messages, then select from them at random at the point of use:
local to = ToNames [ math.random(1,#ToNames ) ]
local from = FromNames[ math.random(1,#FromNames) ]
local message = Messages [ math.random(1,#Messages ) ]
TestPM(to, from, message)

Related

Groovy hashmap and looping

I need to store key value pairs in groovy like for ex, store, address
key: store abc val: 123 street
key: store xyz val: north street
How can I achieve this? I tried below
mapAddress = [store:"abc", addr:"123 street"]
mapAddress.append
mapAddress = [store:"xyz", addr:"north street"]
mapAddress.append
But it retains only the last record store: xyz.
And how can I loop only the unique stores using for loop? Thanks in advance for your help.
It seems you need to create a list of maps.
See https://groovy-lang.org/groovy-dev-kit.html#_map_literals
In your example you just reassign your map with the new value
Do you really need to store them in the format you've showed?
I recommend storing them like so:
def stores = [:] // define your variable here
stores << ["abc": "123 street"] // first entry
stores << ["xyz": "north street"] // second entry
Or if you need to have more data per each store, then you can store them in a map of maps:
def stores = [:]
stores << ["abc": [address: "123 street", "some other property": "some value"]]
stores << ["xyz": [address: "north street", "some other property": "some other value"]]
Maps can only hold unique keys, so if you add a new entry with the same key as one that's already in the map, the previous entry will be replaced.
In both of the cases you can simply loop through them via
stores.each{ println(it) }.
If you plan to have multiple stores that will have the same key, you could store them in a map of lists, for example:
def stores = [:]
stores << ["abc": [[address: "123 street", "some other property": "some value"], [address: "456 street", "some other property": "some value"]]]
stores << ["xyz": [[address: "north street", "some other property": "some other value"]]]
stores.each {
println it.value.first()
}
But, at this point you're probably better off using classes to define your data.

How to multi line string in terraform

I am trying below from an example
resource "google_logging_metric" "my_metric" {
description = "Check for logs of some cron job\t"
name = "mycj-logs"
filter = "resource.type=\"k8s_container\" AND resource.labels.cluster_name=\"${local.k8s_name}\" AND resource.labels.namespace_name=\"workable\" AND resource.labels.container_name=\"mycontainer-cronjob\" \nresource.labels.pod_name:\"my-pod\""
project = "${data.terraform_remote_state.gke_k8s_env.project_id}"
metric_descriptor {
metric_kind = "DELTA"
value_type = "INT64"
}
}
Is there a way to make the filter field multiline?
A quick search in Google sends you to the documentation: https://www.terraform.io/docs/language/expressions/strings.html#heredoc-strings
You just need to write something like
<<EOT
hello
world
EOT
If it's a matter of formatting the output, this answer covers it.
If you want to make your code more readable, i.e. split the long string over a few lines but keep it as a single line in the output, using the join() function might be worth considering:
resource "google_logging_metric" "my_metric" {
description = "Check for logs of some cron job\t"
name = "mycj-logs"
project = "${data.terraform_remote_state.gke_k8s_env.project_id}"
filter = join(" AND ",
[
"resource.type=\"k8s_container\"",
"resource.labels.cluster_name=\"${local.k8s_name}\"",
"resource.labels.namespace_name=\"workable\"",
"resource.labels.container_name=\"mycontainer-cronjob\"",
"resource.labels.pod_name:\"my-pod\""
]
)
metric_descriptor {
metric_kind = "DELTA"
value_type = "INT64"
}
}
Note that setting out the code this way shows that in the OP there is a missing AND in the filter expression.
Because the original expression is one long line, this is very hard to see and slow to read/maintain-- and mistakes are easy to make.

I have duplicate code - is there a way to extend/reuse terraform modules?

I've copied and pasted large blocks of terraform, usually a sign to me that I'm missing some language feature that could neaten things up (relatively new to tf).
Example:
module "my_module"
{
source = "../something"
some_var = "a value"
another_var = "another value"
wow_more_var = "wow"
a_module_specific_var = "1"
}
module "another_module"
{
source = "../something"
some_var = "a value"
another_var = "another value"
wow_more_var = "wow"
a_module_specific_var = "2"
}
As you can see - the only way in which these module declarations differ are by the a_module_specific_var (at the end). Which language feature am I missing here that would allow me to abstract the common parts away? If this was in Node which is my usual arena, I'd pull this out into a JS function and just pass 1 or 2 as a parameter.
You can use count or for_each with modules, documented here. I would create a list containing those module specific vars, and then use for_each, like so:
module "my_module"
{
for_each = toset( ["1", "2"] )
source = "../something"
some_var = "a value"
another_var = "another value"
wow_more_var = "wow"
a_module_specific_var = each.key
}

Most elegant way to get two properties at the same time

Suppose you have hierarchical data and want to obtain the merged value of separate properties, what is the most elegant, or groovy, way to do so?
The following example holds information about failed and skipped tests. Of course, it does make sense, that these values are separated - but for the use case of retrieving a list of all tests, that did not run successfully, I came across two possible solutions, which both of them did not satisfy me.
def junitResultList = [
[
name: "Testsuite A",
children: [
failedTests: ["Test 1", "Test 2"],
skippedTests: []
]
],
[
name: "Testsuite B",
children: [
failedTests: ["CursorTest"],
skippedTests: ["ClickTest", "DragNDropTest"]
]
]
]
To be more specific, I want the value to be ["Test 1", "Test 2", "CursorTest", "ClickTest", "DragNDropTest"].
The first approach was simply to perform an addition of the spread test lists:
(junitResultList*.children*.failedTests +
junitResultList*.children*.skippedTests).flatten()
While this works, it appeared to me that specifying the path to these properties twice seems not to be the most groovy way, so I came up with this horrible but somehow appealing disasterpiece:
(junitResultList*.children*.findAll {
['skippedTests', 'failedTests'].contains(it.key)
})*.values().flatten()
You can simplify your initial expression to something like this:
junitResultList.children.collect { it.failedTests + it.skippedTests }.flatten()
or
junitResultList.children.collect { [it.failedTests, it.skippedTests] }.flatten()
You can just do as below:
//Define the keys to find
def requiredKeys = ['failedTests', 'skippedTests']
println requiredKeys.collect{ junitResultList.children."$it"}.flatten()
You can quickly try the same online demo
You can get the subMap()s and then the values() on that:
junitResultList*.children*.subMap(["failedTests","skippedTests"])*.values().flatten()

SugarCRM - very SIMPLE Logic Hook executed with delay

i have very, very simple logic hook- I am still learning and I am confused at the start.
I turn on Developer mode.
I already have field "FIRST_NAME" in Contacts module.
I Created my field "MY_FIELD" also in COntacts module.
In logic_hooks.php file I added
$hook_array['before_save'] = Array();
$hook_array['before_save'][] = Array(1, 'Value from one field to another', 'custom/modules/Contacts/my.php', 'User_hook','copy');
In my.php file I added
class User_hook {
function copy(&$bean, $event, $arguments)
{
$bean->my_field_c = $bean->fetched_row['first_name']. " - additional text";
}
}
So when I entered in First_Name value "First" I am getting in My field value "-additional text" but I should get "First- additional text."
If I go to Edit View and enter in First name field "Second" I am getting in My field value "First - additional text" but I should get "Second - additional text".
If I enetein Edit View "Third" I am getting in My field "Third - addiitional text" but I should get "Third - additional text".
So obviously my logic hook is executed with delay in one iteration- why and how to change it? This is my first hook so I am not so experience. Thanks for help
$bean->fetched_row['first_name'] will return the value of the field BEFORE you change it. You'd use this to see what the value of first_name was before the user changed it on the form.
Try using
class User_hook {
function copy(&$bean, $event, $arguments)
{
$bean->my_field_c = $bean->first_name. " - additional text";
}
}

Resources