PageRenderTime 67ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/app/controllers/spanish_sentence_quiz_controller.rb

https://bitbucket.org/kapilnakhwa/demo-teachme
Ruby | 352 lines | 244 code | 41 blank | 67 comment | 23 complexity | 742a52521c59c0827a4367b2c4c3c59e MD5 | raw file
  1. #encoding : utf-8
  2. #This File holds the SpanishSentencesQuizController class code,
  3. #which is used to interact with a JQuery module that displays
  4. #a quiz to fill in a correct blank word for a sentence
  5. #
  6. #
  7. #Author:: Brian Cowan (mailto:brian@briancowan.net)
  8. #Copyright:: Copyright (c) 2010 Brian Cowan for 123TeachMe.com
  9. #License:: Proprietary Code
  10. #Version:: $history$
  11. #
  12. class SpanishSentenceQuizController < ApplicationController
  13. caches_action :list, :category
  14. # List of all Sentence Match categories
  15. def list
  16. @page_title = 'Spanish Sentence Quizzes'
  17. @page_heading = @page_title
  18. if(params[:full]=='true') then
  19. @categories = TranslatedSentence.quiz_category_hash()
  20. else
  21. @widget=Widget.where('lookup="spanish_sentence_quiz"').first;
  22. end
  23. end
  24. #Go to a random next quiz
  25. def next_quiz
  26. categories = TranslatedSentence.quiz_category_hash()
  27. categories.delete_if{|k,v| v<8}
  28. num=rand(categories.length);
  29. cat_name = categories.keys[num];
  30. redirect_to :action=>"category",:id=>cat_name;
  31. end
  32. #Load rows from the database based upon simple boolean combination of categories
  33. #params:
  34. # :id = boolean tag command [coma separated (&tag |tag !tag)
  35. # :page = page of quizzes to display
  36. # :title = title to display for quizzes (default is additional sentences)
  37. # :group = optional WidgetCategoryGroup.lookup_key to load additional categories
  38. #out:
  39. # HTML:
  40. # Page with widget on given page with title
  41. # JSON:
  42. # {data=>
  43. # [ {:id=>row.id, /*currently unused*/
  44. # :english=>row.english,
  45. # :spanish=>row.spanish_sentence,
  46. # :correct=>row.correct_answer,
  47. # :incorrect=>row.wrong_answers,
  48. # :audio=>row.audio /*with added server http:// for relative dirs)*/
  49. # }]
  50. # }
  51. def category
  52. query=params[:id];
  53. return false if(
  54. (query.blank? && params[:group].blank?) ||
  55. (!query.blank? && (query.length>80 or !query.index("%").nil?))
  56. ) #To limit strange queries
  57. #Decompose query into and/or/not categories, and put group categories into ORs
  58. tags=query.split(',')
  59. ands=[]
  60. ors=[]
  61. nots=[]
  62. tags.each do |t|
  63. l=t[0..0]
  64. s=t[1..-1]
  65. if(l=="|") then
  66. ors << s
  67. elsif(l=="!") then
  68. nots << s
  69. elsif(l=="&") then
  70. ands << s
  71. else
  72. ors << t
  73. end
  74. end
  75. if(!params[:group].blank?)
  76. @grp=WidgetCategoryGroup.find_by_lookup_key(params[:group])
  77. if(!@grp.nil?) then
  78. #add all group categories that are not in params[:id]
  79. gc=@grp.categories.split('|').reject {|c| !ors.index(c).nil?}
  80. ors.concat(gc)
  81. end
  82. end
  83. qstring=""
  84. plist=[]
  85. ors.each do |s|
  86. qstring+="OR (quiz_categories=? OR quiz_categories LIKE ? OR quiz_categories LIKE ? OR quiz_categories LIKE ?) "
  87. plist << s
  88. plist << "%|"+s+"|%"
  89. plist << s+"|%"
  90. plist << "%|"+s
  91. end
  92. tmp1=
  93. if(qstring.blank?) then
  94. false
  95. else
  96. qstring="("+qstring[3..-1]+")"
  97. true
  98. end
  99. if(ands.length>0) then
  100. ands.each do |s|
  101. qstring+="AND (quiz_categories=? OR quiz_categories LIKE ? OR quiz_categories LIKE ? OR quiz_categories LIKE ?) "
  102. plist << s
  103. plist << "%|"+s+"|%"
  104. plist << s+"|%"
  105. plist << "%|"+s
  106. end
  107. qstring=qstring[4..-1] if(!tmp1)
  108. tmp1=true
  109. end
  110. if(nots.length>0) then
  111. nots.each do |s|
  112. qstring+="AND (quiz_categories <> ? AND quiz_categories NOT LIKE ? AND quiz_categories NOT LIKE ? AND quiz_categories NOT LIKE ?) "
  113. plist << s
  114. plist << "%|"+s+"|%"
  115. plist << s+"|%"
  116. plist << "%|"+s
  117. end
  118. qstring=qstring[4..-1] if(!tmp1)
  119. end
  120. qstring+=" AND (spanish IS NOT NULL AND english IS NOT NULL AND correct_answer IS NOT NULL AND wrong_answers IS NOT NULL)"
  121. data=[]
  122. tlist=[qstring]
  123. tlist.concat(plist)
  124. #Engine attrs
  125. @page_title = 'Spanish Sentence Quiz: ' + (@grp.nil? ? query.capitalize.gsub("_"," ") : @grp.name)
  126. @page_heading = @page_title
  127. #Build items
  128. TranslatedSentence.where(tlist).each do |sq|
  129. #verb might be in a different case in the sentence
  130. sp=sq.spanish
  131. ca=sq.correct_answer
  132. aud=sq.audio
  133. if (aud.blank?) then
  134. aud=nil
  135. elsif(aud.index("http")!=0) then
  136. #aud="http://static.123teachme.com"+aud ;
  137. end
  138. m=sp.upcase.match(Regexp.new('(\b|[żĄ])('+ca.upcase+')(\b)',true,'u'))
  139. if(!m.nil?) then
  140. i=m.begin(1)+m[1].length
  141. sqn=sp[0...i]+"___"+sp[(i+ca.length)..-1]
  142. data<<{
  143. :cats=>sq.quiz_categories,
  144. :english=>sq.english,
  145. :spanish=>sqn,
  146. :correct=>ca,
  147. :incorrect=>sq.wrong_answers.gsub("|",","),
  148. :audio=>aud
  149. }
  150. else
  151. #do a looser check
  152. i=sp.upcase.index(ca.upcase)
  153. if(!i.nil?) then
  154. sqn=sp[0...i]+"___"+sp[(i+ca.length)..-1]
  155. data<<{
  156. :cats=>sq.quiz_categories,
  157. :english=>sq.english,
  158. :spanish=>sqn,
  159. :correct=>ca,
  160. :incorrect=>sq.wrong_answers.gsub("|",","),
  161. :audio=>aud
  162. }
  163. else
  164. #Flag there is something strange with the data
  165. data<<{
  166. :cats=>sq.quiz_categories,
  167. :flag=>true,
  168. :id=>sq.id,
  169. :english=>sq.english,
  170. :spanish=>sp,
  171. :correct=>ca,
  172. :incorrect=>sq.wrong_answers.gsub("|",","),
  173. :audio=>aud
  174. }
  175. end
  176. end
  177. end
  178. #---step categories, so similar quizzes are not all next to each other
  179. #first separate data into categories
  180. data_tmp={}
  181. data.each do |i|
  182. data_tmp[i[:cats]]||=[]
  183. data_tmp[i[:cats]]<< i
  184. end
  185. #count how many are in each category and assign 0 to frequency weight
  186. full_count=data.length+0.0
  187. cat_cnt={}
  188. cat_weight={}
  189. cat_len=data_tmp.keys.length
  190. data_tmp.keys.each do |k|
  191. cat_cnt[k]=data_tmp[k].length+0.0
  192. cat_weight[k]=0.0
  193. end
  194. data=[]
  195. #now separate, putting one from each category weighted by how many elements are in that category
  196. while(!data_tmp.empty?) do
  197. data_ntmp={};
  198. data_tmp.keys.sort.each do |k|
  199. cat_weight[k]+=cat_cnt[k]/full_count
  200. ar=data_tmp[k].dup
  201. if(cat_weight[k]>1.0) then
  202. cat_weight[k]-=1.0
  203. i=ar.pop()
  204. i.delete(:cats); #cats unused in widget now, delete done for security and transmission efficiency
  205. data<< i
  206. if(!ar.empty?) then
  207. data_ntmp[k]=ar
  208. end
  209. else
  210. data_ntmp[k]=ar
  211. end
  212. end
  213. data_tmp=data_ntmp
  214. end
  215. #for extra quizzes
  216. @widget=Widget.where('lookup="spanish_sentence_quiz"').first
  217. respond_to do |f|
  218. f.html do
  219. @data=data
  220. end
  221. f.json do
  222. render :json=>{:data=>data}.to_json
  223. end
  224. end
  225. end
  226. #Load rows from the database
  227. #params:
  228. # :id = coma split list of rows
  229. # :page = page of quizzes to display
  230. # :title = title to display for quizzes (default is additional sentences)
  231. #out:
  232. # HTML:
  233. # page with widget on given page and title
  234. # JSON:
  235. # {data=>
  236. # [ {:id=>row.id, /*currently unused*/
  237. # :english=>row.english,
  238. # :spanish=>row.spanish_sentence,
  239. # :correct=>row.correct_answer,
  240. # :incorrect=>row.wrong_answers,
  241. # :audio=>row.audio /*with added server http:// for relative dirs)*/
  242. # }]
  243. # }
  244. def load_rows
  245. row_ids=params[:id].split(",")
  246. rows={}
  247. row_ids.each do |id|
  248. iid=id.to_i
  249. rows[id]=true if(iid.to_s==id)
  250. end
  251. data=[]
  252. vals=rows.keys.join(",")
  253. qstring="id in ("+vals+") AND (spanish IS NOT NULL AND english IS NOT NULL AND correct_answer IS NOT NULL AND wrong_answers IS NOT NULL)"
  254. sqs=TranslatedSentence.where(qstring).all
  255. sqs.each do |sq|
  256. #verb might be in a different case in the sentence
  257. sp=sq.spanish;
  258. ca=sq.correct_answer
  259. aud=sq.audio
  260. if (aud.blank?) then
  261. aud=nil
  262. elsif(aud.index("http")!=0) then
  263. #aud="http://static.123teachme.com"+aud
  264. end
  265. m=sp.upcase.match(Regexp.new('(\b|[żĄ])('+ca.upcase+')(\b)',true,'u'))
  266. if(!m.nil?) then
  267. i=m.begin(1)+m[1].length
  268. sqn=sp[0...i]+"___"+sp[(i+ca.length)..-1]
  269. data<<{
  270. :english=>sq.english,
  271. :spanish=>sqn,
  272. :correct=>ca,
  273. :incorrect=>sq.wrong_answers.gsub("|",","),
  274. :audio=>aud
  275. };
  276. else
  277. #do a looser check
  278. i=sp.upcase.index(ca.upcase)
  279. if(!i.nil?) then
  280. sqn=sp[0...i]+"___"+sp[(i+ca.length)..-1]
  281. data<<{
  282. :english=>sq.english,
  283. :spanish=>sqn,
  284. :correct=>ca,
  285. :incorrect=>sq.wrong_answers.gsub("|",","),
  286. :audio=>aud
  287. }
  288. else
  289. #Flag there is something strange with the data
  290. data<<{
  291. :flag=>true,
  292. :id=>sq.id,
  293. :english=>sq.english,
  294. :spanish=>sp,
  295. :correct=>ca,
  296. :incorrect=>sq.wrong_answers.gsub("|",","),
  297. :audio=>aud
  298. }
  299. end
  300. end
  301. end
  302. respond_to do |f|
  303. f.html do
  304. @data=data
  305. end
  306. f.json do
  307. render :json=>{:data=>data}.to_json
  308. end
  309. end
  310. end
  311. end