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.
Related
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.
I have searched around quite a bit and have failed to find an answer. In AutoHotKey, I am not sure the difference when a single percent is used near the beginning of a line, and when a variable is enclosed between two percent signs. I usually use trial and error to find when I use one or the other, I am hoping someone could shed some light on what the difference is or explain what it is actually doing.
Here are some examples of this in action.
Example 1: I noticed if you have multiple variables along with text, scripts tend to go with the preceding percent. Such as:
some_val := Clipboard
loop 5
msgbox % "Index:" . A_Index . ", variable:" . some_val
Example 2: I often see this as well, and sometimes it appears it must be used. Is this true?
some_variable := "test text to send"
Send, %some_variable%
Wrapping in double percent signs is legacy AHK and basically there is no need to ever use it anymore. Only reason to wrap in double % would be being stuck behind in the old times, or maybe one could argue it also being more convenient, or something, to write in some cases, but I'm not buying it.
The legacy syntax is replaced by expression syntax.
The expression syntax is closer to how many other languages behave. AHK legacy syntax really is a mess.
All legacy commands (MsgBox for example) use the old legacy syntax on each parameter (unless otherwise specified).
If you specify a % followed up by a space at the start of the parameter, you're forcing AHK to evaluate an expression on that parameter instead of reading it as a legacy text parameter.
Example:
MsgBox, 5+5
We're using a legacy command, we're not starting the parameter off with a % and a space, so we're using the legacy syntax. The MsgBox is going to print the literal text 5+5 instead of 10.
MsgBox, % 5+5
Again, legacy command, but now we're forcing AHK to evaluate an expression here, 5+5.
The result of expression's evaluation is going to be passed onto the MsgBox command and the MsgBox is going to print 10.
If we wanted to MsgBox to print the literal text 5+5, and use the expression syntax to do it, we'd do MsgBox, % "5+5".
Quotation marks in expression syntax mean we're specifying a string.
Well then there's the problem of knowing when you're in expression syntax, and when you're in the legacy syntax.
By default, you're basically always in an expression.
You leave it by for example using a command or = to assign.
If the difference between a command and a function isn't clear to you, here's an example:
Command, % 7+3, % MyCoolArray[4], % SomeOtherNiceFunction(), % false
Function(7+3, MyCoolArray[4], SomeOtherNiceFunction(), false)
In the command we specified a % followed up by a space to evaluate the expressions on each parameter, and in the function, we didn't have to do that since we're already in an expression.
And if you're not clear on the difference between = and :=,
= is legacy and deprecated, it assigns plain text to a variable
:= assigns the result of an expression to a variable.
So that's what I could write from on top of my head.
If you had some more complex examples, I could try showing on them. Maybe convert some code you may have over to expression syntax, make it 100% free of legacy syntax.
And here's a good page on the documentation you should give a read:
https://www.autohotkey.com/docs/Language.htm
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. :-)
In functions, the MATLAB editor displays a warning when a defined variable is not subsequently used before the function ends or before the variable is overwritten. This obviously tells me that the editor has a way of searching for occurrences of given variables in the code.
Can I do this manually? The Find function is obviously limited here, since it only searches the body of text in the editor window (including comments) for matches of the search string. This makes it very inconvenient when searching for variables with short names (such as the by me commonly used "a").
I cannot tell you about previous versions of the built-in editor, but at least from 2011b, the righthand side margin of the editor creates color tags for:
Warnings, tagged in orange
Errors, tagged in red color
Variable/function occurrence: tagged in dark gray, for selected text.
The third of them is what you are looking for. You just have to double click on a variable name or a function name to select it and your Matlab editor will automatically highlight the rest of the occurrences of the very same identifier, tagging them on the righthand side ribbon with the grey mark I mentioned above.
You can limit the search to match case and whole word, which will give you only this variable, either in comment or not.
BTW, you shouldn't use variable names like a,b,c. It makes the code harder to read and to maintain. Even if you have dummy variables like in loops and temporary ones, use for example indexFiles, or tempValue
You can also use some regular expression to match the variable names in your code.
If you'll assume that any variable name is separated from the rest of the code by any of linefeed tab space ! " # $ % & ' ( ) * + , - . / : ; < = > ? [ \ ] ^ `` { | } ~, then you can create a small function that takes the function name as input and outputs the lines in which the variable name is mentioned. However, this approach doesn't separate function names and variable names, but you should have some standard for separating them anyway. I use this approach to change variable names of my MATLAB code (but my code for that is written in awk, not in MATLAB).
And I wonder what you'll do when you have a complex program with thousands or tens of thousands of lines of code and your variables are named a, b, c and so on...
I am trying to translate a .bat file to PowerShell and having trouble with understanding what a few snippets of code is doing:
set MY_VARIABLE = "some\path\here"
"!MY_VARIABLE:\=/!"
What is line 2 above doing? Specially, I dont understand what the :\=/ is doing since I have seen the variable else where in the code being referenced like !MY_VARIABLE!.
The other point of confusion is the below code.
set SOME_VARIABLE=!SOME_ARGUMENTS:\=\\!
set SOME_VARIABLE=!SOME_ARGUMENTS:"=\"!
Also, can you tell me what is going on in lines 3 and 4 above as well?
What would the below variables translate into PowerShell as well?
set TN0=%~n0
set TDP0=%~dp0
set STAR=%*
Any help on this is much appreciated. Thanks.
The !var:find=replace! is string substitution for a variable that is delay-expanded.
http://www.robvanderwoude.com/ntset.php#StrSubst
When you use ! instead of % for a variable, you want DOS to do the variable replacement at execution time (which is probably what you think it does with %, but it doesn't). With %, the variable is substituted at the point that the command is parsed (before it's run) -- so if the variable changes as part of the command, it won't be seen. I think some switch to using ! all of the time, because it gives "normal" behavior.
You can read more about delayed expansion here
http://www.robvanderwoude.com/ntset.php#DelayedExpansion
The first two set variableName= commands use modifiers to expand on the name of the batch file, represented as %0.
%~n0 expands it to a file name, and
%~dp0 expands it to include a drive letter and path.
The final one, %*, represents all arguments passed to the batch file.
Additional information can be found in answers here or here.
Exclamation points (!) i n DOS batch files reference the intermediate value, useful if you are in a for-loop. If you were to use a % instead (in a loop), it would return the same value over and over.
Lines 3 and 4 are setting "SOME_VARIABLE" to the intermediate value of "SOME_ARGUMENTS:\=\" and SOME_ARGUMENTS:"=\", respectively. Again, I'm guessing that these lines are from a loop.
As for the variable assignments, Powershell variable assignments work like this:
$myVariable = "my string"
~dp0 (in DOS batch) translates into the path (with drive letter) of the current bat file. You can get that in Powershell by doing a "get-location".
Why someone would need to set a variable for STAR(*) is beyond me, so I'm assuming there was some encoding issue or other reason that they couldn't just use an asterisk.
~n0 I'm not sure about; maybe someone else knows what that one is.