How to put BEGIN PROGRAM-END PROGRAM structure inside a macro? - spss

I wrote a Python script for SPSS that I need to use a couple of times in a syntax. Thus, I would like to avoid repeating BEGIN PROGRAM-END PROGRAM. structure more than once. I decided to place it within a macro but sadly it doesn't work even though there are no bugs neither in a macro nor a script. Code:
define mac_export (!positional !tokens(1))
OUTPUT EXPORT
/CONTENTS EXPORT = visible LAYERS = printsetting
MODELVIEWS = printsetting
/XLSX DOCUMENTFILE = "tables1.xlsx"
OPERATION = createsheet
sheet = !quote(!unquote(!1))
LOCATION = lastcolumn NOTESCAPTIONS = no
!enddefine.
define clean ()
begin program.
import spss, SpssClient
SpssClient.StartClient()
OutputDoc = SpssClient.GetDesignatedOutputDoc()
OutputDoc.SelectAllText()
OutputDoc.Delete()
OutputDoc.SelectAllLogs()
OutputDoc.Delete()
OutputDoc.SelectAllNotes()
OutputDoc.Delete()
OutputDoc.SelectAllTitles()
OutputDoc.Delete()
OutputDoc.SelectAllWarnings()
OutputDoc.Delete()
end program.
!enddefine.
*** REPORT.
ctables
/table
(att1 + att2 + att3)
[s][mean f1.1]
/slabels position = column visible = no
/titles title = "Attitudes".
clean.
mac_export "Attitudes".
ctables
/mrsets countduplicates = no
/table gender > $STATEMENTS [colpct.responses.count f40.0] by age
/slabels position = column
/titles title = "Statements".
clean.
mac_export "Statements".
* AND OTHER TABLES...
When I run this code SPSS stops at the first call of clean macro. What can I do to simplify my code and avoid repeating BEGIN PROGRAM structure?

First of all it's explicitly said at the bottom of the DEFINE-!ENDDEFINE. description that scripts' codes cannot be put inside a macro: https://www.ibm.com/support/knowledgecenter/pl/SSLVMB_25.0.0/statistics_reference_project_ddita/spss/base/syn_define_overview.html. Second, you can use SCRIPT command to run a script from an external file. You can also place this command inside a macro. Concerning BEGIN PROGRAM structure there is an interesting workaround:
First, you have to copy Python code with BEGIN PROGRAM-END PROGRAM clause to a different, new syntax file. Let's assume this file is named Python_cleaning.sps.
Second, you need to replace BEGIN PROGRAM structure inside your clean macro with a simple INSERT line. This command allows to run an external syntax from another. Code:
define clean ()
insert file = "C:\path\Python_cleaning.sps"
syntax = interactive error = stop cd = no encoding = "utf8".
!enddefine.
Finally, you can run Python script in your syntax using clean macro.

Related

Replacing strings using str_replace_all with excel file

I'm trying to replace a very long list of strings (200+) with the str_replace all function. I would like to be able to read in an excel file which has the R code for the replacements as the list of replacements to so that I don't have 200+ lines in my script dedicated to naming strings, but can't seem to get it to work.
What I have:
`REPLACEMENTS = c(
'\\bAFFL\\b'='AFFILIATE',
'\\bACCY\\b'='ACCOUNTANCY',
'\\bACTG\\b'='ACCOUNTING',
'\\bACQUIS\\b'='ACQUISITION',
'\\bADMNR\\b'='ADMINISTRATOR',
)
df$tobereplaced = str_replace_all(df$tobereplaced, REPLACEMENTS)`
What I want:
`REPLACEMENTS = excelfile$replacements
df$tobereplaced = str_replace_all(df$tobereplaced, REPLACEMENTS)`
When I try this I get the error:
Error in fix_replacement(replacement) :
argument "replacement" is missing, with no default

syntax highlighting autocmd is not working in neovim

I am new to vim and esp. in lua scripting. I want to create an autocmd such that all the jinja files will get yaml syntax highlighting.
local a = vim.api
a.nvim_create_autocmd( { "BufNewFile", "BufRead" }, {
pattern = { "*.j2" },
command = [[ lua(syntax = "html")]],
})
but this is not working. Could someone point the obvious.
DD.
I give you an Example on how i do Lua Syntaxhighlightning for my own *.luado files.
Before i have copied ( as super Q User: root.root ) /usr/share/nvim/runtime/syntax/lua.vim to /usr/share/nvim/runtime/syntax/luado.vim.
So i can change it independently from original lua.vim.
It is not necessary to change luado.vim for the Example below.
~/.config/nvim/lua/init.lua required by ~/.config/nvim/init.vim
( At First and off course before: syntax on )
--[[ Automatic Execution of Lua Oneliner if file extension *.luado
With Lua Syntaxhighlighting ]]
vim.api.nvim_create_autocmd({"BufEnter"},{
pattern = {"*.luado"},
command = "luado vim.api.nvim_command('setfiletype luado') load(line, 'koys_nvim_auto_luado')()"
})
Triggers at "BufEnter" and shows that "BufNewFile", "BufRead" not really needed.
( Every time before it is shown from Buffer ;-) )
Impression
Now lets change to next Buffer with :bn to test3.luado
And back with :bp to test2.luado (Output of set)
(test2.luado will be shown after ENTER/RETURN)

In Lua, using a boolean variable from another script in the same project ends up with nill value error

This code is for a modding engine, Unitale base on Unity Written in Lua
So I am trying to use a Boolean Variable in my script poseur.lua, so when certain conditions are met so I can pass it to the other script encounter.lua, where a engine Predefined functions is being uses to make actions happens base on the occurring moment.
I tried to read the engine documentation multiple times, follow the exact syntax of Lua's fonction like GetVar(), SetVar(), SetGobal(),GetGlobal().
Searching and google thing about the Language, post on the subreddit and Game Exchange and tried to solve it by myself for hours... I just can't do it and I can't understand why ?
I will show parts of my codes for each.
poseur:
-- A basic monster script skeleton you can copy and modify for your own creations.
comments = {"Smells like the work\rof an enemy stand.",
"Nidhogg_Warrior is posing like his\rlife depends on it.",
"Nidhogg_Warrior's limbs shouldn't\rbe moving in this way."}
commands = {"GREET", "JUMP", "FLIRT", "CRINGE"}
EndDialougue = {" ! ! !","ouiii"}
sprite = "poseur" --Always PNG. Extension is added automatically.
name = "Nidhogg_Warrior"
hp = 99
atk = 1
def = 1
check = "The Nidhogg_Warrior is\rsearching for the Nidhogg"
dialogbubble = "rightlarge" -- See documentation for what bubbles you have available.
canspare = false
cancheck = true
GreetCounter = 5
Berserk = false
encounter:
-- A basic encounter script skeleton you can copy and modify for your own creations.
encountertext = "Nidhogg_Warrior is\rrunning frantically"
nextwaves = {"bullettest_chaserorb"}
wavetimer = 5.0
arenasize = {155, 130}
music = "musAncientGuardian"
enemies = {"poseur"}
require("Monsters.poseur")
enemypositions = {{0, 0}}
-- A custom list with attacks to choose from.
-- Actual selection happens in EnemyDialogueEnding().
-- Put here in case you want to use it.
possible_attacks = {"bullettest_bouncy", "bullettest_chaserorb", "bullettest_touhou"}
function EncounterStarting()
-- If you want to change the game state immediately, this is the place.
Player.lv = 20
Player.hp = 99
Player.name = "Teemies"
poseur.GetVar("Berserk")
end
Thank you for reading.
The answer to my problem was to use SetGobal(), GetGobal().
For some reasons my previous attempt to simply use SetGobal()Resulted in nil value despite writing it like that SetGobal("Berserk",true) gave me a nill value error, as soon as I launch the game.
But I still used them wrong. First I needed to put it SetGobal() at the end of the condition instead of at the start of the the poseur.lua script because the change of value... for some reasons was being overwritten by it first installment.
And to test the variable in the function in my encounter.lua, I needed to write it like that
function EnemyDialogueStarting()
-- Good location for setting monster dialogue depending on how the battle is going.
if GetGlobal("Jimmies") == true then
TEEEST()
end
end
Also any tips an suggestions are still welcome !
Well firstly, in lua simple values like bool and number are copied on assignment:
global={}
a=2
global.a=a--this is a copy
a=4--this change won't affect value in table
print(global.a)--2
print(a)--4
Secondly,
SetGobal and the other mentioned functions are not part of lua language, they must be related to your engine. Probably, they use word 'Global' not as lua 'global' but in a sense defined by engine.
Depending on the engine specifics these functions might as well do a deep copy of any variable they're given (or might as well not work with complicated objects).

lua, combining strings with variables inside tables when imported from file

I am having a problem with variables inside tables. this is essential since I use tables as configuration for my program.
so I have tested the following code that works:
> x = "X"
> t = {["ref"]="table with value: "..x}
> print(t["ref"])
table with value: X
> x = "Y"
> t = {["ref"]="table with value: "..x}
> print(t["ref"])
table with value: Y
it however doesn't work without the second > t = ["ref"]="table with value: "..x
now I went to implement this into my main program witch consists of two files, one witch returns the configuration table. And one file with all the functions and stuff. it looks as following
FILE A (main.lua):
testString = "test1"
print(testString)
local CONFIG = require'config'
print(CONIFG[1].test)
testString = "test2"
print(testString)
local CONFIG = require'config'
print(CONIFG[1].test)
FILE B (config.lua):
local CONFIG = {
{["test"]=[[this is a test: ]]..testString}
}
return CONFIG
now when i run file A (a.k.a. main.lua) i get the following output:
test1
this is a test: test1
test2
this is a test: test1
i can't figure out what i am doing wrong here.. i thought it had something to do with that it was a single string so i made testString a table but that gave me the same result...
(that title really seems scary.. sorry)
require, by design, caches the return value. So if you call require with the same string, it will not execute the script again. It will simply return the previously returned value.
require is for loading modules. And modules should not change their return values based on other global state.
The function you're probably looking for is dofile. This will always load and execute the file (but it has none of the path searching properties of require). Alternatively, you can use loadfile to load the file as a function, then execute that function to regenerate the table whenever you want.
Also:
I am having a problem with variables inside tables.
There are no "variables inside tables". Or at least not the way you mean. Expecting a change to a variable to affect some other value is like expecting this:
a = 5
b = a + 5
a = 10
assert(b == 15, "This will never be true.")
When an expression (whether a + 5 or "table with value: " .. x) is evaluated, it results in a value. The resulting value is in no way dependent on any value or variable from the expression that generated it.
That's why you had to regenerate the value; because values don't change just because some variable changes.

Lua create multiple closure instances

I have some lua code in a file. I want to create multiple closure instances of this code, each with a different _ENV upvalue. I can use luaL_loadfile to load the file and set the first upvalue, N times with different tables, to create N instances. But wouldn't this load and compile the file N times?
The lua equivalent of what i want to do is the following, except without the loadfile
func_list = {}
for i = 1, 10 do
local new_env = {hello=i, print=print}
func_list[i] = loadfile("Code.lua", "t", new_env)
end
for i = 1, 10 do
func_list[i]()
end
------ Code.lua ------
print(hello*hello)
is there a better way to do this?
Whenever you load a string/file in Lua, what you get in return is a function to call to actually run the file. What load does for you is just some additional processing to set the _ENV.
However, nothing prevents you from setting _ENV yourself. You could do it with something like this:
-- Code.lua --
_ENV = ...
print(hello * hello)
Then, you could load/compile the file just once, and use multiple instances as such:
local code = loadfile("Code.lua")
env_list = {}
for i = 1, 10 do
local new_env = {hello=i, print=print}
code(new_env)
env_list[i] = new_env
end
If you do not want the user to write _ENV = ... in every file, you could instead load the file into a string, prepend the line yourself and use load to compile the source. But this would not work on compiled files.
Use the IO libraries to load the file into a string, and then call loadstring on it.
Alternatively, just get one chunk and then change it's env prior to executing it

Resources