Calculate the ideal weight of your boa constrictor (logarithms in bash & bc)
Linux - GeneralThis Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Calculate the ideal weight of your boa constrictor (logarithms in bash & bc)
Perhaps there are more Linux users who have boa constrictors (or maybe there are snake owners looking for an excuse to install bash, or an OS with bash) who would like to know what their snake is supposed to weigh, according to its length.
Constrictors, like many animals, have a cubic length/weight ratio, which tends to remain fairly tightly related as the animal grows. I have only ever seen one location on the net that goes into exceptional detail on this subject, and it's here: http://crinaustin.home.att.net/ and the weight calculation I have used in my script is from this page: http://home.att.net/~crinaustin/BoaHerpetoculture.htm where you can see a few graphs showing the length/weight ratio on a logarithmic scale (and where you can double-check that the results from my script appear close enough to trust).
Yes, you can do this with a half-decent desk calculator too, but now you don't need to remember HOW to do it and I got to play around with bc, the "basic calculator", which I have been meaning to learn a bit about.
Here it is:
Code:
#!/bin/bash
# calculate boa constrictor ideal weight per given length.
#
# Feel free to leave suggestions for improvement.
#
# Inspired by: http://home.att.net/~crinaustin/BoaHerpetoculture.htm
# Script by GrapefruiTgirl (LQ) -- presently at crawlingwithsnakes at hush dot com
# November 2009 - GPL licensed.
# Thanks to fellow LQ members for their interest & input.
error () {
cat << EOF
Something wrong with your input.
Supply a numeric or floating-point value, suffixed with i,f,m, or c
to indicate inches, feet, meters, centimeters.
Examples: 48i, 7f, 2.2m, 186c
EOF
exit 1
}
echo -en "\nEnter length of snake (examples: 48i, 7f, 2.2m, 186c) > "
read length
[ ! "$(echo "$length" | gawk '/[0-9.][fmic]$/{print}')" ] && error
units=$(echo "$length" | grep -o [[:alpha:]])
length=$(echo "$length" | sed 's/[[:alpha:]]$//')
case $units in
m) length=$(echo "scale = 3; $length*3.2808399" | bc -l) ;;
i) length=$(echo "scale = 3; $length*0.0833333333" | bc -l) ;;
c) length=$(echo "scale = 3; $length*0.032808399" | bc -l) ;;
esac
weight_kgs=$(echo "scale = 3; e(3.216*l($length)-3.537)" | bc -l)
upper_weight_kgs=$(echo "scale = 3; $weight_kgs*1.15" | bc -l)
lower_weight_kgs=$(echo "scale = 3; $weight_kgs*0.85" | bc -l)
weight_lbs=$(echo "scale = 3; $weight_kgs*2.2046" | bc -l)
upper_weight_lbs=$(echo "scale = 3; $weight_lbs*1.15" | bc -l)
lower_weight_lbs=$(echo "scale = 3; $weight_lbs*0.85" | bc -l)
echo -e "\nUpper limit weight: \t$upper_weight_lbs lbs. \t($upper_weight_kgs kg.)"
echo -e "Ideal weight: \t\t$weight_lbs lbs. \t($weight_kgs kg.)"
echo -e "Lower limit weight: \t$lower_weight_lbs lbs. \t($lower_weight_kgs kg.)"
exit 0
As always, suggestions are welcome.
Sasha
Last edited by GrapefruiTgirl; 11-18-2009 at 10:46 PM.
Reason: new version -- better (correct?) formulae and more input units
Distribution: Solaris 9 & 10, Mac OS X, Ubuntu Server
Posts: 1,189
Rep:
Man, you are one weird girl.
Reminds me of way back when I wrote a little program on a mainframe to calculate the gear ratios for my road bike. Determined which gears I could pass over to get smoother acceleration.
shopt -s extglob
case "$inches" in
+([0-9])*(.)*([0-9]) )
echo 'DEBUG: cool'
;;
* )
echo "What are you thinking of, length '$inches' inches!" >&2
\exit 1
esac
This assumes the minimum length of a boa constrictor is at least 1" and does not otherwise test minimum and maximum length (so you can have more fun with bc doing that).
BTW, I haven't given up on your hibernate script -- just been busy with other things.
@ catkin -- I haven't given up on the hibernate script either, but have been occupied with other stuff here at home. And yes, some sanity checking is a worthwhile addition, perhaps for "constrictor weight Ver II" :-) And, the minimum length would be more like about 16" while a maximum of maybe 13 feet (while extreme) would be a good upper limit.
@ BrianL -- NO snakies through the fan!! :/
@ Ghostdog -- Doing it entirely with bc would likely make more sense; using bash to invoke bc is as we can see, kinda loopy. A bc script would likely be much cleaner.
@ Choogendyke -- Heh I've been called worse! I can live with 'weird' I'd bet if, back when you wrote your gear ratio script, it got to the internet, *someone* out there would be interested in it, out of curiosity if nothing else. So, maybe we will see an increase in snake people visiting LQ!
I hope you don't mind me finding this amusing, but it really cheered me up to see something so obviously useful that I'd never thought of.
More seriously, I'd give consideration to allowing the length input in inches or metres, maybe by invoking the script with a -m (metric) or -i (inches or imperial), but then maybe you never use metric for length measurement...I'm guessing that you'd make inches the default.
And thanks again for posting this; I always struggle with the syntax for BC, so this is a good reminder.
I hope you don't mind me finding this amusing, but it really cheered me up to see something so obviously useful that I'd never thought of.
More seriously, I'd give consideration to allowing the length input in inches or metres, maybe by invoking the script with a -m (metric) or -i (inches or imperial), but then maybe you never use metric for length measurement...I'm guessing that you'd make inches the default.
And thanks again for posting this; I always struggle with the syntax for BC, so this is a good reminder.
Hi salasi,
No, I don't mind if amusing is how you find this -- I'm glad you found it entertaining.
As to the metric vs imperial, there are several reasons it is the way it is: I personally am comfortable with either, in most situations, but:
1) for weights, pounds is more meaningful to me; I don't have as good a grip on someone weighing "74.3 Kg" as I do if they say "145 Lbs". That said, for the benefit of the kilogrammers out there, I did the easy conversion and provided dual output.
2) The data provided on the website where I got the idea & formula from, was in inches & pounds, mostly.
3) Measuring a living object is not easy, a snake no less! Trying to get them to lie still AND straight as an arrow is nearly impossible . Let's say a 9 foot snake, that's a LOT of centimeters. Inches are a much easier unit for such a measurement IMHO -- you get a smaller number of them, plus they are easier to read on the average tape.
I DID have the thought last night, to allow input in a suffixed format like so:
145c (centimeters) 2.1m (meters) 86i (inches)
.. and may yet allow that, just for the sheer hilarity of it
I might be missing something but your math does not work for me. It is possible to calculate a decimal exponent using logs. i.e.
x^3.216=e^(3.216 * ln(x))
or
final=$(echo "e(3.216*l($feet))" | bc -l)
As a quick sample for those not math inclined.
4=sqrt(16)=16^0.5
echo "e(.5*l(16) )" | bc -l
3.99999999999999999998
Aha!!
I have been waiting for *someone* to address the decimal exponentation issue. Thank you Michael
It's more likely that I am missing something, not you; my method of stuffing the values in the equation into bc are admittedly not 'normal'.
The formulae on the page that I get this from, did show how to do it using log(x) but I could not figure out the bc syntax of the log function, the e bit. Now that I see how it's done, I can revisit the butchery way I did it.
Hopefully you will be able to take a moment sometime in the near future to have a look at some calculations I am working on; maybe I'll post some stuff tonight, though I'm into a few other things at this monent.
OK, so in the script, I used Equation #3 from the link below, because I couldn't figure out the ln(x) bit. Now that I think I have that part down, here's where it's at:
sasha@reactor:~$ echo "3.216*l(4)-3.537" | bc -l
.92132266536156823015
At this point, I get stymied; what to do with this result, to get the Kgs?
PS - it should be noted that while I did very well in mathematics in school, I find the online reference pages for log functions positively cryptic. Maybe I'm getting older than I think I am :/
Last edited by GrapefruiTgirl; 11-18-2009 at 07:58 PM.
Awesome the inverse is the missing link. To simplify (wow this will make the whole script so much better) the following works nicely:
echo "e(3.216*l(3)-3.537)" | bc -l #where the underlined "3" in the middle represents 3 foot snake.
At a glance, the results are difficult to compare to the graph at the image I linked, because of the logarithmic nature of the scales on the graph. But the results look reasonable. I must measure+weigh my snake to see how her weight compares to this formula.
I'll have to re-write the script thanks very much michaelk!!
Sasha
Last edited by GrapefruiTgirl; 11-18-2009 at 08:39 PM.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.