Jump to content

Find the last Sunday of each month: Difference between revisions

Line 49:
 
<lang AppleScript>on run argv
-- Default range in absence of arguments: from two years ago, to two years ahead
-- Up to two optional command line arguments: [yearFrom], [yearTo]
-- ~ $ osascript ~/Desktop/lastSundays.scpt
--
-- ~ $ osascript ~/Desktop/lastSundays.scpt 2013
--
-- ~ $ osascript ~/Desktop/lastSundays.scpt 2013 2016
set intThisYear to year of (current date)
if class of argv is list then
set lngArgs to length of argv
if lngArgs > 0 then
if lngArgs > 1 then
set {intFrom, intTo} to argv
else
set intYear to item 1 of argv
set {intFrom, intTo} to {intYear, intYear}
end if
else
set {intFrom, intTo} to {intThisYear - 2, intThisYear + 2}
end if
else
set {intFrom, intTo} to {intThisYear - 2, intThisYear + 2}
end if
intercalate(linefeed, ¬
map(isoRow, ¬
transpose(map(lastSundaysOfYear, range(intFrom, intTo)))))¬
apply(cond(class of argv is list and argv ≠ {}, ¬
singleYearOrRange, fiveCurrentYears), argIntegers(argv))))))
end run
 
-- ARGUMENT HANDLING
 
-- Up to two optional command line arguments: [yearFrom], [yearTo]
-- (Default range in absence of arguments: from two years ago, to two years ahead)
 
-- ~ $ osascript ~/Desktop/lastSundays.scpt
-- ~ $ osascript ~/Desktop/lastSundays.scpt 2013
-- ~ $ osascript ~/Desktop/lastSundays.scpt 2013 2016
 
-- singleYearOrRange :: [Int] -> [Int]
on singleYearOrRange(argv)
apply(cond(length of argv > 0, my range, my fiveCurrentYears), argv)
end singleYearOrRange
 
-- fiveCurrentYears :: () -> [Int]
on fiveCurrentYears(_)
set intThisYear to year of (current date)
set {intFrom, intTo} to range({intThisYear - 2, intThisYear + 2})
end fiveCurrentYears
 
-- argIntegers :: maybe [String] -> [Int]
on argIntegers(argv)
if class of argv is list and argv ≠ {} then
{map(my parseInt, argv)}
else
else{}
--end if
end argIntegers
 
 
-- DERIVATION OF LAST SUNDAYS
Line 94 ⟶ 98:
-- lastWeekDaysOfYear :: Int -> Int -> [Date]
on lastWeekDaysOfYear(intYear, iWeekday)
map(mClosuremclosure(my lastWeekDay, ¬
{intYear:intYear, iWeekday:iWeekday}), my lastDaysOfMonths(intYear))
end lastWeekDaysOfYear
Line 111 ⟶ 115:
-- lastDaysOfMonths :: Int -> [Int]
on lastDaysOfMonths(y)
if{31, cond(isLeapYear(0 = y), mod29, 428), and31, (030, 31, y30, mod31, 100)31, or30, (031, = y mod 400)30, then31}
set iFeb to 29
else
set iFeb to 28
end if
{31, iFeb, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
end lastDaysOfMonths
 
-- isLeapYear :: Int -> Bool
on isLeapYear(y)
(0 = y mod 4) and (0 ≠ y mod 100) or (0 = y mod 400)
end isLeapYear
 
-- GENERIC FUNCTIONS
Line 142 ⟶ 144:
("0" & day of dte)
end isoDateString
 
-- parseInt :: String -> Int
on parseInt(s)
s as integer
end parseInt
 
-- Testing and tabulation
Line 149 ⟶ 156:
script mf
on lambdaCol(_, iCol)
map(mClosuremclosure(my closure's mf's lambdaRow, ¬
{iCol:iCol}), my closure's xss)
end lambdaCol
Line 157 ⟶ 164:
end lambdaRow
end script
map(mClosuremclosure(mf's lambdaCol, {xss:xss, mf:mf}), item 1 of xss)
end transpose
 
Line 174 ⟶ 181:
end isoRow
 
-- range :: (Int ->, Int) -> [Int]
on range(m, ntuple)
if tuple = {} then return {}
if length of tuple > 1 then
set lngArgs{m, n} to length of argvtuple
else
set intYear toreturn item 1 of argvtuple
--end if
set lng to (n - m) + 1
set base to m - 1
Line 184 ⟶ 197:
return lst
end range
 
 
-- Higher-order functions
Line 209 ⟶ 221:
 
-- Handler -> Record -> Script
on mClosuremclosure(f, recBindings)
script
property closure : recBindings
property lambda : f
end script
end mClosure</lang>mclosure
 
-- cond :: Bool -> (a -> b) -> (a -> b) -> (a -> b)
on cond(bool, f, g)
if lngArgs > 0bool then
f
else
g
end if
end cond
 
-- apply (a -> b) -> a -> b
on apply(f, a)
mReturn(f)'s lambda(a)
end apply
</lang>
 
{{Out}}
9,655

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.