Chef file evaluation only_if - chef-recipe

Attempting to File.readlines fails at converge even with 'only_if' check:
ruby_block 'set_archive_mode' do
only_if (File.exists?(node['ORACLE_DATABASE']['ORACLE_ADMIN'] + '/' +
node['ORACLE_DATABASE']['ORACLE_SID'] + '/database_archive_verify.test'))
if File.readlines(node['ORACLE_DATABASE']['ORACLE_ADMIN'] + '/' +
node['ORACLE_DATABASE']['ORACLE_SID'] +
'/database_archive_verify.test').grep(/^NOARCHIVELOG/).size > 0
node.run_state['archive_mode'] = 'noarchivelog'
else
node.run_state['archive_mode'] = 'archivelog'
end
end
The code just needs to set a node.run_state transient attribute based on the contents of the file. I've tried several different approaches all resulting in various errors. The above code include 'only_if', but the File.readlines is still being evaluated at converge.

You are using ruby_block wrong, your "readlines" code should be put in the block attribute.

Related

Name convention error with write to file in Matlab

I'm running into a problem with the following code and writing an excel file name. This code is driven by user defined inputs for location and chemical compound desired. The desired output is a file with the chemical compound and location appended for the name. The problem is that any compound with a . in it errors out. For example, if I want PM2.5 for site Kenny, the file name should be PM2.5 Kenny. The code however is recognizing ".5" as a file extension when this is to be part of the name. Any help how to get around this would be appreciated.
The error this gives is:
Unrecognized file extension '.5 Kenny'. Use the 'FileType' parameter to specify the file type.
j = 1
i = 1
while j <= width(c_locations_of_interest)
while i <= width(c_data_types_of_interest)
Value = c_data_types_of_interest{1,i}
Location = c_locations_of_interest{1,j}
output_excel_file = append(Value,' ',Location)
STATEMENTS
writetable(T, output_excel_file)
i = i + 1
end
i = 1
j = j + 1
end
I was able to reproduce your problem with a crude example. Indeed Matlab complains about file extensions. This is because I believe that you are missing the file extension, in your case '.xlsx'
Using sprintf instead of Append:
value = "PM2.5";
location = " Kenny"
extension = "xlsx";
output_excel_file= sprintf("%s%s.%s", value, location, extension);
writetable(T, output_excel_file);
Hope it is clear
EDIT: Corrected my own variables naming ¬¬

The PERSISTENT declaration must precede any use of the variable

While working on my matlab homework, I came across a very strange bug. Here's my code:
function [z,times] = Divide(x,y)
persistent times;
if (y == 0)
if (isempty(times))
times = 1;
else
times = times + 1;
end
end
z = x/y;
end
When run, this gives me the error:
Error: File: Divide.m Line: 3 Column: 16
The PERSISTENT declaration must precede any use of the variable times.
This is strange, because it is telling me that I need to declare the variable as persistent before I declare it as persistent (!?). I have no idea what I'm doing wrong here, so if there's some strange workaround that I should be using, please tell me.
The error message means : you've used the 'times' before you declare it as persistent variable. As you used 'times' in return variables.
One of the solution might be keep two different variables for 'times', one for persistent, and another one for return variable.
Paste my change here for your reference. Good luck!
function [z,times] = Divide(x,y)
persistent p_times;
if (y == 0)
if (isempty(p_times))
p_times = 1;
else
p_times = p_times + 1;
end
end
times = p_times;
z = x/y;
end

Express A^2 as A * A in Matlab

So, I have a really long symbolic exrpression in Matlab that I want to copy/paste into a JavaScript-code to animate a numerical solution for it. The problem is that some places in my code i get exponents (mostly ^2), when I'd rather have Matlab express it as A*A.
I have mulitple (and different) expressions like
cos(th2t)^2
That I would rather have expressed as
cos(th2t)*cos(th2t)
Any way I can do this? The alternative is to use a text editor afterward and search for powers of 2 and replace it, but there are multiple different expressions, so that would take some time...
This is an example of one of the exrpressions I end up with:
(J31*(2*ddth2t*cos(th1t) - 2*w12*w13 - 4*dth1t*dth2t*sin(th1t) - 4*dth2t*w13*sin(th1t) + dth1t^2*sin(2*th2t)*cos(th1t) - w12^2*sin(2*th2t)*cos(th1t) + w13^2*sin(2*th2t)*cos(th1t) + 2*dth2t*w11*sin(2*th2t) + 2*w12*w13*cos(th2t)^2 + ddth1t*sin(2*th2t)*sin(th1t) + 4*dth1t*dth2t*cos(th2t)^2*sin(th1t) + 2*dth1t*w13*sin(2*th2t)*cos(th1t) + 4*dth2t*w13*cos(th2t)^2*sin(th1t) + w11*w12*sin(2*th2t)*sin(th1t) + 4*dth1t*w12*cos(th1t)^2*cos(th2t)^2 - 2*dth1t*w11*sin(2*th1t)*cos(th2t)^2 - 2*dth2t*w11*sin(2*th2t)*cos(th1t)^2 + 2*w12*w13*cos(th1t)^2*cos(th2t)^2 - w11*w13*sin(2*th1t)*cos(th2t)^2 - 4*dth2t*w12*cos(th1t)*cos(th2t)*sin(th1t)*sin(th2t)))/(2*(J11 + J31))
Steve's answer should work fine if you want to rely on the ** operator. However, since that operator is not officially supported, and that solution doesn't directly answer the OP's question, here is a function that can expand out the exponents in a symbolic expression.
function [ text ] = remove_powers( exp )
%Cleans the powers from T, and return expanded text representation
% Define functions
enclose =#(t) ['(' t ')'];
expand_pow=#(b,p) strjoin(strcat(cell(1,p),enclose(char(b))),'*');
count_pow=#(s) arrayfun(#(k) count(char(s(k)),'^'), 1:length(s));
sym2str = #(s) strrep(char(s), ' ', '');
% Check for fractions
[N,D]=numden(exp);
if ~isequal(D,sym(1))
% pass up the num and den
text = [remove_powers(N) '/' enclose(remove_powers(D))];
else
% Split a into subterms
Ts = children(exp);
% Clean children
has_pow=count_pow(Ts)>0;
text = sym2str(exp);
if sum(count_pow(Ts))<count_pow(exp)
% We have removed a power, clean it, expand it, and pass up
text = expand_pow(remove_powers(Ts(1)),Ts(2));
else
% Just clean the unclean children and pass up
for t=Ts(has_pow)
text = strrep(text,sym2str(t),remove_powers(t));
end
end
end
end
The function uses the children function in Matlab to recursively clean each subexpression and replace it (as text) in the parent. This method is better than using regex because it avoids the issue of parsing the syntax, as Steve mentioned in the comment with respect to cos(x^2+2*y)^2.
Which makes for a good example:
syms x y real
exp = cos(x^2+2*y)^2;
cleaned_exp = remove_powers(exp)
Outputs: (cos(2*y+(x)*(x)))*(cos(2*y+(x)*(x)))
Notice that since Matlab is doing the parsing, there was no need to parse the order of precedence for the '^' operators, which could be difficult to accomplish with regex.
To test the OP's example:
syms ddth1t dth1t th1t ddth2t dth2t th2t w11 w12 w13 J11 J31 real
exp = (J31*(2*ddth2t*cos(th1t) - 2*w12*w13 - 4*dth1t*dth2t*sin(th1t) - 4*dth2t*w13*sin(th1t) + dth1t^2*sin(2*th2t)*cos(th1t) - w12^2*sin(2*th2t)*cos(th1t) + w13^2*sin(2*th2t)*cos(th1t) + 2*dth2t*w11*sin(2*th2t) + 2*w12*w13*cos(th2t)^2 + ddth1t*sin(2*th2t)*sin(th1t) + 4*dth1t*dth2t*cos(th2t)^2*sin(th1t) + 2*dth1t*w13*sin(2*th2t)*cos(th1t) + 4*dth2t*w13*cos(th2t)^2*sin(th1t) + w11*w12*sin(2*th2t)*sin(th1t) + 4*dth1t*w12*cos(th1t)^2*cos(th2t)^2 - 2*dth1t*w11*sin(2*th1t)*cos(th2t)^2 - 2*dth2t*w11*sin(2*th2t)*cos(th1t)^2 + 2*w12*w13*cos(th1t)^2*cos(th2t)^2 - w11*w13*sin(2*th1t)*cos(th2t)^2 - 4*dth2t*w12*cos(th1t)*cos(th2t)*sin(th1t)*sin(th2t)))/(2*(J11 + J31));
cleaned_exp = remove_powers(exp);
isequal(sym(cleaned_exp),exp) % This should be 1
count(cleaned_exp,'^') % This should be 0
As expected, the new expression is equivalent to the original, but has no '^' symbols.
This answer suggests that you could call the exponential operator in Javascript with e.g. A**2. As such you could replace all instances of ^ with **.
(Solution from comments)

'Undefined function or variable' in Matlab

Here is my code:
function [im,sindx,end1]=alln(im,i,j,secret,sindx,end1)
slen=length(secret);
p=im(i,j);
neigh= [im(i-1,j) im(i+1,j) im(i,j-1) im(i,j+1) im(i-1,j-1) im(i+1,j-1) im(i-1,j+1) im(i+1,j+1)];
minpix = min (neigh)
maxpix = max (neigh)
if minpix < p < maxpix
lowlim = minpix+1;
highlim = maxpix-1;
range = highlim-lowlim+1;
nbits=floor(log2(abs(range)));
if sindx+nbits-1>slen
end1=1;
return
end
for k=1:nbits
bin(k)=secret(sindx+k-1);
end
b = bin2dec(bin);
newvalue1 = abs (minpix + b);
newvalue2 = abs (maxpix - b);
if abs(p-newvalue1)<= abs(p-newvalue2)
im(i,j) = newvalue1;
else
im(i,j) = newvalue2;
end
sindx=sindx+nbits;
end
end
My main program calls this function. When I run the program, I get the following error message:
??? Undefined function or variable "bin".
Error in ==> alln at 34
b = bin2dec(bin);
I know there are many experts for whom this is not a problem at all. I am new to MATLAB. Please guys, show me the way, which type of modification in the code can overcome this problem?
First of all, are there some lines missing from the file? Perhaps you've stripped some comments from the top? Because the error message says that
b = bin2dec(bin);
is line 34, but it's line 22 in the code you present.
OK, that aside...
The error message says that 'bin' isn't defined, but I see that it's being set on the line...
bin(k)=secret(sindx+k-1);
That suggests to me that THAT line isn't being run.
I see that that bin = ... line is inside of a 'for' loop, so I suspect that the for loop is run zero times, meaning that 'bin' never gets defined. What is nbits? Is it 1, or perhaps less than 1? THAT would prevent the loop from running at all.
Try removing the semicolon from the end of the
nbits=floor(log2(abs(range)));
line and run your code again.
Leaving off the semicolon will force the value of nbits to be printed in the Command Window. I bet you'll find that it's 1 or less. If that's the case, then start looking at HOW nbits is calculated, and I bet you'll find the problem.
At what input arguments to the function alln, are you getting the error?
Lets suppose that nbits is 0, then the following loop will not run:
for k=1:nbits
bin(k)=secret(sindx+k-1);
end
So, bin will be undefined. So, the error happens. This is one of the cases where the error can happen. There are many such possible cases.

How can i make the 'if' selection sturucture work for an array of inputs while doing a loop with a 'while' structure?

A=[21.04 93.3 133.5 158.5 182.5];
k=0;
while k<=length(A)
k=k+1;
if A(k) <=170
B=(4*10^-5).*(A).^2 + (0.0096).*A + 0.012;
else
B=(0.0005).*(A).^2 - (0.1503).*A + 14.131;
end
end
I was trying to use conditions to solve a problem with two outcomes, but Matlab kept telling me i cant use 'if' for an array selection. how can i improve it? please help me.
This should work as it stands now, but there are a few issues I see. It seems like you are trying to make B dependent on the value of A. I don't think you are doing what you intend to do. A much simpler way would be:
B=zeros(size(A))
B(A<=170)=(4*10^-5).*(A(A<=170)).^2 + (0.0096).*A(A<=170) + 0.012)
B(A>170)=(0.0005).*(A(A>170)).^2 - (0.1503).*A(A>170) + 14.131;
Also, you are looping too much. A for loop would be much easier to follow, and useful in this case:
for k=1:length(A)
if A(k) <=170
B=(4*10^-5).*(A).^2 + (0.0096).*A + 0.012;
else
B=(0.0005).*(A).^2 - (0.1503).*A + 14.131;
end
end