Old Russian measure of length: Difference between revisions

Added AppleScript solutions.
m (→‎{{header|REXX}}: changed/add whitespace and comments, aligned statements.)
(Added AppleScript solutions.)
Line 59:
versta: 0.000937383
</pre>
 
=={{header|AppleScript}}==
===Vanilla===
 
<lang applescript>-- General purpose linear measurement converter.
on convertLinear(inputNumber, inputUnitRecord, outputUnitRecord)
set {inputType, outputType} to {inputUnitRecord's type, outputUnitRecord's type}
if (inputType is not outputType) then error "Unit type mismatch: " & inputType & ", " & outputType
-- The |offset| values are only relevant to temperature conversions and default to zero.
set inputUnit to inputUnitRecord & {|offset|:0}
set outputUnit to outputUnitRecord & {|offset|:0}
return (inputNumber - (inputUnit's |offset|)) * (inputUnit's coefficient) / (outputUnit's coefficient) ¬
+ (outputUnit's |offset|)
end convertLinear
 
on program(inputNumber, inputUnitName)
-- The task description only specifies these seven units, but more can be added if wished.
-- The coefficients are the equivalent lengths in metres.
set unitRecords to {{|name|:"metre", type:"length", coefficient:1.0}, ¬
{|name|:"centimetre", type:"length", coefficient:0.01}, {|name|:"kilometre", type:"length", coefficient:1000.0}, ¬
{|name|:"vershok", type:"length", coefficient:0.04445}, {|name|:"arshin", type:"length", coefficient:0.7112}, ¬
{|name|:"sazhen", type:"length", coefficient:2.1336}, {|name|:"versta", type:"length", coefficient:1066.8}}
-- Massage the given input unit name if necessary.
if (inputUnitName ends with "s") then set inputUnitName to text 1 thru -2 of inputUnitName
if (inputUnitName ends with "meter") then set inputUnitName to (text 1 thru -3 of inputUnitName) & "re"
-- Get the record with the input unit name from 'unitRecords'.
set inputUnitRecord to missing value
repeat with thisRecord in unitRecords
if (thisRecord's |name| is inputUnitName) then
set inputUnitRecord to thisRecord's contents
exit repeat
end if
end repeat
if (inputUnitRecord is missing value) then error "Unrecognised unit name: " & inputUnitName
-- Guess the user's spelling preference from the short-date order configured on their machine.
tell (current date) to set {Feb1, its day, its month, its year} to {it, 1, 2, 3333}
set USSpelling to (Feb1's short date string's first word as integer is 2)
-- Convert the input number to its equivalents in all the specified units, rounding to eight decimal
-- places and getting integer values as AS integers where possible. Pair the results with the unit names.
set output to {}
repeat with thisRecord in unitRecords
set outputNumber to convertLinear(inputNumber, inputUnitRecord, thisRecord)
set outputNumber to outputNumber div 1 + ((outputNumber * 100000000 mod 100000000) as integer) / 100000000
if (outputNumber mod 1 is 0) then set outputNumber to outputNumber div 1
set outputUnitName to thisRecord's |name|
if ((outputUnitName ends with "metre") and (USSpelling)) then ¬
set outputUnitName to (text 1 thru -3 of outputUnitName) & "er"
if (outputNumber is not 1) then set outputUnitName to outputUnitName & "s"
set end of output to {outputNumber, outputUnitName}
end repeat
return output -- {{number, unit name}, … }
end program
 
on demo()
set output to {}
set astid to AppleScript's text item delimiters
repeat with input in {{1, "kilometre"}, {1, "versta"}}
set {inputNumber, inputUnitName} to input
set end of output to (inputNumber as text) & space & inputUnitName & " is:"
set conversions to program(inputNumber, inputUnitName)
set AppleScript's text item delimiters to space
repeat with thisConversion in conversions
set thisConversion's contents to thisConversion as text
end repeat
set AppleScript's text item delimiters to "; "
set end of output to conversions as text
end repeat
set AppleScript's text item delimiters to linefeed
set output to output as text
set AppleScript's text item delimiters to astid
return output
end demo
 
return demo()</lang>
 
{{output}}
<lang applescript>"1 kilometre is:
1000 metres; 100000 centimetres; 1 kilometre; 2.249718785152E+4 vershoks; 1406.07424072 arshins; 468.69141357 sazhens; 0.93738283 verstas
1 versta is:
1066.8 metres; 106680 centimetres; 1.0668 kilometres; 24000 vershoks; 1500 arshins; 500 sazhens; 1 versta"</lang>
 
===AppleScriptObjC===
 
<lang applescript>use AppleScript version "2.5" -- macOS 10.12 (Sierra) or later. Not 10.11 (El Capitan).
use framework "Foundation"
use scripting additions
 
property |⌘| : current application
 
-- Return a custom NSUnit with a linear converter.
on customNSUnit(unitClassName, symbol, coefficient, |offset|)
set converter to |⌘|'s class "NSUnitConverterLinear"'s alloc()'s initWithCoefficient:(coefficient) |constant|:(|offset|)
return |⌘|'s class unitClassName's alloc()'s initWithSymbol:(symbol) converter:(converter)
end customNSUnit
 
on program(inputNumber, inputUnitName)
-- The task description only specifies these seven units, but more can be added if wished.
-- The base unit of the NSUnitLength class is 'meters'.
set unitRecords to {{|name|:"metre", NSUnit:|⌘|'s class "NSUnitLength"'s |meters|()}, ¬
{|name|:"centimetre", NSUnit:|⌘|'s class "NSUnitLength"'s |centimeters|()}, ¬
{|name|:"kilometre", NSUnit:|⌘|'s class "NSUnitLength"'s |kilometers|()}, ¬
{|name|:"vershok", NSUnit:customNSUnit("NSUnitLength", "vershok", 0.04445, 0)}, ¬
{|name|:"arshin", NSUnit:customNSUnit("NSUnitLength", "arshin", 0.7112, 0)}, ¬
{|name|:"sazhen", NSUnit:customNSUnit("NSUnitLength", "sazhen", 2.1336, 0)}, ¬
{|name|:"versta", NSUnit:customNSUnit("NSUnitLength", "versta", 1066.8, 0)}}
-- Massage the given input unit name if necessary.
if (inputUnitName ends with "s") then set inputUnitName to text 1 thru -2 of inputUnitName
if (inputUnitName ends with "meter") then set inputUnitName to (text 1 thru -3 of inputUnitName) & "re"
-- Get the record with the input unit name from 'unitRecords'.
set filter to |⌘|'s class "NSPredicate"'s predicateWithFormat_("name == %@", inputUnitName)
set filteredList to ((|⌘|'s class "NSArray"'s arrayWithArray:(unitRecords))'s filteredArrayUsingPredicate:(filter)) as list
if (filteredList is {}) then error "Unrecognised unit name: " & inputUnitName
set inputUnitRecord to beginning of filteredList
-- Set up an NSMeasurement using the input number and the NSUnit from the record.
set inputMeasurement to |⌘|'s class "NSMeasurement"'s alloc()'s ¬
initWithDoubleValue:(inputNumber) unit:(inputUnitRecord's NSUnit)
-- Get equivalent NSMeasurements in all the specified units and format them as text using an NSMeasurementFormatter
-- configured to use the measurements' own units instead of local equivalents and, in the case of the three preset units,
-- to include the full words, localised and pluralised as appropriate, instead of the symbols "m", "cm", or "km".
set output to {}
set measurementFormatter to |⌘|'s class "NSMeasurementFormatter"'s new()
tell measurementFormatter to setUnitOptions:(|⌘|'s NSMeasurementFormatterUnitOptionsProvidedUnit)
tell measurementFormatter to setUnitStyle:(|⌘|'s NSFormattingUnitStyleLong)
repeat with thisRecord in unitRecords
set outputMeasurement to (inputMeasurement's measurementByConvertingToUnit:(thisRecord's NSUnit))
set formattedMeasurement to (measurementFormatter's stringFromMeasurement:(outputMeasurement)) as text
if not ((outputMeasurement's doubleValue() is 1) or (thisRecord's |name| ends with "metre")) then ¬
set formattedMeasurement to formattedMeasurement & "s"
set end of output to formattedMeasurement
end repeat
return output -- {formatted text, … }
end program
 
on demo()
considering numeric strings
if ((system info)'s system version < "10.12") then ¬
error "El Capitan doesn't support the Foundation framework's Units and Measurement system"
end considering
set output to {}
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to "; "
repeat with input in {{1, "kilometre"}, {1, "versta"}}
set {inputNumber, inputUnitName} to input
set end of output to (inputNumber as text) & space & inputUnitName & " is:"
set end of output to program(inputNumber, inputUnitName) as text
end repeat
set AppleScript's text item delimiters to linefeed
set output to output as text
set AppleScript's text item delimiters to astid
return output
end demo
 
return demo()</lang>
 
{{output}}
<lang applescript>"1 kilometre is:
1,000 metres; 100,000 centimetres; 1 kilometre; 22,497.188 vershoks; 1,406.074 arshins; 468.691 sazhens; 0.937 verstas
1 versta is:
1,066.8 metres; 106,680 centimetres; 1.067 kilometres; 24,000 vershoks; 1,500 arshins; 500 sazhens; 1 versta"</lang>
 
=={{header|AWK}}==
557

edits