help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Calculation


From: Greg Wooledge
Subject: Re: Calculation
Date: Sun, 20 Jun 2021 12:56:32 -0400

On Sun, Jun 20, 2021 at 06:35:39PM +0200, Silvio Siefke wrote:
> At end I use a script for the job. The size of the construction sites 
> are loaded in an array. With the sizes, the materials are calculated 
> and at the end calculated together and also calculated on the square 
> meter. All results are written to a CSV file.

> size.txt
> 90.25
> 50.58
> 59.74
> 12.80
> 10.80
> 98.58
> 15.60
> 39.36
> 20.15
> 825.69
> 1080.96
> 2087.69
> 5074.80

OK, this is helpful.

> # the size read in to an array
> readarray -t size < /home/siefke/Downloads/size.txt
> 
> # loop goes over the array and start calculate
> for i in "${size[@]}"; do

You're never using more than one "size" value at a time, so the array
isn't really necessary.  However, since the file is small (you said
it's about 100 lines), holding it in memory is fine.

> # deciamal numbers round up to single number
> round_days=$(concalc "$i"/150 | awk '{print 
> ($0-int($0)<0.499)?int($0):int($0)+1}')
> round_sand=$(concalc "$i*0.04*1,8" | awk '{print 
> ($0-int($0)<0.499)?int($0):int($0)+1}')
> round_cement=$(concalc "$i*0.04*15" | awk '{print 
> ($0-int($0)<0.499)?int($0):int($0)+1}')
> round_adhesive_bridge=$(concalc "$i*1.5/25" | awk '{print 
> ($0-int($0)<0.499)?int($0):int($0)+1}')
> round_edgestripes=$(concalc "$i*1.5/50" | awk '{print 
> ($0-int($0)<0.499)?int($0):int($0)+1}')

You're still using this really convoluted awk command to do rounding,
and the rounding you're doing isn't quite correct.  Nor does it match
the comments.

The comment says "round up", but that's not what you're doing.  You're
not even rounding normally, because for some reason you're treating 0.499
as a value to be rounded up, rather than down.

Finally, I still have no idea what "concalc" does.  Is it simply performing
the arithmetic specified in a single argument?  I.e. for the first one:

concalc "$i/150"

Is it simply dividing $i by 150, and then writing the result to stdout?

If that's the case, you can do the whole thing in awk, including the
rounding, and do the rounding *properly* at the same time, with a lot
less code.

awk '
  {days = $1/150.0; sand = $1*0.04*1.8; cement = $1*0.04*15;
   bridge = $1*1.5/25; edgestripes = $1*1.5/50;
   printf("%.0f,%.0f,%.0f,%.0f,%.0f\n",
     days, sand, cement, bridge, edgestripes)
  }
' size.txt

And with the input size.txt file that you specified, here's the output
that I get:

1,6,54,5,3
0,4,30,3,2
0,4,36,4,2
0,1,8,1,0
0,1,6,1,0
1,7,59,6,3
0,1,9,1,0
0,3,24,2,1
0,1,12,1,1
6,59,495,50,25
7,78,649,65,32
14,150,1253,125,63
34,365,3045,304,152

(Additional calculations snipped.)

You can move the rest of the calculations into the awk program, and add
however many additional %.0f fields you require in the printf command,
which is what's doing the rounding.

Bash isn't actually helping you very much here, because it can't do
floating point arithmetic.  So you might as well write the whole thing
in awk, which can easily do everything required for this project.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]