bash arithmetic expressions with variables - bash

I am having troubles with the arithmetic expressions in a bash file (a unix file .sh).
I have the variable "total", which consists of a few numbers separated by spaces, and I want to calculate the sum of them (in the variable "dollar").
#!/bin/bash
..
dollar=0
for a in $total; do
$dollar+=$a
done
I know I am missing something with the arithmetic brackets, but I couldn't get it to work with variables.

Wrap arithmetic operations within ((...)):
dollar=0
for a in $total; do
((dollar += a))
done

There are a number of ways to perform arithmetic in Bash. Some of them are:
dollar=$(expr $dollar + $a)
let "dollar += $a"
dollar=$((dollar + a))
((dollar += a))
You may see more on the wiki. If you need to handle non-integer values, use a external tool such as bc.

Related

What does an 'at' # sign mean in Julia?

For example, here:
ys = lift(frequency, phase) do fr, ph
#. 0.3 * sin(fr * xs - ph)
end
from here.
I am failing to interpret it as a macro definition or call.
TLDR: # invokes a macro. https://docs.julialang.org/en/v1/manual/metaprogramming/
One of julia's best features in my opinion are it's macros. They allow you to easily write functions that manipulate source code. #. for example turns 0.3 * sin(fr * xs - ph) into 0.3 .* sin(fr .* xs - ph). Another common example is #time which roughly would translate the same expression to
t1=time()
0.3 * sin(fr * xs - ph)
println(time()-t1)
Note that neither of these are achievable by a function, since functions have their inputs evaluated before they run, while macros instead operate on the code itself.
I think it is worth to add that it is easy to learn what #. does by invoking help. Press ? then write #. and hit enter to get:
help?> #.
#. expr
Convert every function call or operator in expr into a "dot call" (e.g.
convert f(x) to f.(x)), and convert every assignment in expr to a "dot
assignment" (e.g. convert += to .+=).
If you want to avoid adding dots for selected function calls in expr, splice
those function calls in with $. For example, #. sqrt(abs($sort(x))) is
equivalent to sqrt.(abs.(sort(x))) (no dot for sort).
(#. is equivalent to a call to #__dot__.)
Examples
≡≡≡≡≡≡≡≡≡≡
julia> x = 1.0:3.0; y = similar(x);
julia> #. y = x + 3 * sin(x)
3-element Array{Float64,1}:
3.5244129544236893
4.727892280477045
3.4233600241796016
where you also learn that #. is just a shorthand for #__dot__.
And if you want to find its definition write e.g.:
julia> #which #. 1
#__dot__(__source__::LineNumberNode, __module__::Module, x) in Base.Broadcast at broadcast.jl:1241
to get the exact information on location of its implementation or write #edit #. 1 and it will get opened-up in your editor.
Above I have commented on how to learn what #. does and how it is implemented. If you want to learn what is the effect of #. (or any macro in general) you can use the #macroexpand macro. Therefore if you write e.g.:
julia> #macroexpand #. coalesce(sin(#view x[:, 1]), 0.0)
:(coalesce.(sin.(true && (view)(x, :, 1)), 0.0))
you can see how #. macro rewrites your original expression coalesce(sin(x), 0.0). Note that in this case the expressions are not evaluated - you only get an equivalent expression with all macros removed.
If you wanted to see only #. macro expanded (assuming - as in an example above it is the outermost macro) then use:
julia> #macroexpand1 #. coalesce(sin(#view x[:, 1]), 0.0)
:(coalesce.(sin.(#= REPL[11]:1 =# #view(x[:, 1])), 0.0))
As you can see #macroexpand1 is not recursive and only expanded the outermost macro and left #view macro untouched.

What does this variable notation mean ? a[++b]=$c

I have seen this notation in bash:
a=${b[c--]}
or also
a[++b]=$c
or the other way around:
a[b++]=$c
but if I execute it on the command line nothing happens.
OSX#26:~ $ a[++b]=2
OSX#27:~ $ echo ${a[++b]}
OSX#28:~ $
What is the use of this notation ?
Edit:
I am asking about this notation. As I have seen it it is a variable, because of the $ in front. But ++ does remind me of increment, so I am confused. Is this some sort of variable increment ?
c-- is an arithmetic expression, it means "return the value of c and then decrement it by 1". ${b[n]} denotes the n-th element of the array b (where the first element has index 0). Expressions inside the square brackets are interpreted as arithmetic (with some exceptions like *, #, '1' etc.) Let's try it:
b=(x y z)
c=2
a=${b[c--]}
echo $a $c # Outputs: z 1
so c-- returns 2, but sets c to 1. b[2], i.e. z, is then assigned to a.
++c is similar to c--, but it adds 1 to c before returning its value.

How do you make a range in bash case sensitive?

I'm trying to use a for loop like this, where the range consists of letters, both uppercase and lowercase. The problem is, bash doesn't differentiate uppercase and lowercase when it's within a range. How do I make it case sensitive? TIA.
for s in {a..z,A..Z}
do
echo ${s}
done
If you want the letters in that order, just use:
for s in {a..z} {A..Z}
There's no requirement that bash only allows a single brace expansion per line.
The two forms currently allowed are mutually exclusive, being either a selection (of two or more) or a range:
{<val1>,<val2>[,...]}
{<from>..<to>[..<incr>]}
The brace expression {a..z,A..Z} simply expands, using the first form, to the two words (not ranges):
a..z
A..Z
Looks like you got the syntax wrong.
$ echo $BASH_VERSION
3.2.25(1)-release
$ echo {a..k} {A..K}
a b c d e f g h i j k A B C D E F G H I J K
$ echo {a..k,A..K}
a..k A..K

Evaluation functions and expressions in Boolean expressions

I am aware how we can evaluate an expression after converting into Polish Notations. However I would like to know how I can evaluate something like this:
If a < b Then a + b Else a - b
a + b happens in case condition a < b is True, otherwise, if False a - b is computed.
The grammar is not an issue here. Since I only need the algorithm to solve this problem. I am able evaluate boolean and algebraic expressions. But how can I go about solving the above problem?
Do you need to assign a+b or a-b to something?
You can do this:
int c = a < b ? a+b : a-b;
Or
int sign = a < b ? 1 : -1;
int c = a + (sign * b);
Refer to LISP language for S-express:
e.g
(if (> a b) ; if-part
(+ a b) ; then-part
(- a b)) ; else-part
Actually if you want evaluate just this simple if statement, toknize it and evaluate it, but if you want to evaluate somehow more complicated things, like nested if then else, if with experssions, multiple else, variable assignments, types, ... you need to use some parser, like LR parsers. You can use e.g Lex&Yacc to write a good parser for your own language. They support somehow complicated grammars. But if you want to know how does LR parser (or so) works, you should read into them, and see how they use their table to read tokens and parse them. e.g take a look at wiki page and see how does LR parser table works (it's something more than simple stack and is not easy to describe it here).
If your problem is just really parsing if statement, you can cheat from parser techniques, you can add empty thing after a < b, which means some action, and empty thing after else, which also means an action. When you parsed the condition, depending on correctness or wrongness you will run one of actions. By the way if you want to parse expressions inside if statement you need conditional stack, means something like SLR table.
Basically, you need to build in support for a ternary operator. IE, where currently you pop an operator, and then wait for 2 sequential values before resolving it, you need to wait for 3 if your current operation is IF, and 2 for the other operations.
To handle the if statement, you can consider the if statement in terms of C++'s ternary operator. Which formats you want your grammar to support is up to you.
a < b ? a + b : a - b
You should be able to evaluate boolean operators on your stack the way you currently evaluate arithmetic operations, so a < b should be pushed as
< a b
The if can be represented by its own symbol on the stack, we can stick with '?'.
? < a b
and the 2 possible conditions to evaluate need to separated by another operator, might as well use ':'
? < a b : + a b - a b
So now when you pop '?', you see it is the operator that needs 3 values, so put it aside as you normally would, and continue to evaluate the stack until you have 3 values. The ':' operator should be a binary operator, that simply pushes both of its values back onto the stack.
Once you have 3 values on the stack, you evaluate ? as:
If the first value is 1, push the 2nd value, throw away the third.
If the first value is 0, throw away the 2nd and push the 3rd.

Passing parameters stored in a list to expression

How can I pass values to a given expression with several variables? The values for these variables are placed in a list that needs to be passed into the expression.
Your revised question is straightforward, simply
f ## {a,b,c,...} == f[a,b,c,...]
where ## is shorthand for Apply. Internally, {a,b,c} is List[a,b,c] (which you can see by using FullForm on any expression), and Apply just replaces the Head, List, with a new Head, f, changing the function. The operation of Apply is not limited to lists, in general
f ## g[a,b] == f[a,b]
Also, look at Sequence which does
f[Sequence[a,b]] == f[a,b]
So, we could do this instead
f[ Sequence ## {a,b}] == f[a,b]
which while pedantic seeming can be very useful.
Edit: Apply has an optional 2nd argument that specifies a level, i.e.
Apply[f, {{a,b},{c,d}}, {1}] == {f[a,b], f[c,d]}
Note: the shorthand for Apply[fcn, expr,{1}] is ###, as discussed here, but to specify any other level description you need to use the full function form.
A couple other ways...
Use rule replacement
f /. Thread[{a,b} -> l]
(where Thread[{a,b} -> l] will evaluate into {a->1, b->2})
Use a pure function
Function[{a,b}, Evaluate[f]] ## l
(where ## is a form of Apply[] and Evaluate[f] is used to turn the function into Function[{a,b}, a^2+b^2])
For example, for two elements
f[l_List]:=l[[1]]^2+l[[2]]^2
for any number of elements
g[l_List] := l.l
or
h[l_List]:= Norm[l]^2
So:
Print[{f[{a, b}], g[{a, b}], h[{a, b}]}]
{a^2 + b^2, a^2 + b^2, Abs[a]^2 + Abs[b]^2}
Two more, just for fun:
i[l_List] := Total#Table[j^2, {j, l}]
j[l_List] := SquaredEuclideanDistance[l, ConstantArray[0, Length[l]]
Edit
Regarding your definition
f[{__}] = a ^ 2 + b ^ 2;
It has a few problems:
1) You are defining a constant, because the a,b are not parameters.
2) You are defining a function with Set, Instead of SetDelayed, so the evaluation is done immediately. Just try for example
s[l_List] = Total[l]
vs. the right way:
s[l_List] := Total[l]
which remains unevaluated until you use it.
3) You are using a pattern without a name {__} so you can't use it in the right side of the expression. The right way could be:
f[{a_,b_}]:= a^2+b^2;

Resources