openscad If statement issue with variable - openscad

I have a problem with If statement in OpenScad.
I have 4 variables
a=20;
b=14;
w=1;
c=16;
I want to check witch number is bigger a or b.
And after depending who is smaller to take the value of smaller variable(in our case b < a) and to make a simple operation with c variable ( c=b-w).
I tried like this but it doesn't work.
a=20;
b=14;
w=1;
c=16;
if(a>b)
{
c=b-w;
}
if (a<b)
{
c=a-w;
}
if (a==b)
{
c=a-w;
}
It seems logic, but in openscad as I understood you can't change the value of variable inside a If statement. What trick can I use in order to get my goal.
Thank you!

in the 3. leg you confused the assignment-operator „=“ with the equal-operator „==“ (correct if (a==b)).
in your 3. leg you do the same as in the 2., so you could handle both as an „else“-leg.
Correct: assignment is not allowed in if-statement. In openscad you can use the ? operator instead:
c = a > b ? b-w : a-w;
After = follows the condition. The statement after the ? becomes the value if the condition is true, and the statement after the : becomes the value if the condition is false. Nested conditions are possible, e.g. your conditions:
c = a > b ? b-w : (a < b ? a-w : a-w);
More information in the documentation.

OpenSCAD's variable assignment is different. You can only assign variables inside a bracket. So c = b - w will only be assigned inside the if bracket. Outside if this bracket it will still be 16. Don't ask me why. You can read more in the Documentation of OpenSCAD.

c = min(c,min(a,b)/2-w);
this also solve the problem )

Related

Swift Programming Beginner : Why is there an error in my loop when implementing a Variable?

When I try and run my code in Xcode playground I get a warning:
Variable 'n' was never mutated; consider changing to 'let' constant.
First of all, I am changing the variable in the body of the loop so why is it telling me to change it to a let (constant) data type.
func multiples (n : Int) {
var n = 1
for _ in (3 ..< 1000) {
var n = n + 1
let multiple3 = 3 * n
print(multiple3)
}
}
I am changing the variable in the body of the loop
No, you’re not. The one in the body of the loop is a different n.
To fix that, change
var n = n + 1
To
n = n + 1
3 little notes:
a) If you read carefully messages from Xcode, you will understand about vars' lifetime and usage. ("Variable 'n' was never mutated; consider changing to 'let' constant" )
b) you have two var with same name in different scope
c) the you enter "for", n on the left will be computed using N in outer scope, so inner n will always be == 2
d) using debugger You will see as in picture.
Those are two different variables named n. One is unchanged and one is created for each new iteration of the for loop.
The reason you can have two variables with the same name is that they exist in different scopes and the one inside the for loop temporarily overrides the one outside the loop for the duration of the loop but only inside it.

Does mathjs have any concept of null or undefined?

I think the answer is probably 'no' as from what I can tell maths libraries don't seem to handle null, but what I'd like to have is to be handle null in these scenarios:
x=1
(y not defined)
z = sum(x, y)
with eval() ideally giving:
z=1
However, this throws an exception, as y is not defined.
In effect I'm defaulting 'y' to zero in that example, and that won't work in all scenarios.
So, what I suppose I'm asking is, is there an in-built way to define a default for a variable if it's not assigned a value?
If not, I'm assuming that this would be possible by writing a custom function. If someone could confirm this, I'd really appreciate it.
Thanks :-).
Ok - I was looking through the release notes for v4 and saw it talking about the constants 'null, undefined' (and others). So, in order to solve this I have to define a variable as undefined (probably should have known this!).
(Note: I suspect these constants are available in previous version too.)
Then combined with a 'default' custom function I can get what I wanted:
x=1
y = null
z = sum(x, def(y, 0))
z=1
where 'def' is defined and imported as below (making use of 'lodash'):
var customFunctions = {
def: function (value, defaultValue) {
return !_.isNil(value) ? value : defaultValue;
}
};
math.import(customFunctions);
BOSH!

Maple strange results while solving for complex equation

I'm trying to make Maple solve a complex equation, but it produces an incorrect result.
The following images tells it all :
At (3) I would expect to get something close to 1 (as (2) shows), yet it gives me something that doesn't make any sense. Is it that the || (to express the complex number modulus) operator has another significance in the solve() function?
The more appropriate function here is fsolve.
Example 1
restart:
G:=(w,L)->(5+I*L*2*Pi*w)/(150+I*L*2*Pi*w);
evalf(5*abs(G(10,1)));
fsolve(5*abs(G(10,L))=%,L=0..10)
Example 2
As above, you need to specify the interval L=0..1 where the solution might be.
G:=(f,L)->(256.4+I*L*2*Pi*f)/(256.4+9845+I*L*2*Pi*f);
evalf(5*abs(G(20000,0.03602197444)));
fsolve(5*abs(G(20000,L))=%,L=0..1);
If you are facing difficulties to specify the interval then you should plot it first, it will give you an idea about it?
plot(5*abs(G(20000,L)),L=0..1)
Restrict the values of L in the solve command with the assuming command.
Example 1:
G:= (w,L) -> (50+I*L*2*Pi*w)/(150+I*L*2*Pi*w);
result := evalf(5*abs(G(10,1)));
solve({5*abs(G(10,L)) = result},L) assuming L::real;
{L = 1.000000000}, {L = -1.000000000}
Example 2:
G:=(f,L) -> (256.4+I*2*Pi*L*f)/(256.4+9845+I*2*Pi*L*f);
result := 5*abs(G(20000,0.03602197444));
solve({5*abs(G(20000,L)) = result},L) assuming L::real;
{L = 0.03602197445}, {L = -0.03602197445}

Replacement of numbers

I am given three variables having finite values ( all are integers) m,n, r.
Now I need to do m<-r and n<-r ( assign m and n the value of r ) and I have read in "The Art of Computer Programming vol. 1 " that the operations can be combined as
m<-n<-r
But will the above statement not mean "assign m the value of n and then n the value of r".
Thanks in advance.
The order of assignment is from right to left. Thus, m<-n<-r will be interpreted as: n<-r and then m<-n.
Since n equals r after the first assignment, m<-n and m<-r are identical.
Assignment = operator is like assigning the right side value to left side. For eg
int a = 1 + 2;
Here first 1+2 is evaluated and assigned to a because it follows right to left associativity.
Now if you have something like this
int a=b=2;
It again follows right to left associativity. From right first b=2 is evaluated and assign 2 to b then b is assigned to a. It works like this a=(b=2)
Know in your question you have m<-n<-r . This will work like this m<-(n<-r)
You can see reference Operator Associativity

1-line try/catch equivalent in MATLAB

I have a situation in MATLAB where I want to try to assign a struct field into a new variable, like this:
swimming = fish.carp;
BUT the field carp may or may not be defined. Is there a way to specify a default value in case carp is not a valid field? For example, in Perl I would write
my $swimming = $fish{carp} or my $swimming = 0;
where 0 is the default value and or specifies the action to be performed if the assignment fails. Seems like something similar should exist in MATLAB, but I can't seem to find any documentation of it. For the sake of code readability I'd rather not use an if statement or a try/catch block, if I can help it.
You can make your own function to handle this and keep the code rather clear. Something like:
swimming = get_struct(fish, 'carp', 0);
with
function v = get_struct(s, f, d)
if isfield(s, f)
v = s.(f); % Struct value
else
v = d; % Default value
end
Best,
From what I know, you can't do it in one line in MATLAB. MATLAB logical constructs require explicit if/else statements and can't do it in one line... like in Perl or Python.
What you can do is check to see if the fish structure contains the carp field. If it isn't, then you can set the default value to be 0.
Use isfield to help you do that. Therefore:
if isfield(fish, 'carp')
swimming = fish.carp;
else
swimming = 0;
end
Also, as what Ratbert said, you can put it into one line with commas... but again, you still need that if/else construct:
if isfield(fish,'carp'), swimming = fish.carp; else, swimming = 0;
Another possible workaround is to declare a custom function yourself that takes in a structure and a field, and allow it to return the value at the field, or 0.
function [out] = get_field(S, field)
if isfield(S, field)
out = S.(field);
else
out = 0;
end
Then, you can do this:
swimming = get_field(fish, 'carp');
swimming will either by 0, or fish.carp. This way, it doesn't sacrifice code readability, but you'll need to create a custom function to do what you want.
If you don't like to define a custom function in a separate function file - which is certainly a good option - you can define two anonymous functions at the beginning of your script instead.
helper = {#(s,f) 0, #(s,f) s.(f)}
getfieldOrDefault = #(s,f) helper{ isfield(s,f) + 1 }(s,f)
With the definition
fish.carp = 42
and the function calls
a = getfieldOrDefault(fish,'carp')
b = getfieldOrDefault(fish,'codfish')
you get for the first one
a = 42
and the previous defined default value for the second case
b = 0