I am looking for a M-Function that returns the currently opened Excel Spreadsheet Filename without the directory and extension.
i.e. If the spreadsheet that is opened is located here:
C:\HPCLMHSTLI_930.XLSX
I would like:
HPCLMHSTLI_930
Note: I got this working using a Custom M Function that reads a Settings Table which has two Cells defined with the following:
=MID(CELL("filename"),SEARCH("[",CELL("filename"))+1, SEARCH("]",CELL("filename"))-SEARCH("[",CELL("filename"))-1)
=LEFT(B3,(SEARCH(".",B3)-1))
So I am NOT looking for this solution. This solution just seems like a lot of work and that there should be a more elegant M-Language function that would return the currently opened spreadsheet filename.
I didn't quite follow how you got the path - I guess that is Cell("fileName"), but with a bit of fiddling with M Code, I came up with the following:
let
x = "C:\HPCLMHSTLI_930.XLSX",
y=Text.AfterDelimiter(x,"\"),
z=Text.BeforeDelimiter(y,".")
in
z
This seems to do the trick. Since a file name can have more than 1 period in it, this may be too simple, but maybe this can work if your filenames are simple enough.
But this can be improved by wrapping this in a function in the following way:
let
ParseFileName = (x) =>
let
y=Text.AfterDelimiter(x,"\"),
z=Text.BeforeDelimiter(y,".")
in z
in
ParseFileName
and then call that using something like this:
let
Source = ParseFileName("C:\HPCLMHSTLI_930.XLSX")
in
Source
I found two more possible answers.
This first is a bit more sophisticated than the one above. In this case, we grab the substring starting after the first "\" and the last "."
let
x = "C:\HPCLMHSTLI_930.XLSX",
y = Text.PositionOf(x,"\", Occurrence.First),
z = Text.PositionOf(x,".", Occurrence.Last),
a = Text.Middle(x,y+1,z-y-1)
in
a
There probably should be if statements in case one of these characters are not found.
I found one final solution that could also work in the simpler cases.
let
x = "C:\HPCLMHSTLI_930.XLSX",
z = Text.BetweenDelimiters(x,"\",".")
in
z
M gives us a bunch of choices on this.
Related
I have a variable
filterSize = 3; %Size of the Filter;
I want to define a new char variable called size and assign it as
size = (filterSize x filterSize)
size='3x3';
but I want to use filterSize to do it to automate. size need to be char. Thanks
You can use sprintf to format a char containing variables
filterSize = 3;
sz = sprintf( '%dx%d', filterSize, filterSize );
You should avoid using size as a variable name because you're shadowing a commonly used in-built function.
I have solved the problem.
size_temp = [string(filterSize),'x',string(filterSize)];
a = convertStringsToChars(size_temp);
x=char(size_temp(1));
y=char(size_temp(2));
z=char(size_temp(3));
size = [x,y,z]
but as cris Luengo suggests in the comments
size = [num2str(filterSize),'x', num2str(filterSize)] is a better solution
MATLAB has a function that precisely does what you asked for:
.
call generic example :
evalin('base',['output = ',expression])
MATLAB funtion help reference :
https://uk.mathworks.com/help/matlab/ref/evalin.html?s_tid=srchtitle_evalin_1
Assigning a value to new variable within your code has detractors and supporters, as it is a sharp tool that writes new code with code.
I had a couple of bitter discussions with a Mathworks forum member over different ways to use evalin.
When some one preaches not to do something because they call it sinful yet they keep doing it all the time, there's room for doubt that people in general should refrain to use evalin to concisely build new code within existing code.
I recommend you to ignore the last line in evalin help page where some one discourages from using evalin to exactly do what you need to in order to solve your question.
Hope it helps
I need to update one field of a very large default record.
As the default may change I don't want to rebuild the entire record manually.
Now I have come across the following way of doing this, but I am not sure how it works:
unaggregate :: MyResult -> MyResult
unaggregate calc#MyResult{..} = calc{ the_defaults = the_override
`mappend` the_defaults }
where
the_override = create ("aggregation" := False)
I have tried searching for 'Haskell # operator' in Google but it does not return immediately useful information.
I saw somewhere calc#MyResult{..} does pattern matching on variables but I don't see what variable calc does for the MyResult record...
Also I have looked up mappend (and Monoids) and I am not sure how these work either...
Thank you for any help
The # symbol is called an "as-pattern". In the example above, you can use calc to mean the whole record. Usually you'd use it like this: calc#(MyResult someResult) -- so you can have both the whole thing and the pieces that you're matching. You can do the same thing with lists (myList#(myHead:myTail)) or tuples (myTuple#(myFst, mySnd). It's pretty handy!
MyResult{..} uses RecordWildcards. Which is a neat extension! BUT RecordWildcards doesn't help you update just one field of a record.
You can do this instead: calc { theFieldYouWantToUpdate = somethingNew }.
I am currently attempting to parse data that is sent from an outside source serially. An example is as such:
DATA|0|4|7x5|1|25|174-24|7x5|1|17|TERW|7x5|1|9|08MN|7x5|1|1|_
This data can come in many different lengths, but the first few pieces are all the same. Each "piece" originally comes in with CRLF after, so I've replaced them with string.gsub(input,"\r\n","|") so that is why my input looks the way it does.
The part I would like to parse is:
4|7x5|1|25|174-24|7x5|1|17|TERW|7x5|1|9|08MN|7x5|1|1|_
The "4" tells me that there will be four lines total to create this file. I'm using this as a means to set the amount of passes in the loop.
The 7x5 is the font height.
The 1 is the xpos.
The 25 is the ypos.
The variable data (172-24 in this case) is the text at these parameters.
As you can see, it should continue to loop this pattern throughout the input string received. Now the "4" can actually be any variable > 0; with each number equaling a set of four variables to capture.
Here is what I have so far. Please excuse the loop variable, start variable, and print commands. I'm using Linux to run this function to try to troubleshoot.
function loop_input(input)
var = tonumber(string.match(val, "DATA|0|(%d*).*"))
loop = string.match(val, "DATA|0|")
start = string.match(val, loop.."(%d*)|.*")
for obj = 1, var do
for i = 1, 4 do
if i == 1 then
i = "font" -- want the first group to be set to font
elseif i == 2 then
i = "xpos" -- want the second group to be set to xpos
elseif i == 3 then
i = "ypos" -- want the third group to be set to ypos
else
i = "txt" -- want the fourth group to be set to text
end
obj = font..xpos..ypos..txt
--print (i)
end
objects = objects..obj -- concatenate newly created obj variables with each pass
end
end
val = "DATA|0|4|7x5|1|25|174-24|7x5|1|17|TERW|7x5|1|9|08MN|7x5|1|1|_"
print(loop_input(val))
Ideally, I want to create a loop that, depending on the var variable, will plug in the captured variables between the pipe deliminators and then I can use them freely as I wish. When trying to troubleshoot with parenthesis around my four variables (like I have above), I receive the full list of four variables four times in a row. Now I'm having difficulty actually cycling through the input string and actually grabbing them out as the loop moves down the data string. I was thinking that using the pipes as a means to delineate variables from one another would help. Am I wrong? If it doesn't matter and I can keep the [/r/n]+ instead of each "|" then I am definitely all for that.
I've searched around and found some threads that I thought would help but I'm not sure if tables or splitting the inputs would be advisable. Like these threads:
Setting a variable in a for loop (with temporary variable) Lua
How do I make a dynamic variable name in Lua?
Most efficient way to parse a file in Lua
I'm fairly new to programming and trying to teach myself. So please excuse my beginner thread. I have both the "Lua Reference Manual" and "Programming in Lua" books in paperback which is how I've tried to mock my function(s) off of. But I'm having a problem making the connection.
I thank you all for any input or guidance you can offer!
Cheers.
Try this:
val = "DATA|0|4|7x5|1|25|174-24|7x5|1|17|TERW|7x5|1|9|08MN|7x5|1|1|_"
val = val .. "|"
data = val:match("DATA|0|%d+|(.*)$")
for fh,xpos,ypos,text in data:gmatch("(.-)|(.-)|(.-)|(.-)|") do
print(fh,xpos,ypos,text)
end
I have the code mentioned below in matlab. I want to write all the 162 rows and 4 columns calculated into an excel file.
When i use xlswrite in the code i get only one row and 4 columns as the value of P gets overwritten in each iterative step.
If i use another loop inside the for loop the execution time increase drastically. Please help to least write the values of P into an array which i can later write into excel file(when i tried 'In an assignment A(I) = B, the number of elements in B and I must be the same' error appeared.)
please help
function FitSMC_BC
clc
% Parameters: P(1)=theta_S; P(2)=theta_r; P(3)=psib; P(4)=lamda;
smcdata=xlsread('asimdata');
nn=length(smcdata)-1;
for i=1:nn
psi=smcdata(:,1);
thetaObs=smcdata(:,i+1);
%Make an initial guess:
Pini=[0.5 0.1 -1 1.5];
P=fminsearch(#ObFun,Pini,[],psi,thetaObs);
disp(['result',num2str(i),': P=',num2str(P)]);
theta=Gettheta(P,psi);
end
function OF=ObFun(P,psi,thetaObs)
theta=Gettheta(P,psi);
OF=sqrt(mean((theta - thetaObs).^2));
function theta=Gettheta(P,psi)
SoilPars.theta_S=P(1);
SoilPars.theta_r=P(2);
SoilPars.psib=P(3);
SoilPars.lamda=P(4);
[theta]=thetaFun(psi,SoilPars);
function [theta]=thetaFun(psi,SoilPars)
theta_S=SoilPars.theta_S;
theta_r=SoilPars.theta_r;
psib=SoilPars.psib;
lamda=SoilPars.lamda;
theta=theta_r+((theta_S-theta_r)*((psib./psi).^lamda));
theta(psi>psib)=theta_S;
You can modify the P line with
P(i,:) = fminsearch(#ObFun,Pini,[],psi,thetaObs);
P will store each calculation (4 element vector) in a new line.
You may also initialise P before the for loop with P = nan(nn, 4);
Then write P in an Excel file using xlswrite.
I haven't studied your code in-depth, but as far as I can tell, you have two options:
Create a matrix P and use xlswrite on the entire matrix. This seems to me like the most reasonable approach.
Use xlswrite1 from the fileexchange in a loop. This will increase execution time a bit, but not nearly as much as using regular xlswrite as it is specially deigned to be used inside loops. The reason why it is so much faster is because it only opens and closes the Excel-file once, whereas the regular xlswrite opens and closes it every time you call the function.
You seem to know how to use indexing so I'm not sure why you're simply doing something like this:
P = zeros(size(smcdata,1),nn)
for i=1:nn
...
P(:,i) = fminsearch(#ObFun,Pini,[],psi,thetaObs);
disp(['result',num2str(i),': P=',num2str(P(:,i))]);
theta = Gettheta(P(:,i),psi); % Why is this here? Are you writing it to file too?
end
xlswrite('My_FileName.xls',P);
Or you could call xlswrite on each iteration of the loop (probably slower) and append the new data using something like this:
for i=1:nn
...
P = fminsearch(#ObFun,Pini,[],psi,thetaObs);
disp(['result',num2str(i),': P=',num2str(P)]);
theta = Gettheta(P,psi); % Why is this here? Are you writing it to file too?
xlswrite('My_FileName.xls',P,1,['A' int2str((i-1)*size(P,2)+1)]);
end
Of course your code isn't runnable so you'll have to debug any other little errors. Also, since smcdata seems to be a matrix rather than a vector, you should be careful using length with it. You probably should use size.
Question : Is there a way to have direct access to a specific cell in vtkPolyData structure?
I'm using vtkPolyData to store sets of lines, say L.
Currently, I'm using GetLines() to know the number of lines in L. Then, I have to use GetNextCell to go through this set of lines using a "while" loop.
Current code is something like:
vtkSmartPointer<vtkPolyData> a;
...
vtkSmartPointer<vtkCellArray> lines = a->GetLines();
...
while(lines->GetNextCell(numberOfPoints, pointIds) != 0)
-> I'd like to be able to work directly on a specific line by doing something like:
myline = a[10];
doSomething(myline);
you could get an access to a specific cell using vtkDataSet::GetCell(vtkIdType cellId) function