Horizontal sundial calculations: Difference between revisions
Content added Content deleted
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
|||
Line 1,566: | Line 1,566: | ||
HR= 5; HRA= 75.500; HLA= -18.451 |
HR= 5; HRA= 75.500; HLA= -18.451 |
||
HR= 6; HRA= 90.500; HLA= -95.775</pre> |
HR= 6; HRA= 90.500; HLA= -95.775</pre> |
||
=={{header|jq}}== |
|||
{{works with|jq}} |
|||
'''Also works with gojq, the Go implementation of jq.''' |
|||
'''Adapted from [[#Wren|Wren]]''' |
|||
'''Generic Utilities''' |
|||
<syntaxhighlight lang=jq> |
|||
# `prompts` should be an array defining the prompts, variable names, and their types, |
|||
# as exemplified below. |
|||
# After all values have been gathered, `get` emits an object defining the bindings. |
|||
def get($prompts): |
|||
label $out |
|||
| foreach range(0;infinite) as $_ ({i:null, imax: ($prompts|length)}; |
|||
if .i == null then .i = 0 |
|||
elif .i == .imax then break $out |
|||
else .help = null |
|||
| first(inputs) as $n |
|||
| $prompts[.i].type as $type |
|||
| if $type == null or $type == "string" |
|||
then .result[$prompts[.i].key] = $n |
|||
| .i += 1 |
|||
elif $type == "number" |
|||
then (try ($n|tonumber) catch null) as $n |
|||
| if $n then .result[$prompts[.i].key] = $n |
|||
| .i += 1 |
|||
else .help = .i |
|||
end |
|||
elif $type == "integer" |
|||
then if ($n|test("^[0-9]+$")) |
|||
then .result[$prompts[.i].key] = ($n|tonumber) |
|||
| .i += 1 |
|||
else .help = .i |
|||
end |
|||
elif $type|type == "object" |
|||
then if $type.regex and ($n | test($type.regex)) |
|||
then .result[$prompts[.i].key] = $n |
|||
| .i += 1 |
|||
else .help = .i |
|||
end |
|||
else . |
|||
end |
|||
end; |
|||
(select(.help) | $prompts[.help].help // empty), |
|||
if .i < .imax then $prompts[.i].prompt |
|||
else .result |
|||
end ) |
|||
; |
|||
def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .; |
|||
def rpad($len): tostring | ($len - length) as $l | . + ("0" * $l)[:$l]; |
|||
# Input: a string of digits with up to one "." |
|||
# Output: the corresponding string representation with exactly $n decimal digits |
|||
def align_decimal($n): |
|||
tostring |
|||
| if index(".") |
|||
then capture("(?<i>[0-9]*[.])(?<j>[0-9]{0," + ($n|tostring) + "})") |
|||
| .i + (.j|rpad($n)) |
|||
else . + "." + ("0" * $n) |
|||
end ; |
|||
def pi: 4*(1|atan); |
|||
</syntaxhighlight> |
|||
'''The Task''' |
|||
<syntaxhighlight lang=jq> |
|||
def prompts: [ |
|||
{ prompt: "Enter latitude: ", key: "lat", type: "number", help: "in degrees"}, |
|||
{ prompt: "Enter longitude: ", key: "lng", type: "number", help: "in degrees"}, |
|||
{ prompt: "Enter legal meridian: ", key: "ref", type: "number", help: "in degrees"} |
|||
]; |
|||
def task: |
|||
get(prompts) |
|||
| if type != "object" then . # the prompts |
|||
else |
|||
((.lat * pi / 180)|sin) as $slat |
|||
| (.lng - .ref) as $diff |
|||
| "\n sine of latitude : \($slat)", |
|||
" diff longitude : \($diff)", |
|||
"\nHour, sun hour angle, dial hour line angle from 6am to 6pm", |
|||
(range(-6;7) as $h |
|||
| (15*$h - $diff) as $hra |
|||
| (($hra * pi /180)|sin) as $s |
|||
| (($hra * pi /180)|cos) as $c |
|||
| (atan2($slat*$s; $c) * 180 / pi) as $hla |
|||
| [$h|lpad(3)] + ([$hra, $hla] | map(align_decimal(3)|lpad(7))) | join(" ") ) |
|||
end; |
|||
task |
|||
</syntaxhighlight> |
|||
'''Invocation''': |
|||
The program handles user input errors provided the -R option is specified: |
|||
<pre> |
|||
jq -nRr -f horizontal-sundial-calculations.jq |
|||
</pre> |
|||
'''Transcript''' |
|||
<pre> |
|||
Enter latitude: |
|||
-4.95 |
|||
Enter longitude: |
|||
-150.5 |
|||
Enter legal meridian: |
|||
? |
|||
in degrees |
|||
Enter legal meridian: |
|||
-150 |
|||
sine of latitude : -0.08628636579792338 |
|||
diff longitude : -0.5 |
|||
Hour, sun hour angle, dial hour line angle from 6am to 6pm |
|||
-6 89.500 84.224 |
|||
-5 74.500 17.282 |
|||
-4 59.500 8.333 |
|||
-3 44.500 4.846 |
|||
-2 29.500 2.794 |
|||
-1 14.500 1.278 |
|||
0 0.500 0.043 |
|||
1 15.500 1.370 |
|||
2 30.500 2.909 |
|||
3 45.500 5.018 |
|||
4 60.500 8.671 |
|||
5 75.500 18.450 |
|||
6 90.500 95.775 |
|||
</pre> |
|||
=={{header|Julia}}== |
=={{header|Julia}}== |