TIBASIC: How can one prompt a multivariable expression? - calculator

On the Ti-84 and Ti-89, I know that one can use "Define" to define a function with multiple variables. However, is there a way to use "Prompt" or something of the sort to define a function?
Suppose we have a very simple program that evaluates an expression (only an example):
Prompt a,b,c
Disp a^5-sqrt(c)/b
Instead of having to manually go into the Program Editor every single time to change the expression, how can we automatically Prompt the user to Define a function such as eq(a,b,c)=a^5-sqrt(c)/b?

Yes you can! Use y-variables.
Functions are stored as y-variables on the TI-84, and these variables can be accessed by going to the VARS>Y-VARS>Function... menu. Then you can prompt the user for the equation with the y-variable being the input, like this:
Prompt Y1
Keep in mind that this is a string, meaning you need quotation marks at the beginning and end of your function when putting it in as the user. This can be cumbersome, and can be avoided by using Input instead, and storing it into a String variable (found in VARS>String...) first then to a y-variable.
Input "f(a,b,c): ",Str1
Str1→Y1

Related

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.

combine compute, loop and concat

I would like to run the following syntax on lots of variables. Thus, I'd like to loop over a bunch of variables.
The syntax is the following:
compute v3a_mit = v3a.
recode v3a_mit
(-9998=2) (sysmis=9).
exe.
In this case, however, the syntax only concerns the variable "v3a".I have some other variables (v3b, v3c, v3d...) for which I would like to execute this syntax.
So, the loop should look like this.
DO REPEAT X=v3a to v3z
compute concat(X,'_mit') = X.
recode concat(X,'_mit')
(-9998=2) (sysmis=9).
exe.
END REPEAT.
So, within the loop, new variables shall be created which get a new name depending on the variable which is executed in the loop. The "SHIFT VALUES VARIABLE" command would be ideal (with shift=0) but this command cannot be used within a loop. Unfortunately "compute concat(X,'_mit')" does not work either.
CONCAT is a function for manipulating the values of string variables. So you can't use it for defining a variable name.
However you can make use of the !CONCAT function inside of a SPSS macro.
You can use the following macro to recode a set of variables.
DEFINE !recodeVars (vars = !CMDEND)
* for every variable in the 'vars' list do the RECODE INTO command.
!DO !var !IN (!vars)
RECODE !var (-9998=2) (sysmis=9) INTO !CONCAT(!var, '_mit').
!DOEND
!ENDDEFINE.
* macro call.
!recodeVars vars = v3a v3b v3c v3d.
Here, I used the RECODE INTO command, instead of one COMPUTE and a following RECODE command. But of course the principle of how to use the !CONCAT command would be the same for the COMPUTE operation.
However you can't call the macro in way like this !recodeVars vars = v3a TO v3z. In that case the macro would try perform the RECODE for the variables "v3a", "TO" and "v3z". You have to call this macro with the whole list of variables you want to recode.
This might be a lot of typing. As an easy way to avoid the typing, you could produce a SPSS command via the SPSS Menu (for example Analize -> Descreptive Statistics -> Frequencies) Then select the variables you want to recode (select the first variable, hold the SHIFT key and select the last variable) and then press the paste button. The Frequency command with the list of variables will be pasted to your syntax. You can now copy paste the variable list to your macro call.
If you have the Python integration plugin installed you could also use this small python block to retrieve the varlist between two variables.
BEGIN PROGRAM.
import spss,spssaux
variables = 'v3a to v3z' #Specify variables
varlist = spssaux.VariableDict().expand(variables)
spss.SetMacroValue('!varlist', ' '.join(varlist))
END PROGRAM.
This creates a macro named "!varlist" which expands to the list of variables when called.
You can now call the "!recodeVars" macro the following way: !recodeVars vars = !varlist.
If you don't have the python plugin installed (and don't want to use manual typing or copy and pasting) you can get the full variable list with the use of the "!DefList" macro from Raynald's SPSS Tools.
By the way, you can also make use of a macro for the SHIFT VALUES command.

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 to use assignin for multiple variables?

I have a nested function which calls a script basicially containing some definitions of constants and strings. I need to pass these variables to the base workspace. I know I could define them as global which is supposed to be not the best solution, is it?
The conventional way, using the output arguments of the function seems to be too complicated in my case. (It's actually just a one time call, so I don't want to blow up my code) So I thought about using assignin and who but neither it does seem to work for cell arrays nor for comma separated lists. Probably I'm just missing some syntax refinements.
function myFunction()
myScriptWithDefinitions;
% who returns a cell array with all variables from my script
temp = who;
% now I try to assign these variables to my base workspace
% these are my attempts, none of them working
assignin('base',who);
assignin('base',temp{:});
assignin('base',{temp{:}});
...
end
I'm aware that I acually need to pass both, a list of names and a list of values.
any further ideas?
Edit: something like
assignin('base',{'A','B'},{2,5})
% or
assignin('base',{'A',2},{'B',5})
does not work, so I guess assignin in general is not an option.
with assignin you can only assign-in 1 variable at once.
With "who" you get a cell-array of strings, that contains the names of the variables. Now if you have this list:
myVarList=who;
you can loop over and assign the variables to the workspace:
myVarList=who;
for indVar = 1:length(myVarList)
assignin('base',myVarList{indVar},eval(myVarList{indVar}))
end
Note: this is an eval-solution... if someone knows a quick replacement for that, please let me know :)

How to get input from user in function

I want to ask about function M-file in MATLAB: if I want input from the user, how do I do that?
Can I write the input directly in the function M-file?
Or do I have to write an input statement in a script file and return to the function file to write another statement?
As Luis mentioned, the input function (documentation) prompts the user and then receives input. As far as I know, it will work fine whether in a function or in a script. If you find that it doesn't, post the code so folks can take a look at it.
input will treat what the user types as if you had typed it at a matlab command line. For example, if your code says
count=input('Enter a count')
and the user enters 3*5, the value of count will be 15. To get exactly "3*5", use input('Prompt','s') instead.