Friday Challenge - Christmas Style
Last year I did a few Christmas style friday challenges, so I'm a bit overdue. This one is rather simple. Given a query that contains an ID, which corresponds to a day, and a gift, print out the famous "12 Days of Christmas" song dynamically. Ie, day 1 you get gift 1. Day 2 you get 1 of gift 1, and 2 of gift 2. And so on.
Bonus points if you use festive green and red fonts in your display. (Once again, this is why they don't let me design.)
Double bonus points if you make a cfpresentation out it and record MP3s to go along with it.
Here is your query that you must use with the code. (Note, it uses CF8 Array shorthand style. If you aren't on CF8, you can rewrite that as a list and use listToArray.)
<cfset song = querynew("id,gift","integer,varchar")>
<cfset gifts = ["A partridge in a pear tree","Two turtle doves","Three French hens","Four calling birds","Five golden rings","Six geese a-laying",
"Seven swans a-swimming","Eight maids a-milking","Nine ladies dancing","Ten lords a-leaping","Eleven pipers piping","Twelve drummers drumming"]>
<cfloop index="x" from="1" to="#arrayLen(gifts)#">
<cfset queryAddRow(song)>
<cfset querySetCell(song, "id", x)>
<cfset querySetCell(song, "gift", gifts[x])>
</cfloop>
Comments
On the 1 day of christmas my true love gave to me:
<span style="color:green">A partridge in a pear tree</span> <br>
On the 2 day of christmas my true love gave to me:
<span style="color:red">Two turtle doves</span> <span style="color:green">A partridge in a pear tree</span> <br>
On the 3 day of christmas my true love gave to me:
<span style="color:green">Three French hens</span> <span style="color:red">Two turtle doves</span> <span style="color:green">A partridge in a pear tree</span> <br>
On the 4 day of christmas my true love gave to me:
<span style="color:red">Four calling birds</span> <span style="color:green">Three French hens</span> <span style="color:red">Two turtle doves</span> <span style="color:green">A partridge in a pear tree</span> <br>
On the 5 day of christmas my true love gave to me:
<span style="color:green">Five golden rings</span> <span style="color:red">Four calling birds</span> <span style="color:green">Three French hens</span> <span style="color:red">Two turtle doves</span> <span style="color:green">A partridge in a pear tree</span> <br>
On the 6 day of christmas my true love gave to me:
<span style="color:red">Six geese a-laying</span> <span style="color:green">Five golden rings</span> <span style="color:red">Four calling birds</span> <span style="color:green">Three French hens</span> <span style="color:red">Two turtle doves</span> <span style="color:green">A partridge in a pear tree</span> <br>
On the 7 day of christmas my true love gave to me:
<span style="color:green">Seven swans a-swimming</span> <span style="color:red">Six geese a-laying</span> <span style="color:green">Five golden rings</span> <span style="color:red">Four calling birds</span> <span style="color:green">Three French hens</span> <span style="color:red">Two turtle doves</span> <span style="color:green">A partridge in a pear tree</span> <br>
On the 8 day of christmas my true love gave to me:
<span style="color:red">Eight maids a-milking</span> <span style="color:green">Seven swans a-swimming</span> <span style="color:red">Six geese a-laying</span> <span style="color:green">Five golden rings</span> <span style="color:red">Four calling birds</span> <span style="color:green">Three French hens</span> <span style="color:red">Two turtle doves</span> <span style="color:green">A partridge in a pear tree</span> <br>
On the 9 day of christmas my true love gave to me:
<span style="color:green">Nine ladies dancing</span> <span style="color:red">Eight maids a-milking</span> <span style="color:green">Seven swans a-swimming</span> <span style="color:red">Six geese a-laying</span> <span style="color:green">Five golden rings</span> <span style="color:red">Four calling birds</span> <span style="color:green">Three French hens</span> <span style="color:red">Two turtle doves</span> <span style="color:green">A partridge in a pear tree</span> <br>
On the 10 day of christmas my true love gave to me:
<span style="color:red">Ten lords a-leaping</span> <span style="color:green">Nine ladies dancing</span> <span style="color:red">Eight maids a-milking</span> <span style="color:green">Seven swans a-swimming</span> <span style="color:red">Six geese a-laying</span> <span style="color:green">Five golden rings</span> <span style="color:red">Four calling birds</span> <span style="color:green">Three French hens</span> <span style="color:red">Two turtle doves</span> <span style="color:green">A partridge in a pear tree</span> <br>
On the 11 day of christmas my true love gave to me:
<span style="color:green">Eleven pipers piping</span> <span style="color:red">Ten lords a-leaping</span> <span style="color:green">Nine ladies dancing</span> <span style="color:red">Eight maids a-milking</span> <span style="color:green">Seven swans a-swimming</span> <span style="color:red">Six geese a-laying</span> <span style="color:green">Five golden rings</span> <span style="color:red">Four calling birds</span> <span style="color:green">Three French hens</span> <span style="color:red">Two turtle doves</span> <span style="color:green">A partridge in a pear tree</span> <br>
On the 12 day of christmas my true love gave to me:
<span style="color:red">Twelve drummers drumming</span> <span style="color:green">Eleven pipers piping</span> <span style="color:red">Ten lords a-leaping</span> <span style="color:green">Nine ladies dancing</span> <span style="color:red">Eight maids a-milking</span> <span style="color:green">Seven swans a-swimming</span> <span style="color:red">Six geese a-laying</span> <span style="color:green">Five golden rings</span> <span style="color:red">Four calling birds</span> <span style="color:green">Three French hens</span> <span style="color:red">Two turtle doves</span> <span style="color:green">A partridge in a pear tree</span> <br>
<cfset gifts = ["A partridge in a pear tree","Two turtle doves","Three French hens","Four calling birds","Five golden rings","Six geese a-laying",
"Seven swans a-swimming","Eight maids a-milking","Nine ladies dancing","Ten lords a-leaping","Eleven pipers piping","Twelve drummers drumming"]>
<cfloop index="x" from="1" to="#arrayLen(gifts)#">
<cfset queryAddRow(song)>
<cfset querySetCell(song, "id", x)>
<cfset querySetCell(song, "gift", gifts[x])>
</cfloop>
<cfquery name="getSong" dbtype="query">
select *
from song
order by id desc
</cfquery>
<cfset title = "The 12 days of Christmas...">
<cfpresentation title="#title#">
<cfoutput query="getSong">
<cfsavecontent variable="slideTitle">On the #id#<cfif id eq 1>st<cfelseif id eq 3>rd<cfelseif id eq 2>nd<cfelse>th</cfif> day of Christmas my true love gave to me....</cfsavecontent>
<cfpresentationslide title="#slideTitle#">
<div>
<img src="christmas_lights.gif" /><br/>
<h1>#title#</h1>
<h2>#slideTitle#</h2>
<span>#getSong.gift#</span>
</div>
</cfpresentationslide>
</cfoutput>
</cfpresentation>
http://cfsilence.com/blog/demos/12days/12days.cfm
<CFSET IMGRoot = "http://www.dkferguson.com/12days">
<cfset song = querynew("id,gift","integer,varchar")>
<cfset gifts = ["A partridge in a pear tree","Two turtle doves","Three French hens","Four calling birds","Five golden rings","Six geese a-laying",
"Seven swans a-swimming","Eight maids a-milking","Nine ladies dancing","Ten lords a-leaping","Eleven pipers piping","Twelve drummers drumming"]>
<cfloop index="x" from="1" to="#arrayLen(gifts)#">
<cfset queryAddRow(song)>
<cfset querySetCell(song, "id", x)>
<cfset querySetCell(song, "gift", gifts[x])>
</cfloop>
<CFOUTPUT>
<CFLOOP INDEX="d" FROM="1" TO="12">
<DIV ID="day#d#" STYLE="width:100%; float:left;">
<CFQUERY NAME="getGifts" DBTYPE="QUERY">
select * from song where id <= #d#
order by id desc
</CFQUERY>
<BR><BR>
ON DAY #d# of Christmas I got all this stuff:<BR>
<CFLOOP QUERY="getGifts">
<DIV ID="gift#d##id#" STYLE="float:left;">
<IMG SRC="#IMGRoot#/#id#.jpg">
</DIV>
</CFLOOP>
</DIV>
</CFLOOP>
</CFOUTPUT>
<cffunction name="Dayify" returntype="query">
<cfargument name="Q" type="query" required="true">
<cfset var Result="">
<cfset var P=arguments.q>
<cfset var R=arguments.q>
<cfquery dbtype="query" name="Result">
SELECT r.id AS daynum, p.id AS id, p.gift AS gift
FROM r, p
WHERE (r.id >= p.id)
ORDER BY 1, 2 DESC, 3
</cfquery>
<cfreturn Result>
</cffunction>
<cffunction name="htmlFromSong" returntype="string">
<cfargument name="Q" type="query" required="true">
<cfset var Verses=Dayify(Q)>
<cfset var Result="">
<cfset var Colors=listToArray("red,green")>
<cfset var Suffixes="st,nd,rd">
<cfif Verses.recordCount gt 3>
<cfset Suffixes=listAppend(Suffixes,repeatString("th,",Verses.recordCount-3))>
</cfif>
<cfset suffixes=listToArray(suffixes)>
<cfsavecontent variable="Result">
<cfoutput query="Verses" group="DayNum">
<p>On the #DayNum#<sup>#Suffixes[DayNum]#</sup> day of Christmas, my true love gave to me: <cfoutput><cfif DayNum neq id>, <cfif id eq 1>and </cfif></cfif><span style="color:#Colors[incrementValue(id MOD 2)]#">#HTMLEditFormat(gift)#</span></cfoutput>.</p>
</cfoutput>
</cfsavecontent>
<cfreturn Result>
</cffunction>
<cfoutput>#htmlFromSong(Song)#</cfoutput>
<cfset song = querynew("id,gift","integer,varchar")>
<cfset gifts = ["A partridge in a pear tree","Two turtle doves","Three French hens","Four calling birds","Five golden rings","Six geese a-laying",
"Seven swans a-swimming","Eight maids a-milking","Nine ladies dancing","Ten lords a-leaping","Eleven pipers piping","Twelve drummers drumming"]>
<cfloop index="x" from="1" to="#arrayLen(gifts)#">
<cfset queryAddRow(song)>
<cfset querySetCell(song, "id", x)>
<cfset querySetCell(song, "gift", gifts[x])>
</cfloop>
<cffunction name="ord" access="public" returntype="string" output="false">
<cfargument name="theNum" type="string" required="true" />
<cfset theNewNum = "" />
<cfswitch expression="#arguments.theNum#">
<cfcase value="1">
<cfset theNewNum = arguments.theNum &'st' />
</cfcase>
<cfcase value="2">
<cfset theNewNum = arguments.theNum &'nd' />
</cfcase>
<cfcase value="3">
<cfset theNewNum = arguments.theNum &'rd' />
</cfcase>
<cfdefaultcase>
<cfset theNewNum = arguments.theNum &'th' />
</cfdefaultcase>
</cfswitch>
<cfreturn theNewNum />
</cffunction>
<cfoutput>
<cfset title="The 12 Days of Christmas" />
<cfpresentation title="The 12 Days of Christmas - stole this part from Todd thx">
<cfloop from="1" to="12" index="i">
<cfset slideTitle = "On the #ord(i)# day of christmas my true love brought to me" />
<cfpresentationSlide title="#slideTitle#" duration="2">
<div>
#title#<br />
#slideTitle#
<br /><br />
<cfloop from="12" to="1" index="j" step="-1">
<cfif j LTE i>
<cfif j MOD 2>
<cfset fColor = 'green' />
<cfelse>
<cfset fColor = 'red' />
</cfif>
<cfif j EQ 5>
<span style="letter-spacing:2.5em; color:#fColor#;">#song.gift[j]#</span><br />
<cfelse>
<span style="color:#fColor#;">#song.gift[j]#</span><br />
</cfif>
</cfif>
</cfloop>
</div>
</cfpresentationSlide>
<br /><br />
</cfloop>
</cfpresentation>
</cfoutput>
Looks like it can be very useful.
Mine didn't do this?
<cfscript>
function SingTheSong(level) {
if(level < 13) {
writeOutput('On the ' & level & ' day of christmas, my true love gave to me..<br>');
for(i = level; i neq 0; i=i-1){
if(i mod 2 gt 0){colour='red';} else {colour='green';}
writeOutput(' <span style="color:' & colour & ';">' & song.gift[i] & '</span><br>');
}
SingTheSong(level+1);
}
}
</cfscript>
<cfoutput>
#SingTheSong(1)#
</cfoutput>
<cfcomponent output="true">
<cfset this.gifts = ListToArray("A partridge in a pear tree,Two turtle doves and,Three French hens,Four calling birds,Five golden rings,Six geese a-laying,Seven swans a-swimming,Eight maids a-milking,Nine ladies dancing,Ten lords a-leaping,Eleven pipers piping,Twelve drummers drumming")>
<cfset this.days = ListToArray("first,second,third,fourth,fifth,sixth,seventh,eight,ninth,tenth,eleventh,twelfth")>
<cffunction name="down" access="remote" output="true" returntype="void">
<cfargument name="arrayPosition" default="1" />
#this.gifts[arguments.arrayPosition]#
<cfif arguments.arrayPosition gt 1>
, #down(arguments.arrayPosition-1)#
</cfif>
</cffunction>
<cffunction name="daysOfXmas" access="remote" output="true" returntype="void">
<cfloop from="1" to="12" index="eachDay">
On the #this.days[eachDay]# day of xmas, my true love gave to me<br>
#down(eachDay)#<br><br>
</cfloop>
</cffunction>
</cfcomponent>
http://blog.simb.net/2007/12/14/rays-christmas-cod...
Technically the part that outputs the song is 8 lines of code.
I mashed that up with my stuff and randomized the results for each slide:
http://cfsilence.com/blog/demos/12days/yahoo/index...
(Oh and for the cfpresentation fans - rather then re-create the preso on the fly I took advantage of the directory attribute and wrote it to disk)
<div style="width: 400px; font: .9em/1.8em Georgia, 'Times New Roman', Times, serif; padding: 30px;">
<cfoutput>
<cfloop from="1" to="#arrayLen(gifts)#" index="j">
<div style="padding: 20px 0; border-bottom: 1px solid ##ccc; color: green;">
<em style="color: red;">On the #j# day of Christmas, my true love gave to me,</em><br />
<cfloop from="#j#" to="1" index="k" step="-1">
<cfif (j gte 2 and k eq 1)>
and
</cfif>
#song.gift[k]#<br />
</cfloop>
</div>
</cfloop>
</cfoutput>
</div>


Here is my "solution". It's not elegant or pretty (thanks in part to the colors) but it works :). I loop through the query and through each loop I pass the query and the day a function which then loops through the function and outputs the song as its sung (in reverse).
<cffunction name="song2" output="true" >
<cfargument name="x" type="numeric" required="true">
<cfargument name="q" type="query" required="true">
<cfloop from="#x#" to="1" index="i" step="-1">
<cfoutput><span style="color:<cfif i mod 2 eq 0>red<cfelse>green</cfif>">#q.gift[i]#</span></cfoutput>
</cfloop>
</cffunction>
<cfoutput query="song">
On the #id# day of christmas my true love gave to me:
#song2(song.id,song)# <br>
</cfoutput>