How to create hotkey to check if variable name is valid - macros

As Robert Martin says,
"You should name a variable using the same care with which you name a
first-born child."
SAS's 32 character limit can make this difficult sometimes. It would be nice to know if a given name is valid. Fortunately, SAS provides a function for this: NVALID.
With this, we can construct a script that tells us whether or not our name is valid (NVALID doesn't seem to work directly in a %PUT statement).
data _null_;
name_to_check = 'isThisAValidNameOrIsItTooLong';
isValid = nvalid(name_to_check, 'v7');
if isValid then put "WARNI%str(NG-) Valid name: " name_to_check;
else put "ERR%str(OR-) Invalid name: " name_to_check;
run;
This could be turned into a macro.
%macro CheckValidity(name_to_check);
data _null_;
isValid = nvalid("&name_to_check", 'v7');
if isValid then put "WARNI%str(NG-) Valid name: &name_to_check";
else put "ERR%str(OR-) Invalid name: &name_to_check";
run;
%mend;
%CheckValidity(IsThisAValidName?);
Furthermore, we could bind this macro to a key in the KEYS menu.
submit "%CheckValidity();"
Of course this particular binding is pretty much worthless. That is, unless, there is a way for us to feed the function an input.
Two possibilities come to mind toward this end:
Bind selected text to a macro variable. Then the selected text could be fed into the macro via submit "%CheckValidity(&selected_text);"
Somehow use the KEYS paste keyword.
I've not had any luck with either approach.
In Case 1, it's not clear how to make the Enhanced Editor self-aware. That is, I don't know how I would go about binding selected text to a macro variable.
In Case 2, it's not clear how the paste keyword works, as there isn't really any documentation for it. Whenever I use it, I get
ERROR: You must paste into an input field.
My questions are these:
Is there a way to bind selected text to a macro variable?
Can the paste command be used to paste selected text into the input of
macro?
Is there another way this same task could be achieved?
Sure, this same task can be easily performed with something like AutoHotKey. But can it be done with just SAS?

Related

How do I set this IniRead dynamically?

Been stuck for a while, hoping someone with experience could help me a bit...
Right now I'm reading Ini like this three times but wish to do it dynamically to improve my codes in the long run.
IniRead, Alert_price_low, %TrackerFile%, Item, Alert_price_low
IniRead, Alert_price_high, %TrackerFile%, Item, Alert_price_high
IniRead, Alert_checkbox, %TrackerFile%, Item, Alert_checkbox
I made this function below trying to read it dynamically, but doesn't return anything...
FindIniSettings(TrackerFile, Alert_checkbox)
FindIniSettings(TrackerFile, x){
x := IniRead, %x%, TrackerFile, Item, %x%
return x
}
How my Ini file content looks like:
[Item]
Alert_price_low=777
Alert_price_high=999
Alert_checkbox=1
Thanks!
The problem here is pretty much just with the usage of the new expression syntax.
Seems you've been using only the deprecated legacy syntax, and functions are not apart of that.
So first problem is here
FindIniSettings(TrackerFile, Alert_checkbox)
Here you're not in legacy syntax, so to specify strings you quote them.
FindIniSettings(TrackerFile, "Alert_checkbox")
(And I'm assuming TrackerFile here is a variable that contains some iniFileNameOrPath.ini string)
Also, you're not storing the return value of this function anywhere.
Second problem is here
x := IniRead, %x%, TrackerFile, Item, %x%
Firstly, commands are legacy, they don't return values like that.
You can't use an := operator to get the return value.
They return values only by writing the output to the requested variable, which will be specified in the first parameter of the command.
You specified the output variable to be named whatever x contains. This is no good since you can't possibly know what the output variable is going to be during runtime (without some unnecessary extra tricks).
Also, be quite confusing to name the output to be the same as input key. Though, that would work.
So two problems there, := and the first %x%, and there's still some more to go which is right here:
, TrackerFile,
Commands are legacy, as mentioned above, they exclusively use the legacy syntax in every parameter (unless otherwise specified in the documentation).
So, you're passing in the literal text "TrackerFile", not whatever string should be stored inside the variable named TrackerFile.
In legacy syntax, you refer to the contents of a variable by wrapping it around in %%, as you've been doing before. Maybe you just forgot here.
But really, I'd recommend you try to get used to ditching the legacy syntax. So what you could/should do, is starting off the parameter with a single % followed up by a space. This makes ahk interpret an expression on that parameter, as opposed to using the legacy syntax. In the modern expression syntax you refer to a variable just by typing its name. No stupid %%s needed.
So here's the fixed script you should end up with. I made this example fully legacy syntax free as a demonstration:
TrackerFile := "test.ini"
returnValueOfThisFunction := FindIniSettings(TrackerFile, "Alert_price_low")
MsgBox, % "Yay, the function returned a value for us:`n" returnValueOfThisFunction
return
FindIniSettings(TrackerFile, key)
{
;even specified the string "Item" explicitly as a string
;this is not needed, but it just looks right to me
;I wouldn't want to specify a legacy parameter there
;in the middle of all this
IniRead, output, % TrackerFile, % "Item", % key
MsgBox, % "Now the variable named ""output"" contains the result of the above command (" output ").`nWe can now return it to the caller."
return output
}
So yeah, pretty much just problems understanding legacy syntax vs expression syntax.
You can give a read to a previous answer of mine here about usage of %% vs % .
And here's a good page on the AHK documentation about the scripting language and legacy vs. modern expression.

Stata and global variables

I am working with Stata.
I have a variable called graduate_secondary.
I generate a global variable called outcome, because eventually I will use another outcome.
Now I want to replace the variable graduate if a condition relative to global is met, but I get an error:
My code is:
global outcome "graduate_secondary"
gen graduate=.
replace graduate=1 if graduate_primary==1 & `outcome'==1
But i receive the symbol ==1 invalid name.
Does anyone know why?
Something along those lines might work (using a reproducible example):
sysuse auto, clear
global outcome "rep78"
gen graduate=.
replace graduate=1 if mpg==22 & $outcome==3
(2 real changes made)
In your example, just use
replace graduate=1 if graduate_primary==1 & $outcome==1
would work.
Another solution is to replace global outcome "graduate_secondary" with local outcome "graduate_secondary".
Stata has two types of macros: global, which are accessed with a $, and local, which are accessed with single quotes `' around the name -- as you did in your original code.
You get an error message because a local by the name of outcome has no value assigned to it in your workspace. By design, this will not itself produce an error but instead will the reference to the macro will evaluate as a blank value. You can see the result of evaluating macro references when you type them by using display as follows. You can also see all of the macros in your workspace with macro dir (the locals start with an underscore):
display `outcome'
display $outcome
Here is a blog post about using macros in Stata. In general, I only use global macros when I have to pass something between multiple routines, but this seems like a good use case for locals.

At which lines in my MATLAB code a variable is accessed?

I am defining a variable in the beginning of my source code in MATLAB. Now I would like to know at which lines this variable effects something. In other words, I would like to see all lines in which that variable is read out. This wish does not only include all accesses in the current function, but also possible accesses in sub-functions that use this variable as an input argument. In this way, I can see in a quick way where my change of this variable takes any influence.
Is there any possibility to do so in MATLAB? A graphical marking of the corresponding lines would be nice but a command line output might be even more practical.
You may always use "Find Files" to search for a certain keyword or expression. In my R2012a/Windows version is in Edit > Find Files..., with the keyboard shortcut [CTRL] + [SHIFT] + [F].
The result will be a list of lines where the searched string is found, in all the files found in the specified folder. Please check out the options in the search dialog for more details and flexibility.
Later edit: thanks to #zinjaai, I noticed that #tc88 required that this tool should track the effect of the name of the variable inside the functions/subfunctions. I think this is:
very difficult to achieve. The problem of running trough all the possible values and branching on every possible conditional expression is... well is hard. I think is halting-problem-hard.
in 90% of the case the assumption that the output of a function is influenced by the input is true. But the input and the output are part of the same statement (assigning the result of a function) so looking for where the variable is used as argument should suffice to identify what output variables are affected..
There are perverse cases where functions will alter arguments that are handle-type (because the argument is not copied, but referenced). This side-effect will break the assumption 2, and is one of the main reasons why 1. Outlining the cases when these side effects take place is again, hard, and is better to assume that all of them are modified.
Some other cases are inherently undecidable, because they don't depend on the computer states, but on the state of the "outside world". Example: suppose one calls uigetfile. The function returns a char type when the user selects a file, and a double type for the case when the user chooses not to select a file. Obviously the two cases will be treated differently. How could you know which variables are created/modified before the user deciding?
In conclusion: I think that human intuition, plus the MATLAB Debugger (for run time), and the Find Files (for quick search where a variable is used) and depfun (for quick identification of function dependence) is way cheaper. But I would like to be wrong. :-)

How can I use a simpler link syntax in org-mode?

I'd like to have links with the syntax [[foo bar]] go to files with the name foo bar.org. This would make using org-mode much more like using a personal local wiki.
Is this possible without breaking existing link functionality? I'd also ideally still be able to export to html, etc. with standard org-mode tools.
The best I've been able to do is something like: (setq org-link-abbrev-alist '(("o" . "file:%s.org")))
This lets me use the syntax [[o:foo bar]], but that is more verbose, and looks distractingly ugly inline. For example: The quick brown o:fox jumps over the o:lazy_dog. And [[o:foo bar][foo bar]] is even more verbose to type and edit (though it reads fine in org mode).
I don't have a ready made solution and am not a programmer, but this part is self-documenting in org.el, you can write a dedicated link search function. I cite:
"List of functions to execute a file search triggered by a link.
Functions added to this hook must accept a single argument, the search
string that was part of the file link, the part after the double
colon. The function must first check if it would like to handle this
search, for example by checking the `major-mode' or the file
extension. If it decides not to handle this search, it should just
return nil to give other functions a chance. If it does handle the
search, it must return a non-nil value to keep other functions from
trying.
Each function can access the current prefix argument through the
variable `current-prefix-arg'. Note that a single prefix is used to
force opening a link in Emacs, so it may be good to only use a numeric
or double prefix to guide the search function.
In case this is needed, a function in this hook can also restore the
window configuration before `org-open-at-point' was called using:
(set-window-configuration org-window-config-before-follow-link)")
See also Hyperlinks :: Custom Searches # gnu.org

Mutt macros: How to set and then use a variable in one macro?

I'm trying to write a small mutt macro that will set a variable, and then re-use that variable in the same macro.
What I'm really trying to do is compose a message and sub in the To: address (which later I will populate dynamically).
This is in my .muttrc
set my_to = "bobby#test.com"
macro index E "<enter-command> set my_to = barry#test.com<enter>mn\$my_to"
My problem is the variable my_to never changes from bobby#... to barry#...
I believe it has to do with the $ being interpreted during the config parsing, and the manual recommends using an escape . But if I do that, only the literal "$my_to" shows up.
What am I doing wrong?
update:
I still haven't been able to set/get variables as above, but I'd missed an obvious Mutt solution to my problem ESC-e will create a new email based on the existing. Similar to the edit-as-new in Thunderbird.