I'm trying to make a basic while loop to get back into the swing of things with matlab. All I'm trying to do is create a prompt to ask the user if today is their birthday and if they say yes it'll wish them happy birthday and if they say no it'll say "that's too bad". I can make the prompts appear but what I want to do is unless the user inputs 'yes' or 'no' they will continually be asked if today is their birthday. My question is how I create the loop to prompt my question over and over until the user inputs 'yes' or 'no'.
Try this:
while 1
b = input('Is today your birthday? ','s');
if any(strcmpi(b,{'yes','no'}))
break
end
end
Here is a way (there are many others):
Use a while loop in which you put the prompt (here I use inputdlg) and once the user enters the answer, you check if the string entered compares to either yes, Yes, no and No. If it does not, the dialog box pops up again. If it fits, a message appears.
In order to compare multiple strings at once, you can use strcmp with the answer provided by the user and use a cell array containing the strings you are looking for (i.e. yes/no/etc.). If the answer corresponds to any of the strings, the array (called CheckAns) contains a 1 and the sum is different than 0; otherwise the sum equals 0 so the loop continues.
That's a lot of words so here is the code:
%// Initialize the look up array. All 0 to start and enter the loop
CheckAns = [0 0 0 0];
while ~sum(CheckAns)
Ans = inputdlg('Is this your birthday?');
CheckAns = strcmpi(Ans,{'yes';'no'});
if strcmpi(Ans,'yes')
disp('Happy birthday')
elseif strcmpi(Ans,'no')
disp('Haha loser')
end
end
Related
I have a collection of smaller scripts foo1, foo2, etc. and a script master.m that runs them all, like this:
% master.m
run foo1
run foo2
Let's say foo1 calls for input somewhere by saying a = input('Gimme a number\n');.
I thought that if I put the value(s) I wanted on new lines after the run command that they would be entered as input, but they don't. I've also tried enclosing them as a string, i.e. '5'. That doesn't work either.
Is their another function I should use? I looked at the help file for input, but there's no output function. Presumably there's something like write or writetostdio somewhere.
How do I give user input to a script that is being called by another script without touching the keyboard? Can I put the values I want to input in the master.m file?
EDIT:
Because there's some confusion, I'll try to clear it up.
The scripts foo1 and foo2 will NOT be passing values back and forth. Every script will be run independently. Instead, I'm trying to test a program for a range of user behaviours (which are responses to prompts via input in foo1). These are normally typed on the keyboard, but I want my master.m file to tell foo1 what the user inputs are.
Sorry if this is confusing, but hopefully that clears it up.
Modifying existing code to accommodate both manual input and testing inputs is trivial:
function foo1(niterations)
if nargin == 0
niterations = round(input('How many iterations? '));
end
for ii = 1:numel(niterations)
% Run the thing
fprintf('Running some random program with %d iterations! Yay!\n', niterations(ii));
end
end
Using this approach we can do:
>> foo1
How many iterations? 2
Running some random program with 2 iterations! Yay!
or
>> foo1(2)
Running some random program with 2 iterations! Yay!
or
>> foo1([1, 3, 5, 7, 9])
Running some random program with 1 iterations! Yay!
Running some random program with 3 iterations! Yay!
Running some random program with 5 iterations! Yay!
Running some random program with 7 iterations! Yay!
Running some random program with 9 iterations! Yay!
This is far more logical than trying to pipe things from text files, use evalin to poof things into workspaces, or whatever automagical approach is required to accommodate using scripts in this fashion.
Ok, this is a bit ugly... but might be a work-around if for some reason foo1.m etc. have to remain as scripts.
The idea is to replace each instance of input with a newly defined function myInput which checks if a variable PROMPT_VALUE has been set in the base work-space; and returns that if so, and otherwise passes through to the built-in input. For example:
% myInput.m
function [ valueOut ] = myInput( promptString )
W = evalin('caller','whos'); %or 'base'
doesPVexist = ismember('PROMPT_VALUE',[W(:).name]);
if doesPVexist
valueOut = evalin('caller', 'PROMPT_VALUE');
else
valueOut = input(promptString);
end
end
Assuming we have the following sub-scripts:
% foo1.m
a = myInput('Number to double: ');
disp(2*a);
% foo2.m
b = myInput('Number to halve: ');
disp(b/2);
We can test the approach as follows:
% master.m
clearvars;
PROMPT_VALUE=5;
run foo1.m;
PROMPT_VALUE=3;
run foo2.m
If you run this as-is it will take the PROMPT_VALUE as inputs to each of the subscripts (returning 10, and 1.5). If those lines are commented out it will look for input from the user.
I am trying to filter workgroup name that only contains BL or CL so I used the formula...
STARTSWITH([wrkgrp_shrt_nm], "BL") or STARTSWITH([wrkgrp_shrt_nm], "CL" )
I get the little green check, but when I hit apply it is blank and nothing pulls through
I tried another formula...
if right([wrkgrp_shrt_nm],2) = 'BL' then 1 elseif
right([wrkgrp_shrt_nm],2) = 'CL' then 1 elseif
right([wrkgrp_shrt_nm],2) then 0
end
but I am only getting an error
any suggestions?
If you want "contains", you can just call contains()
contains(wrkgrp_shrt_nm, 'BL') or contains(wrkgrp_shrt_nm, 'CL')
Does the same thing as the find() solution Fred posted, just a little easier to read in this case. I'm not sure why Fred says you cannot use IF. I use IF all the time without problems.
BTW, in case you were wondering, the square brackets around field names are optional if the field name does not include spaces or punctuation, and function names are not case sensitive.
To clarify, you're asking for "contains BL or CL", but your formula specify STARTSWITH which will be true is your field [wrkgrp_shrt_nm] starts with the string "BL" or the string "CL".
If you want "contains", you could use FIND:
FIND([wrkgrp_shrt_nm], 'BL' ) > 0 OR FIND([wrkgrp_shrt_nm], 'CL' ) > 0
You cannot use IF in a condition field, but you can use inline IF (IIF), however it's not necessary in your case.
Edit:
I can totally be wrong with my comment on IF (because I'm still new in Tableau) but I tried IF in a condition field of a filter (as the OP asked) and I can't make it work. I use IF all the time in Calculated Fields however. I'll try again...
I am making program which will go through all possible choices.
Range is from 00000 to 99999.
For example:
00001,00002...01000,01001,01002...99999.
The problem is that i can make string as '00000' but as i convert it to int in order to add extra 1 to keep cycle going only one 0 appears. In that case i will get 0+1 = 1 and i need 00001.
Not completely sure how should i do it with lists because i might need it in the future for certain operations (to get one element from a current number 00450, 01004, 94571...)
Any advice/help would be greatly appreciated! :)
You can use zfill(num) on strings to add leading zeros
def convert_int(number,decimals) :
return str(number).zfill(decimals)
print convert_int(1,6) #prints 000001
I don't know if this is exactly what you want, but you can use string formatting. For example, this will turn int('00000') + 1 into '00001':
new_i = '%05d'%(int('00000')+1)
where %05d adds as many trailing zeros as necessary to whatever comes after % so the total length of the final string formatted number is 5.
Can I do the something below coded using or without loop?
Actually I am having a character array comprising of unique words more than 5000 and other array comprising of approx 3000 words. I want to search each word in my array named as word in other array named as uniques and wish to create a feature vector i.e. values 1 if exists and 0 if doesn't.
I am doing the following..
load 'uniques' %uniques={'alpha','ok',abc'};
fid=fopen(myfilename);
words=textscan(fid,'%s');
fclose(fid);
word=words{1,1}; %word={'good','bad',anywhere','countries','ok',done','abc'}
for i=1:size(uniques,2)
ind=strmatch(word(i), uniques, 'exact');
end
Now, seeing above as examples before uniques and word arays, my system must return 0 for good as good is not there in uniques and same 0 values but 1 for ok because it does exist in uniques. All in all, I must have in the end, {0,0,0,0,1,0,1} ..
After I run, it gives me ind=[]
Please guide
You have described the exact functionality of the ismember function:
ismember(word, uniques);
as an aside, this is what #nkjt was saying about fixing your loop:
for i=1:size(word,2)
ind(i)=strmatch(word(i), uniques, 'exact');
end
But this loop is unnecessary since Matlab has this as a built in function
Been programming in C# for a little bit - trying to use file maker and I cant believe it but I cant even get a simple for loop to work.
What I want to do is simple: loop through for the amount of entries in my "amountOfRooms" field and create an entry in a table for each room.
Sounds so simple, but I cant get it to work. Right now I have this:
Set Variable[$cnt[Customers::AmountOfRooms]; value:1]
Go to Layout["rooms"(Rooms)]
Loop
Exit Loop If[$cnt = Customers::AmountOfRooms]
New Record / Request
Set Variable[$cnt; Value: $cnt + 1]
End Loop
Exit Script
No new records are created. I know the script is running because it does go to my layout, but doesnt create any new records. There is a "Repetition" field for my local variable - not sure how to use that or what it means? Any thoughts on how to do this simple loop? Thanks.
Loop
Depending on your relationship, the line Exit Loop If[$cnt = Customers::AmountOfRooms] might be equal at the first iteration because you set the variable to the value three lines above it: Set Variable[$cnt[Customers::AmountOfRooms]; value:1]
There are other ways to do it, but one common technique is to have a $i variable compare against $cnt like this:
Set Variable [$cnt; Value:Customers::AmountOfRooms]
Go to Layout ["Rooms" (Rooms)]
#
Set Variable [$i; Value:1]
Loop
Exit Loop If [$i >= $cnt]
New Record/Request
Set Variable [$i; Value:$i + 1]
End Loop
Exit Script []
Repetition Number
At a high level, you can think of a FileMaker variable as a 1-indexed array. So the statements:
# Set Repetition 1 of $i to 1
Set Variable [$i; Value:1]
#
# Set Repetition 2 of $j to "Second Array Position"
Set Variable [$j[2]; Value:"Second Array Position"]
Would be equivalent to:
# Set the first value of array $i to 1
$i[0] = 1;
#
# Set the second value of array $j to "Second Array Position"
$j[1] = "Second Array Position";
in some other languages.
It's worth nothing that the array comparison is not strictly apt, but it's a good way to begin thinking of them. Regardless, you don't need to worry about the repetition number in this instance. If you want to learn more, you can start here: http://www.filemaker.com/11help/html/scripts_ref1.36.15.html