Annotation of capa/capa51/GUITools/capastats.tcl, revision 1.10
1.1 albertel 1: ###########################################################
2: # runCapaTools
3: ###########################################################
4: ###########################################################
5: ###########################################################
6: proc runCapaTools { classDirConfigFile } {
7: global gUniqueNumber gWindowMenu gFile gCT
8:
9: set num [incr gUniqueNumber]
10:
11: set classDir [file dirname $classDirConfigFile]
12: set gFile($num) $classDir
13:
14: set utilsMenu [menu .utilsMenu$num -tearoff 0 -type tearoff -font 8x13bold \
15: -disabledforeground grey85 ]
16: set gCT($num) $utilsMenu
17:
18: set pathLength [string length $gFile($num)]
19: if { $pathLength > 22 } {
20: set pathSubset ...[string range $gFile($num) [expr $pathLength - 22 ] end]
21: } else {
22: set pathSubset $gFile($num)
23: }
24: $utilsMenu add command -label "CapaUtils Ver 1.1" -foreground grey85 -background \
25: black -state disabled
26: $utilsMenu add command -label $pathSubset -foreground white -background \
27: grey30 -state disabled
28:
29: $utilsMenu add command -label "Change Class path" -command "CTchangePath $num"
30: $utilsMenu add command -label "Run capastat" -command "CTcapaStat $num"
31: $utilsMenu add command -label "Run capastat2" -command "CTcapaStat2 $num"
32: $utilsMenu add command -label "Summarize Log files" -command "CTlogAnalysis $num"
33: $utilsMenu add command -label "Student Course Profile" -command \
34: "CTstartStudentCourseProfile $num"
35: $utilsMenu add command -label "CAPA IDs for one student" \
36: -command "CToneStudentCapaID $num"
37: $utilsMenu add command -label "All CAPA IDs" -command "CTclassCapaID $num"
38: $utilsMenu add command -label "Item Analysis" -command "CTitemAnalysisStart $num"
39: $utilsMenu add command -label "Item Correlation" \
40: -command "CTitemCorrelationStart $num"
41: # $utilsMenu add command -label "Email" -command ""
42: # $utilsMenu add command -label "View Score File" -command ""
43: $utilsMenu add command -label "View Submissions" -command "CTsubmissions $num"
1.6 albertel 44: $utilsMenu add command -label "Create a Class Report" -command "CTcreateReport $num"
1.1 albertel 45: $utilsMenu add command -label "Analyze Class Report" -command "CTanalyzeReport $num"
46: $utilsMenu add command -label "Analyze Responses" -command "CTanalyzeScorer $num"
47: $utilsMenu add command -label "Graph a Responses Analysis" -command "CTgraphAnalyzeScorer $num"
1.2 albertel 48: $utilsMenu add command -label "Discussion Stats" -command "CTdiscussStats $num"
1.1 albertel 49: $utilsMenu add command -label "Quit" -command "CTquit $num"
50: $utilsMenu post 0 0
51: Centre_Dialog $utilsMenu default
52: set geometry [wm geometry $utilsMenu]
53: wm geometry $utilsMenu +0+[lindex [split $geometry +] end]
54: parseCapaConfig $num $gFile($num)
55: parseCapaUtilsConfig $num $gFile($num)
56: }
57:
58: #menu commands
59:
60: ###########################################################
61: # CTchangePath
62: ###########################################################
63: ###########################################################
64: ###########################################################
65: #FIXME need to wait unit all running commands are done
66: proc CTchangePath { num } {
67: global gFile gCapaConfig
68: set path [tk_getOpenFile -title "Please select a capa.config file" -filetypes \
69: { { {Capa Config} {capa.config} } }]
70: if { $path == "" } { return }
71: set gFile($num) [file dirname $path]
72: foreach temp [array names gCapaConfig "$num.*"] { unset gCapaConfig($temp) }
73: parseCapaConfig $num $gFile($num)
74: parseCapaUtilsConfig $num $gFile($num)
75: set pathLength [string length $gFile($num)]
76: if { $pathLength > 22 } {
77: set pathSubset ...[string range $gFile($num) [expr $pathLength - 22 ] end]
78: } else {
79: set pathSubset $gFile($num)
80: }
81: .utilsMenu$num entryconfigure 1 -label $pathSubset
82: }
83:
84: ###########################################################
85: # CTcapaStat2
86: ###########################################################
87: ###########################################################
88: ###########################################################
89: proc CTcapaStat2 { num } {
90: global gFile gCT gUniqueNumber
1.9 albertel 91: # if { [set setId [getOneSet $gCT($num) $gFile($num)]] == "" } { return }
92: if {[set setId [pickSets [CTsetList $gFile($num)] single "Pick A Set" \
93: $gCT($num)]] == "Cancel" } { return }
1.1 albertel 94: set cmdnum [incr gUniqueNumber]
95: set gCT(cmd.$cmdnum) capastat
96: if { [
97: catch {
98: CTdatestamp $cmdnum
99: set day [CTgetWhen $cmdnum]
100: set file [file join $gFile($num) records "subset$setId.db"]
101: displayStatus "Generating [file tail $file]" both $cmdnum
102: CTcreateSubset $num $cmdnum $day $setId
103: updateStatusBar 0.0 $cmdnum
104: updateStatusMessage "Generating Stats [file tail $file]" $cmdnum
105: CTscanSetDB $cmdnum $file Q_cnt L_cnt
106: updateStatusBar 0.0 $cmdnum
107: updateStatusMessage "Generating Averages [file tail $file]" $cmdnum
108: CTpercentageScores $cmdnum $setId $L_cnt
109: CTaverage $cmdnum $Q_cnt $L_cnt faillist dodifflist numyes
110: if { $L_cnt != 0 } {
111: CTbargraph $gCT($num) $num [incr gUniqueNumber] $faillist $gFile($num) "Not-Yet-Correct Distribution for set $setId" "Problem \#" "%Wrong"
112: CTbargraph $gCT($num) $num [incr gUniqueNumber] $dodifflist $gFile($num) "Degree of Difficulty Distribution for set $setId" "Problem \#" "Degree Of Diff."
113: CTbargraph $gCT($num) $num [incr gUniqueNumber] $numyes $gFile($num) "Number of Yeses received for set $setId" "Problem \#" "\#Students"
114: }
115: removeStatus $cmdnum
116: CToutput $num $cmdnum
117: } errors ] } {
118: global errorCode errorInfo
119: displayError "$errors\n$errorCode\n$errorInfo"
120: unset gCT(cmd.$cmdnum)
121: } else {
122: unset gCT(cmd.$cmdnum)
123: }
124: }
125:
126: ###########################################################
127: # CTcapaStat
128: ###########################################################
129: ###########################################################
130: ###########################################################
131: proc CTcapaStat { num } {
132: global gFile gCT gUniqueNumber
1.9 albertel 133: # if { [set setId [getOneSet $gCT($num) $gFile($num)]] == "" } { return }
134: if {[set setId [pickSets [CTsetList $gFile($num)] single "Pick A Set" \
135: $gCT($num)]] == "Cancel" } { return }
1.1 albertel 136: set cmdnum [incr gUniqueNumber]
137: set gCT(cmd.$cmdnum) capastat
138: if { [
139: catch {
140: CTdatestamp $cmdnum
141: set file [file join $gFile($num) records "set$setId.db"]
142: displayStatus "Generating Stats [file tail $file]" both $cmdnum
143: CTscanSetDB $cmdnum $file Q_cnt L_cnt
144: updateStatusBar 0.0 $cmdnum
145: updateStatusMessage "Generating Averages [file tail $file]" $cmdnum
146: CTpercentageScores $cmdnum $setId $L_cnt
147: CTaverage $cmdnum $Q_cnt $L_cnt faillist dodifflist numyes
148: CTbargraph $gCT($num) $num [incr gUniqueNumber] $faillist $gFile($num) "Not-Yet-Correct Distribution for set $setId" "Problem \#" "%Wrong"
149: CTbargraph $gCT($num) $num [incr gUniqueNumber] $dodifflist $gFile($num) "Degree of Difficulty Distribution for set $setId" "Problem \#" "Degree Of Diff."
150: CTbargraph $gCT($num) $num [incr gUniqueNumber] $numyes $gFile($num) "Number of Yeses received for set $setId" "Problem \#" "\#Students"
151: removeStatus $cmdnum
152: CToutput $num $cmdnum
153: } errors ] } {
154: global errorCode errorInfo
155: displayError "$errors\n$errorCode\n$errorInfo"
156: unset gCT(cmd.$cmdnum)
157: } else {
158: unset gCT(cmd.$cmdnum)
159: }
160: }
161:
162: ###########################################################
163: # CTlogAnalysis
164: ###########################################################
165: ###########################################################
166: ###########################################################
167: proc CTlogAnalysis { num } {
168: global gFile gUniqueNumber gCT
1.9 albertel 169: #if { [set setId [getOneSet $gCT($num) $gFile($num)]] == "" } { return }
170: if {[set setId [pickSets [CTsetList $gFile($num)] single "Pick A Set" \
171: $gCT($num)]] == "Cancel" } { return }
1.1 albertel 172: set cmdnum [incr gUniqueNumber]
173: set gCT(cmd.$cmdnum) loganalysis
174: CTdatestamp $cmdnum
175: if { [ catch { CTlogAnalysis2 $num $cmdnum $setId } errors ] } {
176: displayError $errors
177: unset gCT(cmd.$cmdnum)
178: } else {
179: unset gCT(cmd.$cmdnum)
180: }
181: CToutput $num $cmdnum
182: }
183:
184: ###########################################################
185: # CTstartStudentCourseProfile
186: ###########################################################
187: ###########################################################
188: ###########################################################
189: proc CTstartStudentCourseProfile { num } {
190: global gFile gCT
191: getOneStudent $gCT($num) $gFile($num) s_id s_name
192: if { $s_id == "" } { return }
193: CTstudentCourseProfile $num $s_id $s_name
194: }
195:
196: ###########################################################
197: # CTstudentCourseProfile
198: ###########################################################
199: ###########################################################
200: ###########################################################
201: proc CTstudentCourseProfile { num s_id s_name {loginAnalysis 2} } {
202: global gFile gUniqueNumber gCapaConfig gCT
203:
204: set cmdnum [incr gUniqueNumber]
205: set gCT(cmd.$cmdnum) studentcourseprofile
206: displayStatus "Collecting homework scores for $s_name" both $cmdnum
207: CTdatestamp $cmdnum
208: CTputs $cmdnum "$s_name\n"
209: if { [ catch { CTcollectSetScores $cmdnum $gFile($num) $s_id 1 \
210: $gCapaConfig($num.homework_scores_limit_set) } error ] } {
211: global errorCode errorInfo
212: displayError "$error \n $errorCode \n $errorInfo"
213: }
214: foreach type { quiz exam supp others } {
215: updateStatusMessage "Collecting $type scores for $s_name" $cmdnum
216: catch {
217: if { [file isdirectory $gCapaConfig($num.[set type]_path)] } {
218: CTcollectSetScores $cmdnum $gCapaConfig($num.[set type]_path) $s_id 1 \
219: $gCapaConfig($num.[set type]_scores_limit_set)
220: }
221: }
222: }
223: removeStatus $cmdnum
224: if { ($loginAnalysis == 2 && "Yes" == [makeSure \
225: "Do you wish to do a Login Analysis? It may take a while." ])
226: || ($loginAnalysis == 1) } {
227: displayStatus "Analyzing login data." both $cmdnum
228: if { [catch { CTloginAnalysis $cmdnum $gFile($num) $s_id \
229: $gCapaConfig($num.homework_scores_limit_set) } error] } {
230: displayError error
231: }
232: if { [catch { CTstudentSetAnalysis $cmdnum $gFile($num) $s_id \
233: $gCapaConfig($num.homework_scores_limit_set) } error] } {
234: displayError error
235: }
236: removeStatus $cmdnum
237: }
238: CTdisplayStudent $cmdnum $gCT($num) $gFile($num) $s_id
239: unset gCT(cmd.$cmdnum)
240: CToutput $num $cmdnum
241: }
242:
243: ###########################################################
244: # CToneStudentCapaID
245: ###########################################################
246: ###########################################################
247: ###########################################################
248: proc CToneStudentCapaID { num } {
249: global gFile gUniqueNumber gCapaConfig gCT
250:
251: getOneStudent $gCT($num) $gFile($num) s_id s_name
252: if { $s_id == "" } { return }
253:
254: set cmdnum [incr gUniqueNumber]
255: set gCT(cmd.$cmdnum) onestudentcapaid
256: set setlist [getSetRange $gCT($num) $gFile($num)]
257: set command "$gCapaConfig($num.allcapaid_command) -i -stu $s_id -s [lindex $setlist 0] -e [lindex $setlist 1] -c $gFile($num)"
258: if { "Yes" == [makeSure "CMD: $command\n Do you wish to execute this command?"] } {
259: CTdatestamp $cmdnum
260: CTputs $cmdnum "CapaIDs for: $s_id, $s_name\n"
261: displayStatus "Getting CapaIDs" spinner $cmdnum
262: set fileId [open "|$command" "r"]
263: fconfigure $fileId -blocking 0
264: fileevent $fileId readable "CTrunCommand $num $cmdnum $fileId"
265: }
266: }
267:
268: ###########################################################
269: # CTclassCapaID
270: ###########################################################
271: ###########################################################
272: ###########################################################
273: proc CTclassCapaID { num } {
274: global gFile gUniqueNumber gCapaConfig gCT
275:
276: set cmdnum [incr gUniqueNumber]
277: set gCT(cmd.$cmdnum) classcapaid
278: set setlist [getSetRange $gCT($num) $gFile($num)]
279: if { $setlist == "" } { return }
280: set command "$gCapaConfig($num.allcapaid_command) -i -s [lindex $setlist 0] -e [lindex $setlist 1] -c $gFile($num)"
281: if { "Yes" == [makeSure "CMD: $command\n Do you wish to execute this command?"] } {
282: CTdatestamp $cmdnum
283: displayStatus "Getting all CapaIDs" spinner $cmdnum
284: set fileId [open "|$command" "r"]
285: fconfigure $fileId -blocking 0
286: fileevent $fileId readable "CTrunCommand $num $cmdnum $fileId"
287: }
288: }
289:
290: ###########################################################
291: # CTitemAnalysisStart
292: ###########################################################
293: ###########################################################
294: ###########################################################
295: proc CTitemAnalysisStart { num } {
296: global gFile gUniqueNumber gCapaConfig gCT
297:
298: set cmdnum [incr gUniqueNumber]
299: set gCT(cmd.$cmdnum) itemanalysis
300: set paths ""
301: lappend paths [list "classpath" $gFile($num)]
302: foreach path [lsort [array names gCapaConfig "$num.*_path"]] {
303: lappend paths [list [lindex [split $path "."] 1] $gCapaConfig($path) ]
304: }
305: if {[set select [multipleChoice $gCT($num) "Select a class path" $paths ] ] == ""} {
306: unset gCT(cmd.$cmdnum)
307: return
308: }
1.9 albertel 309: # if { [set sets [getSetRange $gCT($num) [lindex $select 1]]] == "" } \{
310: if { [set sets [pickSets [CTsetList [lindex $select 1]] \
311: "extended" "Select Sets" $gCT($num)]] == "Cancel" } {
1.1 albertel 312: unset gCT(cmd.$cmdnum)
313: return
314: }
315: CTdatestamp $cmdnum
1.9 albertel 316: if { [ catch {CTitemAnalysisRange $cmdnum [lindex $select 1] $sets } errors ] } {
1.1 albertel 317: displayError $errors
318: }
319: unset gCT(cmd.$cmdnum)
320: CToutput $num $cmdnum
321: }
322:
323: ###########################################################
324: # CTitemCorrelationStart
325: ###########################################################
326: ###########################################################
327: ###########################################################
328: proc CTitemCorrelationStart { num } {
329: global gFile gUniqueNumber gCapaConfig gCT
330:
331: ## FIXME:
332: ## Let user specify how many categories to calculate correlation
333: ## For each category, the user can specify problem numbers to
334: ## be in that category
335: ## Then, the correlations between each category is calculated
336: ##
337: set cmdnum [incr gUniqueNumber]
338: set gCT(cmd.$cmdnum) itemanalysis
339: set paths ""
340: lappend paths [list "classpath" $gFile($num)]
341: foreach path [lsort [array names gCapaConfig "$num.*_path"]] {
342: lappend paths [list [lindex [split $path "."] 1] $gCapaConfig($path) ]
343: }
1.9 albertel 344: if {[set select [multipleChoice $gCT($num) "Select a class path" $paths]] == ""} {
1.1 albertel 345: unset gCT(cmd.$cmdnum)
346: return
347: }
1.9 albertel 348: #if { [set setId [getOneSet $gCT($num) [lindex $select 1]]] == "" } \{
349: if {[set setId [pickSets [CTsetList [lindex $select 1]] single "Pick A Set" \
350: $gCT($num)]] == "Cancel" } {
1.1 albertel 351: unset gCT(cmd.$cmdnum)
352: return
353: }
354: CTdatestamp $cmdnum
355: if { [ catch { CTitemCorrelation $cmdnum [lindex $select 1] \
356: $setId } errors ] } { displayError $errors }
357: unset gCT(cmd.$cmdnum)
358: CToutput $num $cmdnum
359: }
360:
361: ###########################################################
362: # CTsubmissions
363: ###########################################################
364: ###########################################################
365: ###########################################################
366: proc CTsubmissions { num } {
367: global gCT gFile gUniqueNumber gCapaConfig
368:
369: getOneStudent $gCT($num) $gFile($num) s_id s_name
370: if { $s_id == "" } { return }
371:
372: set cmdnum [incr gUniqueNumber]
373: set gCT(cmd.$cmdnum) submissions
1.9 albertel 374: if { [set sets [pickSets [CTsetList $gFile($num)] \
375: "extended" "Select Sets" $gCT($num)]] == "Cancel" } { return }
376: # if { "" == [set setlist [getSetRange $gCT($num) $gFile($num)]] } { return }
1.1 albertel 377: CTdatestamp $cmdnum
378: CTputs $cmdnum "Submissions for: $s_id, $s_name\n"
379: displayStatus "Getting submissions" spinner $cmdnum
1.9 albertel 380: CTsubmissionsLaunch $num $cmdnum telnet $s_id $s_name 0 $sets
1.1 albertel 381: }
382:
383: ###########################################################
1.6 albertel 384: # CTcreateReport
385: ###########################################################
386: ###########################################################
387: ###########################################################
388: proc CTcreateReport { num } {
389: global gUniqueNumber gCT gFile
390:
391: set cmdnum [incr gUniqueNumber]
392: set gCT(cmd.$cmdnum) createreport
393: CTcreateReportDialog $num $cmdnum
394: }
395:
396: ###########################################################
1.1 albertel 397: # CTanalyzeReport
398: ###########################################################
399: ###########################################################
400: ###########################################################
401: proc CTanalyzeReport { num } {
402: global gUniqueNumber gCT gFile
403:
404: set cmdnum [incr gUniqueNumber]
405: set gCT(cmd.$cmdnum) analyzereport
406:
407: set reportFile [tk_getOpenFile -title "Please select the Report file" \
408: -filetypes { {{Capa Reports} {*.rpt}} {{All Files} {*}} }]
409: if { $reportFile == "" } { return }
410: set percentage [tk_dialog $gCT($num).dialog "How would you like scores displayed?" \
411: "How would you like scores displayed?" "" "" "Points Earned" \
412: "Percentage" "Cancel"]
413: if { $percentage == 2 } { return }
414: set pwd [pwd];cd $gFile($num)
415: set sectionList [pickSections [getExistingSections] "Select Sections To Analyze:" $gCT($num) ]
416: CTdatestamp $cmdnum
417: CTputs $cmdnum "Analyzing Report File $reportFile\n"
418: CTputs $cmdnum " For Sections $sectionList\n"
419: CTputs $cmdnum " Report Created at [clock format [file mtime $reportFile]]\n"
420: cd $pwd
421: set scorelist [CTreportDist $cmdnum $reportFile $percentage $sectionList]
422: set label [lindex "{Grade} {Grade(%)}" $percentage]
423: set ptsearned 0
424: set totalnumstu 0
425: foreach element $scorelist {
426: set numstu [lindex $element 0]
427: set score [lindex $element 1]
428: set ptsearned [expr $ptsearned + ($numstu*$score)]
429: incr totalnumstu $numstu
430: }
431: set average [expr $ptsearned / double($totalnumstu)]
432: set avgmsg [format "Average: %.2f" $average]
433: CTputs $cmdnum $avgmsg\n
434: CTbargraph $gCT($num) $num $cmdnum $scorelist $gFile($num) "Score Distribution for [file tail $reportFile] $avgmsg" $label "\# Students" SCP
435: unset gCT(cmd.$cmdnum)
436: CToutput $num $cmdnum
437: }
438:
439: ###########################################################
440: # CTanalyzeScorer
441: ###########################################################
442: ###########################################################
443: ###########################################################
444: proc CTanalyzeScorer { num } {
445: global gFile gUniqueNumber gCapaConfig gCT
446: set cmdnum [incr gUniqueNumber]
447: set gCT(cmd.$cmdnum) analyzescorer
448: if { "" == [set file [tk_getOpenFile -title "Pick a scorer.output file" -filetypes { { {scorer.output} {scorer.output.*} } { {Submissions File} {*submissions*.db} } { {All Files} {*} } }]] } { return }
449: set path [file dirname [file dirname $file]]
450: if { "" == [set gCT($cmdnum.questNum) [getString $gCT($num) "Which questions?"]]} {
451: return
452: }
453: set gCT($cmdnum.max) [lindex [exec wc -l $file] 0]
454: set gCT($cmdnum.done) 1
455: set gCT($cmdnum.graphup) 0
456: set gCT($cmdnum.num) $num
457: displayStatus "Getting student reponses" both $cmdnum
458: set gCT($cmdnum.fileId) [open $file r]
459: if { [regexp {scorer\.output\.([0-9]|([0-9][0-9]))} $file] } {
460: set gCT($cmdnum.setId) [string range [file extension $file] 1 end]
461: set gCT($cmdnum.parse) CTparseScorerOutputLine
462: set aline [gets $gCT($cmdnum.fileId)]
463: } else {
464: set gCT($cmdnum.setId) [lindex [split [file tail $file] s.] 4]
465: set gCT($cmdnum.parse) CTparseSubmissionsLine
466: }
467: set aline [gets $gCT($cmdnum.fileId)]
468: $gCT($cmdnum.parse) $aline $cmdnum
469: set pwd [pwd];cd $path
470: getSet $gCT($cmdnum.question) $gCT($cmdnum.setId) "CTcontinueAnalyze $cmdnum $path"
471: cd $pwd
472: }
473:
474: proc CTcontinueAnalyze { num path arrayVar } {
475: global gCT gResponse
476: upvar $arrayVar question
477: CTgetQuestions $num question
478: set numAdded 0
479: foreach which $gCT($num.questNum) {
480: incr numAdded [CTgetStudentResponses $num [lindex $gCT($num.response) \
481: [expr $which-1]] $which \
482: question]
483: }
484: updateStatusBar [expr $gCT($num.done)/double($gCT($num.max))] $num
485: if { $numAdded > 0 } { CTupdateAnalyzeScorer $num }
486: set interesting 0
487: while {!$interesting} {
488: incr gCT($num.done)
489: set stunum $gCT($num.question)
490: set aline [gets $gCT($num.fileId)]
491: if { [eof $gCT($num.fileId)] } { CTfinishAnalyzeScorer $num; return }
492: set interesting [$gCT($num.parse) $aline $num]
493: }
494: if { $stunum != $gCT($num.question) } {
495: set pwd [pwd];cd $path
496: getSet $gCT($num.question) $gCT($num.setId) "CTcontinueAnalyze $num $path"
497: cd $pwd
498: } else {
499: CTcontinueAnalyze $num $path question
500: }
501: }
502:
503: proc CTupdateAnalyzeScorer { cmdnum } {
504: global gCT gResponse gUniqueNumber gFile
505: set num $gCT($cmdnum.num)
506: set i 0
507: foreach correct [array names gResponse "$cmdnum.correct.*"] {
508: set probnum [lindex [split $correct .] 2]
509: set answer [join [lrange [split $correct .] 3 end] .]
510: if { $gResponse($correct) } {
511: set color($probnum.$answer) green
512: } else {
513: set color($probnum.$answer) red
514: }
515: }
516: set results ""
517: set oldprobnum [lindex [split [lindex [lsort [array names gResponse $cmdnum.\[0-9\]*]] 0] .] 1]
518: foreach response [lsort -dictionary [array names gResponse $cmdnum.\[0-9\]*]] {
519: incr i
520: set probnum [lindex [split $response .] 1]
521: if { $probnum > $oldprobnum } {
522: set oldprobnum $probnum
523: lappend results [list 0 0 "Problem Divider" white]
524: }
525: set answer [join [lrange [split $response .] 2 end] .]
526: lappend results [list $gResponse($response) $i $answer $color($probnum.$answer)]
527: }
528: if { $results == "" } { return }
529: if { $gCT($cmdnum.graphup)} {
530: CTchangeBargraphData $cmdnum $results
531: } else {
532: CTbargraph $gCT($num) $num $cmdnum $results $gFile($num) "Reponse Distribution" "Which Response" "\#Picked" "Showresponse"
533: set gCT($cmdnum.graphup) 1
534: }
535:
536: update idletasks
537: }
538:
539: proc CTsaveAnalyzeScorer { num cmdnum } {
540: global gResponse gCT gFile
541: set file [tk_getSaveFile -initialdir $gFile($num)]
542: set fileId [open $file w]
543: puts $fileId [array get gResponse "$cmdnum.*"]
544: close $fileId
545: }
546:
547: proc CTfinishAnalyzeScorer { cmdnum } {
548: global gCT gResponse gUniqueNumber gFile
549:
550: set num $gCT($cmdnum.num)
551: set i 0
552: removeStatus $cmdnum
553: foreach correct [array names gResponse "$cmdnum.correct.*"] {
554: set probnum [lindex [split $correct .] 2]
555: set answer [join [lrange [split $correct .] 3 end] .]
556: if { $gResponse($correct) } {
557: set color($probnum.$answer) green
558: } else {
559: set color($probnum.$answer) red
560: }
561: }
562: foreach response [lsort -dictionary [array names gResponse $cmdnum.\[0-9\]*]] {
563: incr i
564: set probnum [lindex [split $response .] 1]
565: set answer [join [lrange [split $response .] 2 end] .]
566: lappend results($probnum) [list $gResponse($response) $i $answer $color($probnum.$answer)]
567: }
568: foreach probnum [lsort -dictionary [array names results]] {
569: CTputs $cmdnum "\nFor Problem $probnum #, Responses:\n"
570: foreach response $results($probnum) {
571: CTputs $cmdnum "[lindex $response 0], [lindex $response 2]\n"
572: }
573: }
574: if { "Yes" ==[makeSure "Would you like to save the results to a file?"] } {
575: CTsaveAnalyzeScorer $num $cmdnum
576: }
577: unset gCT(cmd.$cmdnum)
578: CToutput $num $cmdnum
579: }
580:
581: proc CTparseScorerOutputLine { aline num } {
582: global gCT
583: set gCT($num.stunum) [lindex $aline 0]
584: set aline [string range $aline 40 end]
585: set length [llength [split [lrange $aline 3 end] ,] ]
586: set gCT($num.response) [lrange [split [lrange $aline 3 end] ,] 0 \
587: [expr {$length-2}]]
588: set gCT($num.question) [lindex [lindex [split $aline ,] end] 0]
589: return 1
590: }
591:
592: proc CTparseSubmissionsLine { aline num } {
593: global gCT
594: set aline [split $aline \t]
595: set gCT($num.stunum) [lindex $aline 0]
596: set gCT($num.question) $gCT($num.stunum)
597: set gCT($num.response) ""
598: set interesting 0
599: set current 1
600: foreach {quest response} [lrange $aline 2 end] {
601: if { $quest == "" } break
602: while { $quest > $current } {
603: lappend gCT($num.response) {}
604: incr current
605: }
606: if { [lsearch $gCT($num.questNum) $quest] != -1} { set interesting 1 }
607: lappend gCT($num.response) [string toupper $response]
608: incr current
609: }
610: return $interesting
611: }
612:
613: proc CTgetQuestions { num questionVar } {
614: global gCT
615: upvar $questionVar question
616: # parray question
617: foreach quest $gCT($num.questNum) {
618: foreach line $question($quest.quest) {
619: if { [regexp {^ *([A-Z])\)(.*)} $line temp letter rest] } {
620: set question($quest.$letter) $rest
621: if { [string first $letter $question($quest.ans)] != -1} {
622: set question($quest.correct.$letter) 1
623: set question($quest.$letter) "$rest - Correct"
624: } else {
625: set question($quest.correct.$letter) 0
626: set question($quest.$letter) "$rest - Incorrect"
627: }
628: }
629: }
630: }
631: }
632:
633: proc CTgetStudentResponses { num responses which questionVar } {
634: global gCT gResponse
635: upvar $questionVar question
636: # parray question
637: set i 0
638: foreach response [split $responses {}] {
639: if { $response == "" || $response == " "} { continue }
640: incr i
641: if { [catch {incr gResponse($num.$which.$question($which.$response))}] } {
642: if {[catch {set gResponse($num.$which.$question($which.$response)) 1}]} {
643: #set gResponse($num.$which.Illegal\ Bubble) 1
644: puts "not an option $response $which"
645: continue
646: }
647: }
648: if { $question($which.correct.$response) } {
649: set gResponse($num.correct.$which.$question($which.$response)) 1
650: } else {
651: set gResponse($num.correct.$which.$question($which.$response)) 0
652: }
653: }
654: return $i
655: }
656:
657: ###########################################################
658: # CTgraphAnalyzeScorer
659: ###########################################################
660: ###########################################################
661: ###########################################################
662: proc CTgraphAnalyzeScorer { num } {
663: global gFile gUniqueNumber gCapaConfig gCT gResponse
664: set cmdnum [incr gUniqueNumber]
665: set gCT(cmd.$cmdnum) graphanalyzescorer
666: if { "" == [set file [tk_getOpenFile -title "Pick a Output file" -filetypes { { {All Files} {*} } } -initialdir $gFile($num)]] } { return }
667: set fileId [open $file r]
668: set temp [read $fileId [file size $file]]
669: close $fileId
670: foreach {name value} $temp {
671: set name [join "$cmdnum [lrange [split $name .] 1 end]" .]
672: set gResponse($name) $value
673: }
674: unset temp
675: foreach name [array names gResponse $cmdnum.\[0-9\]*] {
676: puts "[split $name .]"
677: puts "[lindex [split $name .] 1]"
678: lappend probnums [lindex [split $name .] 1]
679: }
680: set probnums [lsort [lunique $probnums]]
681: event generate . <1> -x 1 -y 1
682: event generate . <ButtonRelease-1>
683: if { "" == [set probnums [multipleChoice $gCT($num) "Select which problems" $probnums 0]] } { return }
684: foreach name [array names gResponse $cmdnum.\[0-9\]*] {
685: set probnum [lindex [split $name .] 1]
686: if { -1 == [lsearch $probnums $probnum] } {
687: set answer [join [lrange [split $name .] 2 end] .]
688: unset gResponse($name)
689: unset gResponse($cmdnum.correct.$probnum.$answer)
690: }
691: }
692: set gCT($cmdnum.num) $num
693: set gCT($cmdnum.graphup) 0
694: CTupdateAnalyzeScorer $cmdnum
695: unset gCT(cmd.$cmdnum)
696: }
697:
698: ###########################################################
1.2 albertel 699: # CTdiscussStats
700: ###########################################################
701: ###########################################################
702: ###########################################################
703: proc CTdiscussStats { num } {
704: global gCT gUniqueNumber gFile
705: set cmdnum [incr gUniqueNumber]
706: set gCT(cmd.$cmdnum) discussstats
707: set file [file join $gFile($num) discussion logs access.log]
708: displayStatus "Generating discussion Stats" both $cmdnum
1.3 albertel 709: CTdiscussForum $cmdnum $file $gFile($num) discussData 0
710: CTputsDiscussResults $cmdnum discussData
1.2 albertel 711: CToutput $num $cmdnum
712: removeStatus $cmdnum
713: unset gCT(cmd.$cmdnum)
714: }
715:
716: ###########################################################
1.1 albertel 717: # CTquit
718: ###########################################################
719: ###########################################################
720: ###########################################################
721: proc CTquit { num } {
722: global gCT
723: destroy $gCT($num)
724: }
725:
726: #menu command helpers
727: ###########################################################
728: # CTscanSetDB
729: ###########################################################
730: ###########################################################
731: ###########################################################
732: proc CTscanSetDB { num file Q_cntVar L_cntVar } {
733: global gMaxSet gTotal_try gYes_cnt gyes_cnt gStudent_cnt gStudent_try \
734: gTotal_weight gTotal_scores gEntry gScore gNewStudent_cnt
735: upvar $Q_cntVar Q_cnt
736: upvar $L_cntVar L_cnt
737:
738: set line_cnt 0
739: set valid_cnt 0
740:
741: for { set ii 0 } { $ii <= $gMaxSet } { incr ii } {
742: set gTotal_try($num.$ii) 0
743: set gYes_cnt($num.$ii) 0
744: set gyes_cnt($num.$ii) 0
745: for { set jj 0 } { $jj <= $gMaxSet } { incr jj } {
746: set gStudent_cnt($num.$ii.$jj) 0
747: set gStudent_try($num.$ii.$jj) 0
748: }
749: set gNewStudent_cnt($num.$ii) 0
750: }
751: set gTotal_weight($num) 0
752: set gTotal_scores($num) 0
753:
754: set maxLine [lindex [exec wc $file] 0]
755: set tries ""
756: set fileId [open $file "r"]
757: set aline [gets $fileId]
758: while { ! [eof $fileId] } {
759: incr line_cnt
760: if { ($line_cnt%20) == 0 } {
761: updateStatusBar [expr $line_cnt/double($maxLine)] $num
762: }
763: if { $line_cnt == 2 } {
764: set aline [string trim $aline]
765: set weight [split $aline {}]
766: }
767: if { $line_cnt > 3 } {
768: catch {
769: set aline [string trim $aline]
770: set prefix [lindex [split $aline ,] 0]
771: set s_num [lindex [split $aline " "] 0]
772: set ans_str [lindex [split $prefix " "] 1]
773: set ans_char [split $ans_str {} ]
774: set tries [lrange [split $aline ,] 1 end]
775: for { set valid 0; set ii 0 } { $ii < [llength $ans_char] } { incr ii } {
776: if {([lindex $ans_char $ii] != "-")&&([lindex $ans_char $ii] != "E")
777: && ([lindex $ans_char $ii] != "e") } { set valid 1 }
778: }
779: if { $valid } {
780: for {set score 0; set ii 0} { $ii < [llength $tries] } { incr ii } {
781: set triesii 0
782: incr gTotal_weight($num) [lindex $weight $ii]
783: if { [lindex $ans_char $ii] == "Y" } {
784: set triesii [string trim [lindex $tries $ii]]
785: incr gYes_cnt($num.$ii)
786: incr score [lindex $weight $ii]
787: incr gNewStudent_cnt($num.$ii)
788: } elseif { [lindex $ans_char $ii] == "y" } {
789: set triesii [string trim [lindex $tries $ii]]
790: incr triesii
791: incr gyes_cnt($num.$ii)
792: incr score [lindex $weight $ii]
793: incr gNewStudent_cnt($num.$ii)
794: } elseif { ( [lindex $ans_char $ii] > 0 ) && \
795: ( [lindex $ans_char $ii] <= 9) } {
796: set triesii [string trim [lindex $tries $ii]]
797: incr score [lindex $ans_char $ii]
798: incr gYes_cnt($num.$ii)
799: incr gNewStudent_cnt($num.$ii)
800: } elseif { ( [lindex $ans_char $ii] == 0 ) } {
801: set triesii [string trim [lindex $tries $ii]]
802: incr gNewStudent_cnt($num.$ii)
803: } elseif {([lindex $ans_char $ii]=="n") || \
804: ([lindex $ans_char $ii]=="N")} {
805: set triesii [string trim [lindex $tries $ii]]
806: if { [lindex $ans_char $ii] == "n" } { incr triesii }
807: incr gNewStudent_cnt($num.$ii)
808: }
809: set gStudent_try($num.$valid_cnt.$ii) $triesii
810: incr gTotal_try($num.$ii) $triesii
811: incr gStudent_cnt($num.$ii.$triesii)
812: }
813: incr gTotal_scores($num) $score
814: set gEntry($num.$valid_cnt) "$aline"
815: set gScore($num.$valid_cnt) $score
816: incr valid_cnt
817: }
818: }
819: }
820: set aline [gets $fileId]
821: }
822: close $fileId
823: set Q_cnt [llength $tries]
824: set L_cnt $valid_cnt
825: return
826: }
827:
828: ###########################################################
829: # CTpercentageScores
830: ###########################################################
831: ###########################################################
832: ###########################################################
833: proc CTpercentageScores { num setId valid_cnt } {
834: global gTotal_weight gTotal_scores
835:
836: if { $gTotal_weight($num) > 0 } {
837: set ratio [expr double($gTotal_scores($num)) / double($gTotal_weight($num))]
838: set ratio [expr $ratio * 100.0 ]
839: CTputs $num "\nScore (total scores / total valid weights) for set$setId.db: [format %7.2f%% $ratio]\n"
840: }
841: CTputs $num "The number of valid records for set$setId.db is: $valid_cnt\n"
842: }
843:
844: ###########################################################
845: # CTaverage
846: ###########################################################
847: ###########################################################
848: ###########################################################
849: proc CTaverage { num q_cnt l_cnt faillistVar dodifflistVar numyesVar} {
850: upvar $faillistVar faillist $dodifflistVar dodifflist $numyesVar numyes
851: global gMaxTries gStudent_cnt gStudent_try gTotal_try gYes_cnt gyes_cnt \
852: gNewStudent_cnt
853:
854: set maxIter [expr $q_cnt * 4]
855:
856: for { set ii 0 } { $ii < $q_cnt } { incr ii } {
857: updateStatusBar [expr $ii/double($maxIter)] $num
858: set s_cnt($ii) 0
859: set avg($ii) 0.0
860: set max_try($ii) 0
861: for { set jj 1 } { $jj < $gMaxTries } { incr jj } {
862: if { $gStudent_cnt($num.$ii.$jj) > 0 } {
863: set avg($ii) [expr $avg($ii) + ($jj * $gStudent_cnt($num.$ii.$jj))]
864: incr s_cnt($ii) $gStudent_cnt($num.$ii.$jj)
865: }
866: }
867: set s_cnt($ii) $gNewStudent_cnt($num.$ii)
868: if { $s_cnt($ii) > 0 } { set avg($ii) [expr $avg($ii) / $s_cnt($ii)] }
869: }
870:
871: for { set ii 0 } { $ii < $q_cnt } { incr ii } {
872: updateStatusBar [expr ($ii+$q_cnt)/double($maxIter)] $num
873: set sd($ii) 0.0
874: set sum 0.0
875: for { set jj 0 } { $jj < $l_cnt } { incr jj } {
876: if { $gStudent_try($num.$jj.$ii) > $max_try($ii) } {
877: set max_try($ii) $gStudent_try($num.$jj.$ii)
878: }
879: if { $gStudent_try($num.$jj.$ii) > 0 } {
880: set sq [expr ( $gStudent_try($num.$jj.$ii) - $avg($ii) ) * \
881: ( $gStudent_try($num.$jj.$ii) - $avg($ii)) ]
882: set sum [expr $sum + $sq]
883: }
884: if { $s_cnt($ii) > 1 } {
885: set sd($ii) [expr $sum / ( $s_cnt($ii) - 1.0 )]
886: }
887: if { $sd($ii) > 0 } { set sd($ii) [ expr sqrt($sd($ii)) ] }
888: }
889: }
890:
891: for { set ii 0 } { $ii < $q_cnt } { incr ii } {
892: updateStatusBar [expr ($ii+(2*$q_cnt))/double($maxIter)] $num
893: set sd3($ii) 0.0
894: set sum 0.0
895: for { set jj 0 } { $jj < $l_cnt } { incr jj } {
896: if { $gStudent_try($num.$jj.$ii) > 0 } {
897: set tmp1 [expr $gStudent_try($num.$jj.$ii) - $avg($ii)]
898: set tmp2 [expr $tmp1 * $tmp1 * $tmp1]
899: set sum [expr $sum + $tmp2]
900: }
901: if { ( $s_cnt($ii) > 0 ) && ( $sd($ii) != 0.0 ) } {
902: set sd3($ii) [expr $sum / $s_cnt($ii) ]
903: set sd3($ii) [expr $sd3($ii) / ($sd($ii) * $sd($ii) * $sd($ii)) ]
904: }
905: }
906: }
907: CTputs $num "This is the statistics for each problem: \n"
908: CTputs $num "Prob\# MxTries avg. s.d. s.k. \#Stdnts"
909: CTputs $num " \#Yes \#yes Tries DoDiff %Wrong\n"
910: set numyes [set dodifflist [set faillist ""]]
911: # parray s_cnt
912: for { set ii 0 } { $ii < $q_cnt } { incr ii } {
913: updateStatusBar [expr ($ii+(3*$q_cnt))/double($maxIter)] $num
914: if { $gTotal_try($num.$ii) > 0 } {
915: set dod [expr $gTotal_try($num.$ii)/(0.1 + $gYes_cnt($num.$ii) \
916: + $gyes_cnt($num.$ii))]
917: } else {
918: set dod 0.0
919: }
920: if {[catch {set success [expr 100.0*($s_cnt($ii)-($gYes_cnt($num.$ii)+ \
921: $gyes_cnt($num.$ii)))/$s_cnt($ii)]}]} {
922: set success 0.0
923: set s_cnt($ii) 0
924: }
925: CTputs $num [format "P %2d" [expr int($ii + 1)] ]
926: CTputs $num [format "%6d %8.2f %7.2f %6.2f %5d %5d %5d %5d %5.1f %6.2f\n"\
927: $max_try($ii) $avg($ii) $sd($ii) $sd3($ii) $s_cnt($ii) \
928: $gYes_cnt($num.$ii) $gyes_cnt($num.$ii) \
929: $gTotal_try($num.$ii) $dod $success]
930: if { $success < 0 } { set success 0 }
931: lappend faillist [list $success [expr int($ii + 1)]]
932: lappend dodifflist [list $dod [expr int($ii + 1)]]
933: lappend numyes [list [expr $gYes_cnt($num.$ii)+$gyes_cnt($num.$ii)] \
934: [expr int($ii + 1)]]
935: }
936: }
937:
938: ###########################################################
939: # CTlogAnalysis2
940: ###########################################################
941: ###########################################################
942: ###########################################################
943: proc CTlogAnalysis2 { num cmdnum setId } {
944: global gFile
945: set logFile [file join $gFile($num) records "log$setId.db"]
946: if { [file exists $logFile] } {
947: CTputs $cmdnum "Log analysis for telnet session log$setId.db\n"
1.3 albertel 948: CTscanLogDB $cmdnum $logFile l(Y) l(N) l(S) l(U) l(u) l(A) l(F)
1.1 albertel 949: } else {
1.3 albertel 950: set l(Y) [set l(N) [set l(S) [set l(U) [set l(u) [set l(A) [set l(F) 0]]]]]]
1.1 albertel 951: }
952: set webLogFile [file join $gFile($num) records "weblog$setId.db" ]
953: if { [file exists $webLogFile] } {
954: CTputs $cmdnum "===============================================\n"
955: CTputs $cmdnum "Log analysis for web session weblog$setId.db\n"
1.3 albertel 956: CTscanLogDB $cmdnum $webLogFile w(Y) w(N) w(S) w(U) w(u) w(A) w(F)
1.1 albertel 957: } else {
1.3 albertel 958: set w(Y) [set w(N) [set w(S) [set w(U) [set w(u) [set w(A) [set w(F) 0]]]]]]
1.1 albertel 959: }
1.3 albertel 960: set telnet_total [expr $l(Y)+$l(N)+$l(S)+$l(U)+$l(u)+$l(A)+$l(F)]
961: set web_total [expr $w(Y)+$w(N)+$w(S)+$w(U)+$w(u)+$w(A)+$w(F)]
1.1 albertel 962: CTputs $cmdnum "============== SUMMARY ====================\n"
1.3 albertel 963: CTputs $cmdnum " #Y #N #S #U #u #A #F Total\n"
964: CTputs $cmdnum [format "telnet: %6d %6d %6d %6d %6d %6d %6d %6d\n" \
965: $l(Y) $l(N) $l(S) $l(U) $l(u) $l(A) $l(F) $telnet_total ]
966: CTputs $cmdnum [format " web: %6d %6d %6d %6d %6d %6d %6d %6d\n" \
967: $w(Y) $w(N) $w(S) $w(U) $w(u) $w(A) $w(F) $web_total]
968: foreach v { Y N S U u A F} {
1.1 albertel 969: set sum($v) [expr $l($v) + $w($v)]
970: if { $sum($v) > 0 } {
971: set ratio($v) [expr 100.0*$w($v)/double($sum($v))]
972: } else {
973: set ratio($v) 0.0
974: }
975: }
976: set overall_entries [expr $telnet_total + $web_total]
977: if { $overall_entries > 0 } {
978: set ratio(web) [expr 100.0*(double($web_total)/double($overall_entries))]
979: } else {
980: set ratio(web) 0.0
981: }
1.3 albertel 982: CTputs $cmdnum [format " %%web: % 6.1f % 6.1f % 6.1f % 6.1f % 6.1f % 6.1f % 6.1f % 6.1f\n" \
983: $ratio(Y) $ratio(N) $ratio(S) $ratio(U) $ratio(u) $ratio(A) $ratio(F) $ratio(web) ]
1.1 albertel 984: }
985:
986:
987: ###########################################################
988: # CTscanLogDB
989: ###########################################################
990: ###########################################################
991: ###########################################################
1.3 albertel 992: proc CTscanLogDB { num file Y_lVar N_lVar S_lVar U_lVar u_lVar A_lVar F_lVar } {
1.1 albertel 993: upvar $Y_lVar Y_l
994: upvar $N_lVar N_l
995: upvar $S_lVar S_l
996: upvar $U_lVar U_l
997: upvar $u_lVar u_l
1.3 albertel 998: upvar $A_lVar A_l
999: upvar $F_lVar F_l
1.1 albertel 1000:
1001: set line_cnt 0
1002:
1003: displayStatus "Analyzing [file tail $file]" both $num
1004: set maxLine [lindex [exec wc $file] 0]
1005: set fileId [open $file "r"]
1006:
1007: set aline [gets $fileId]
1008: while { ! [eof $fileId] } {
1009: incr line_cnt
1010: if { ($line_cnt%20) == 0 } {
1011: updateStatusBar [expr $line_cnt/double($maxLine)] $num
1012: }
1013: set aline [string trim $aline]
1014: set ans_str [string range $aline 35 end]
1015: set ans_char [split $ans_str {}]
1016: if { ! [info exists count] } {
1017: for { set i 0 } { $i < [llength $ans_char] } { incr i } {
1018: set count(Y.$i) 0; set count(N.$i) 0; set count(S.$i) 0
1.3 albertel 1019: set count(U.$i) 0; set count(u.$i) 0; set count(A.$i) 0
1020: set count(F.$i) 0
1.1 albertel 1021: }
1022: set count(Y.total) 0; set count(N.total) 0; set count(S.total) 0
1.3 albertel 1023: set count(U.total) 0; set count(u.total) 0; set count(A.total) 0
1024: set count(F.total) 0
1.1 albertel 1025: }
1026: set i -1
1027: foreach char $ans_char {
1028: incr i
1029: if { $char == "-" } { continue }
1030: if { [catch {incr count($char.$i)}] } {
1031: set count(Y.$i) 0; set count(N.$i) 0; set count(S.$i) 0
1.3 albertel 1032: set count(U.$i) 0; set count(u.$i) 0; set count(A.$i) 0
1033: set count(F.$i) 0
1.1 albertel 1034: incr count($char.$i)
1035: }
1036: incr count($char.total)
1037: }
1038: set aline [gets $fileId]
1039: }
1040: close $fileId
1041: removeStatus $num
1.3 albertel 1042: CTputs $num "Prob #: #Y #N #S #U #u #A #F\n"
1.1 albertel 1043: for { set i 0 } { $i < [llength $ans_char] } { incr i } {
1.3 albertel 1044: CTputs $num [format " %2d: %6d %6d %6d %6d %6d %6d %6d\n" [expr $i + 1] \
1045: $count(Y.$i) $count(N.$i) $count(S.$i) $count(U.$i) $count(u.$i) \
1046: $count(A.$i) $count(F.$i) ]
1.1 albertel 1047: }
1048: CTputs $num "===========================================\n"
1.3 albertel 1049: CTputs $num [format " Total: %6d %6d %6d %6d %6d %6d %6d\n" $count(Y.total) \
1050: $count(N.total) $count(S.total) $count(U.total) $count(u.total) \
1051: $count(A.total) $count(F.total) ]
1.1 albertel 1052: set Y_l $count(Y.total)
1053: set N_l $count(N.total)
1054: set S_l $count(S.total)
1055: set U_l $count(U.total)
1056: set u_l $count(u.total)
1.3 albertel 1057: set A_l $count(A.total)
1058: set F_l $count(F.total)
1.1 albertel 1059: return
1060: }
1061:
1062: ###########################################################
1063: # CTcollectSetScores
1064: ###########################################################
1065: ###########################################################
1066: ###########################################################
1067: proc CTcollectSetScores { num path id on_screen limit } {
1068: set id [ string toupper $id ]
1069: set total_scores 0
1070: set total_weights 0
1071: set set_idx 0
1072: set done 0
1073: while { ! $done } {
1074: incr set_idx
1075: if { $set_idx > $limit } { set done 1; continue }
1076: updateStatusBar [expr $set_idx/double($limit)] $num
1077: set filename [file join $path records "set$set_idx.db"]
1078: if { ![file readable $filename ] } { continue }
1079: set fileId [open $filename "r"]
1080: set line_cnt 0
1081: set found 0
1082: set aline [ gets $fileId ]
1083: while { ! [eof $fileId] && ! $found } {
1084: incr line_cnt
1085: if { $line_cnt > 3 } {
1086: set aline [string trim $aline]
1087: set prefix [lindex [split $aline ","] 0]
1088: set s_num [string toupper [lindex [split $aline " "] 0] ]
1089: set ans_str [lindex [split $prefix " "] 1]
1090: if { $id == $s_num } {
1091: set ans_char [split $ans_str {} ]
1092: set valid 0
1093: foreach char $ans_char { if { $char != "-" } { set valid 1; break } }
1094: if { ! $valid } {
1095: set score "-"
1096: } else {
1097: set score 0
1098: for {set i 0} { $i < [llength $ans_char] } { incr i } {
1099: set char [lindex $ans_char $i]
1100: if { $char == "N" || $char == "n"} { set found 1 }
1101: if { $char == "Y" || $char == "y"} {
1102: incr score [lindex $weights $i];set found 1
1103: }
1104: if { $char >= 0 && $char <= 9 } {
1105: incr score $char;set found 1
1106: }
1107: if { $char == "E" } {
1108: incr valid_weights "-[lindex $weights $i]"
1109: }
1110: }
1111: incr total_scores $score
1112: }
1113: }
1114: } elseif { $line_cnt == 2 } {
1115: set aline [string trim $aline]
1116: set weights [split $aline {} ]
1117: set valid_weights 0
1118: foreach weight $weights { incr valid_weights $weight }
1119: } else {
1120: #do nothing for line 1 and 3
1121: }
1122: set aline [ gets $fileId ]
1123: }
1124: close $fileId
1125: incr total_weights $valid_weights
1126: set set_weights([expr $set_idx - 1]) $valid_weights
1127: if { $found } {
1128: set set_scores([expr $set_idx - 1]) $score
1129: } else {
1130: set set_scores([expr $set_idx - 1]) "-"
1131: }
1132: }
1133: set abscent_cnt 0
1134: set present_cnt 0
1135: set summary_str ""
1136: if { $on_screen } { CTputs $num " " }
1137: foreach i [lsort -integer [array names set_scores]] {
1138: if { $set_scores($i) == "-" || $set_scores($i) == "" } {
1139: if { $on_screen } { CTputs $num " - " }
1140: append summary_str "x/$set_weights($i) "
1141: incr abscent_cnt
1142: } else {
1143: if { $on_screen } { CTputs $num [format " %3d" $set_scores($i)] }
1144: append summary_str "$set_scores($i)/$set_weights($i) "
1145: incr present_cnt
1146: }
1147: }
1148: if { $on_screen } {
1149: CTputs $num "\n [file tail $path]:"
1150: foreach i [lsort -integer [array names set_scores]] { CTputs $num " ---" }
1151: CTputs $num "\n "
1152: if { [info exists set_weights] } {
1153: set num_set_weights [llength [array names set_weights]]
1154: } else {
1155: set num_set_weights 0
1156: }
1157: for {set i 0} {$i < $num_set_weights} {incr i} {
1158: if { [info exists set_weights($i)] } {
1159: CTputs $num [format " %3d" $set_weights($i)]
1160: } else {
1161: set num_set_weights $i
1162: }
1163: }
1164: CTputs $num "\n"
1165: if { $total_weights != 0 } {
1166: set ratio [expr 100.0 * $total_scores / double($total_weights) ]
1167: CTputs $num [format " %5d\n" $total_scores]
1168: if { [info exists set_scores] } {
1169: CTputs $num [format " ------- = %3.2f%%, scores absent in %d/%d\n" \
1170: $ratio $abscent_cnt [llength [array names set_scores]]]
1171: } else {
1172: CTputs $num [format " ------- = %3.2f%%, scores absent in %d/%d\n" \
1173: $ratio $abscent_cnt 0 ]
1174: }
1175: } else {
1176: set ratio "-"
1177: CTputs $num [format " %5d\n" $total_scores]
1178: if { [info exists set_scores] } {
1179: CTputs $num [format " ------- = %s%%, scores absent in %d/%d\n" \
1180: $ratio $abscent_cnt [llength [array names set_scores]]]
1181: } else {
1182: CTputs $num [format " ------- = %s%%, scores absent in %d/%d\n" \
1183: $ratio $abscent_cnt 0 ]
1184: }
1185: }
1186:
1187: CTputs $num [format " %5d\n" $total_weights]
1188: }
1189: return [list $total_scores $total_weights $abscent_cnt \
1190: [llength [array names set_scores] ] $summary_str]
1191: }
1192:
1193: ###########################################################
1194: # CTloginAnalysis
1195: ###########################################################
1196: ###########################################################
1197: ###########################################################
1198: proc CTloginAnalysis { num path id limit } {
1199:
1200: CTputs $num "Login analysis: telnet session web session\n\n"
1201: CTputs $num " set #: #Y #N #S #U #u #Y #N #S #U #u\n"
1202: set set_idx 0
1203: set done 0
1204: while { ! $done } {
1205: incr set_idx
1206: if { $set_idx > $limit } { set done 1; continue }
1207: CTputs $num [format " %2d: " $set_idx]
1208: set filename [file join $path records "log$set_idx.db"]
1209: updateStatusMessage "Analyzing [file tail $filename]" $num
1210: updateStatusBar 0.0 $num
1211: if { [file readable $filename] } {
1212: set result [CTstudentLoginData $num $filename $id]
1213: CTputs $num [eval format \"%4d %4d %4d %4d %4d\" $result]
1214: set no_log 0
1215: } else {
1216: CTputs $num "========================"
1217: set no_log 1
1218: }
1219: CTputs $num " "
1220: set filename [file join $path records "weblog$set_idx.db"]
1221: updateStatusMessage "Analyzing [file tail $filename]" $num
1222: updateStatusBar 0.0 $num
1223: if { [file readable $filename] } {
1224: set result [CTstudentLoginData $num $filename $id]
1225: CTputs $num [eval format \"%4d %4d %4d %4d %4d\" $result]
1226: set no_weblog 0
1227: } else {
1228: CTputs $num "========================"
1229: set no_weblog 1
1230: }
1231: CTputs $num "\n"
1232: if { $no_log && $no_weblog } { set done 1 }
1233: }
1234: }
1235:
1236: ###########################################################
1237: # CTstudentSetAnalysis
1238: ###########################################################
1239: ###########################################################
1240: ###########################################################
1241: proc CTstudentSetAnalysis { num path id limit } {
1242: set set_idx 0
1243: set id [string toupper $id]
1244: CTputs $num " set \#:\n"
1245: set done 0
1246: while { ! $done } {
1247: incr set_idx
1248: if { $set_idx > $limit } { set done 1; continue }
1249: set filename [file join $path records "set$set_idx.db"]
1250: updateStatusMessage "Analyzing [file tail $filename]" $num
1251: if { ![file readable $filename] } { continue }
1252: CTputs $num [format " %2d: " $set_idx]
1253: set fileId [open $filename "r"]
1254: set line_cnt 0
1255: set found 0
1256: set aline [gets $fileId]
1257: while { ! [eof $fileId] && !$found } {
1258: incr line_cnt
1259: if { $line_cnt > 3 } {
1260: set aline [string trim $aline]
1261: set s_id [string toupper [string range $aline 0 8]]
1262: if {$id == $s_id} {
1263: set found 1
1264: set breakpt [string first "," $aline]
1265: set data [list [string range $aline 10 [expr $breakpt - 1] ] \
1266: [string range $aline [expr $breakpt + 1] end ] ]
1267: CTputs $num "[lindex $data 0]\n [lindex $data 1]\n"
1268: }
1269: }
1270: set aline [gets $fileId]
1271: }
1272: close $fileId
1273: if { ! $found } { CTputs $num "\n\n" }
1274: }
1275: }
1276:
1277: ###########################################################
1278: # CTstudentLoginData
1279: ###########################################################
1280: ###########################################################
1281: ###########################################################
1282: proc CTstudentLoginData { num filename id } {
1283:
1284: set Y_total 0
1285: set N_total 0
1286: set U_total 0
1287: set u_total 0
1288: set S_total 0
1289: set maxLine [expr double([lindex [exec wc $filename] 0])]
1290: set line_cnt 0
1291: set fileId [open $filename "r"]
1292: set aline [gets $fileId]
1293: while { ![eof $fileId] } {
1294: incr line_cnt
1295: if { $line_cnt%300 == 0 } {
1296: updateStatusBar [expr $line_cnt/$maxLine] $num
1297: }
1298: set aline [string trim $aline]
1299: set s_id [string toupper [string range $aline 0 8]]
1300: set id [string toupper $id]
1301: if {$id == $s_id} {
1302: set ans_char [split [string range $aline 35 end] {} ]
1303: for {set i 0} {$i< [llength $ans_char]} {incr i} {
1304: if {[lindex $ans_char $i] == "Y"} { incr Y_total
1305: } elseif {[lindex $ans_char $i] == "N"} { incr N_total
1306: } elseif {[lindex $ans_char $i] == "U"} { incr U_total
1307: } elseif {[lindex $ans_char $i] == "u"} { incr u_total
1308: } elseif {[lindex $ans_char $i] == "S"} { incr S_total }
1309: }
1310: }
1311: set aline [gets $fileId]
1312: }
1313: close $fileId
1314: return [list $Y_total $N_total $S_total $U_total $u_total]
1315: }
1316:
1317: ###########################################################
1318: # CTrunCommand
1319: ###########################################################
1320: ###########################################################
1321: ###########################################################
1322: proc CTrunCommand { num cmdnum fileId {followup "" }} {
1323: global gCT
1324:
1325: set data [read $fileId]
1326: updateStatusSpinner $cmdnum
1327: if { $data != "" } {
1328: CTputs $cmdnum $data
1329: }
1330: if { [eof $fileId] } {
1331: fileevent $fileId readable ""
1332: catch {close $fileId}
1333: if { $followup == "" } {
1334: CToutput $num $cmdnum
1335: removeStatus $cmdnum
1336: unset gCT(cmd.$cmdnum)
1337: } else {
1338: eval $followup
1339: }
1340: }
1341: }
1342:
1343: ###########################################################
1344: # CTitemAnalysisRange
1345: ###########################################################
1346: ###########################################################
1347: ###########################################################
1.9 albertel 1348: proc CTitemAnalysisRange { num classpath sets } {
1349: foreach i $sets {
1.1 albertel 1350: if { [ catch { CTitemAnalysis $num $classpath $i } errors ] } {
1351: displayError $errors
1352: }
1353: }
1354: }
1355:
1356: ###########################################################
1357: # CTitemAnalysis
1358: ###########################################################
1359: ###########################################################
1360: ###########################################################
1361: proc CTitemAnalysis { num classpath setId } {
1362: global gMaxSet
1363: set done 0
1364:
1365: set total_scores 0
1366: set total_weights 0
1367: set upper_percent 0.0
1368: set lower_percent 0.0
1369:
1370: set Y_total 0
1371: set N_total 0
1372: for { set ii 0} { $ii<$gMaxSet } {incr ii} {
1373: set Y_cnt($ii) 0
1374: set N_cnt($ii) 0
1375: set Ycnt_upper($ii) 0.0
1376: set Ycnt_lower($ii) 0.0
1377: }
1378:
1379: set filename [file join $classpath records "set$setId.db"]
1380: if { ! [file readable $filename] } {
1381: CTputs $num "FILE: $filename does not exist!\n"
1382: return
1383: }
1384:
1385: displayStatus "Analyzing [file tail $filename]" both $num
1386: set maxLine [lindex [exec wc $filename] 0]
1387:
1388: set fileId [open "$filename" "r"]
1389: set valid_cnt 0
1390: set line_cnt 0
1391: set ans_char ""
1392: set aline [gets $fileId]
1393: while {![eof $fileId]} {
1394: incr line_cnt
1395: if { ($line_cnt%20) == 0 } {
1396: updateStatusBar [expr $line_cnt/double($maxLine)] $num
1397: }
1398: if { $line_cnt == 2 } {
1399: set aline [string trim $aline]
1400: set weights [split $aline {}]
1401: # set valid_weights 0
1402: # for { set ii 0 } { $ii < [llength $weights] } { incr ii } {
1403: # incr valid_weights [lindex $weights $ii]
1404: # }
1405: } elseif { $line_cnt > 3} {
1406: set aline [string trim $aline]
1407: set prefix [lindex [split $aline ","] 0]
1408: set s_num [string toupper [lindex [split $aline " " ] 0 ] ]
1409: set ans_str [lindex [split $prefix " "] 1]
1410: set ans_char [split $ans_str {} ]
1411: set valid 0
1412: for { set ii 0 } { $ii < [llength $ans_char] } { incr ii } {
1413: if { [lindex $ans_char $ii] != "-"} { set valid 1 }
1414: }
1415: if { $valid } {
1416: incr valid_cnt
1417: set score 0
1418: for { set ii 0 } { $ii < [llength $ans_char] } { incr ii } {
1.9 albertel 1419: #Can't use incr because the numbers might be doubles
1.1 albertel 1420: if { [lindex $ans_char $ii] == "Y" || \
1421: [lindex $ans_char $ii] == "y" } {
1.9 albertel 1422: catch {incr score [lindex $weights $ii]}
1423: set Y_cnt($ii) [expr {$Y_cnt($ii) + 1}]
1424: set Y_total [expr {$Y_total + 1}]
1.1 albertel 1425: }
1426: if { [lindex $ans_char $ii] == "N" || \
1427: [lindex $ans_char $ii] == "n" } {
1.9 albertel 1428: set N_cnt($ii) [expr {$N_cnt($ii) + 1}]
1429: set N_total [expr {$N_total + 1}]
1.1 albertel 1430: }
1431: if { [lindex $ans_char $ii] >= 0 && \
1432: [lindex $ans_char $ii] <= 9 } {
1433: incr score [lindex $ans_char $ii]
1.9 albertel 1434: if {[catch {set yes_part [expr [lindex $ans_char $ii] / \
1435: double([lindex $weights $ii])]}]} {
1436: set yes_part 1
1437: }
1.1 albertel 1438: set no_part [expr 1.0 - $yes_part]
1439: set Y_cnt($ii) [expr $Y_cnt($ii) + $yes_part]
1440: set Y_total [expr $Y_total + $yes_part]
1441: set N_cnt($ii) [expr $N_cnt($ii) + $no_part]
1442: set N_total [expr $N_total + $no_part]
1443: }
1444: # if { [lindex $ans_char $ii] == "E"} {
1445: # incr valid_weights -[lindex $weights $ii]
1446: # }
1447: }
1448: set s_db([format "%08d%s" $score $s_num]) $ans_str
1449: }
1450: }
1451: set aline [gets $fileId]
1452: }
1453: close $fileId
1454: removeStatus $num
1455: for { set ii 0 } { $ii < $gMaxSet } { incr ii } {
1456: set Ycnt_upper($ii) 0
1457: set Ycnt_lower($ii) 0
1458: }
1459: displayStatus "Pondering data . . ." spinner $num
1460: set upperpart_cnt [expr int(0.27 * double($valid_cnt))]
1461: set lowerpart_limit [expr $valid_cnt - $upperpart_cnt]
1462: set line_cnt 0
1463: foreach sort_key [lsort -decreasing [array names s_db]] {
1464: incr line_cnt
1465: if { ($line_cnt%20) == 0 } { updateStatusSpinner $num }
1466: set ans_str $s_db($sort_key)
1467: set ans_char [split $ans_str {} ]
1468: for { set ii 0 } { $ii < [llength $ans_char] } { incr ii } {
1469: if { [lindex $ans_char $ii] == "Y" || \
1470: [lindex $ans_char $ii] == "y" || \
1471: [lindex $ans_char $ii] == [lindex $weights $ii] } {
1472: if { $line_cnt <= $upperpart_cnt } {
1473: incr Ycnt_upper($ii)
1474: } elseif { $line_cnt > $lowerpart_limit } {
1475: incr Ycnt_lower($ii)
1476: }
1477: }
1478: }
1479: }
1480: CTputs $num " There are $valid_cnt entries in file $filename\n"
1481: CTputs $num [format " The upper 27%% has %d records, the lower 27%% has %d records\n"\
1482: $upperpart_cnt [expr $valid_cnt - $lowerpart_limit] ]
1483: CTputs $num " question \# DoDiff. Disc. Factor (%upper - %lower) \[\#records,\#records\]\n";
1484:
1485: for { set ii 0 } { $ii < [llength $ans_char] } { incr ii } {
1486: updateStatusSpinner $num
1487: set tmp_total [expr $N_cnt($ii) + $Y_cnt($ii)]
1488: if { $tmp_total > 0 } {
1489: set diff [expr 100.0*($N_cnt($ii) / double($N_cnt($ii) + $Y_cnt($ii)))]
1490: } else {
1491: set diff "-"
1492: }
1493: set upper_percent [expr 100.0 * ($Ycnt_upper($ii) /double($upperpart_cnt))]
1494: set lower_percent [expr 100.0 * ($Ycnt_lower($ii) /double($upperpart_cnt))]
1495: set disc [expr $upper_percent - $lower_percent]
1496: CTputs $num [format " %2d: " [expr $ii + 1]]
1497: CTputs $num [format "%6.1f %5.1f (%6.1f - %6.1f) \[%8d,%8d\]\n" \
1498: $diff $disc $upper_percent $lower_percent $Ycnt_upper($ii) \
1499: $Ycnt_lower($ii) ]
1500: }
1501: removeStatus $num
1502: }
1503:
1504: ###########################################################
1505: # CTitemCorrelation
1506: ###########################################################
1507: # INPUTS: class name with full path, set number
1508: #
1509: # r = \frac{\sum{x_i y_i} - \frac{(\sum x_i)(\sum y_i)}{n}}
1510: # {\sqrt{(\sum x_i^2 - \frac{}{}}}
1511: #
1512: # corr = (sum of prod_xy - (sum_x*sum_y / n) ) / sqrt( (sum of sqr_x - (sum_x*sum_x/n))*
1513: #
1514: ###########################################################
1515: ###########################################################
1516: proc CTitemCorrelation { num classpath setId } {
1517: global gMaxSet
1518:
1519: set filename [file join $classpath records "set$setId.db"]
1520: if { ! [file readable $filename] } {
1521: CTputs $num "FILE: $filename does not exist!\n"
1522: return
1523: }
1524:
1525: displayStatus "Analyzing [file tail $filename]" both $num
1526: set maxLine [lindex [exec wc $filename] 0]
1527:
1528: set initialized 0
1529: set question_cnt 0
1530: set fileId [open "$filename" "r"]
1531: set line_cnt 0
1532: set aline [gets $fileId]
1533: while {![eof $fileId]} {
1534: incr line_cnt
1535: if { ($line_cnt%20) == 0 } {
1536: updateStatusBar [expr {$line_cnt/double($maxLine)}] $num
1537: }
1538: if { $line_cnt == 2 } {
1.4 albertel 1539: set aline [string trimright $aline]
1.1 albertel 1540: set weights [split $aline {}]
1541: }
1542: if { $line_cnt > 3} {
1.4 albertel 1543: set aline [string trimright $aline]
1.1 albertel 1544: set data [string range $aline 10 end]
1545: set ans_str [lindex [split $data ","] 0]
1546: set ans_char_list [split $ans_str {} ]
1547: set try_str [string range $aline [expr {[string first "," $data] +1}] end ]
1548: set question_cnt [llength $ans_char_list]
1549: for { set ii 0 } { $ii < $question_cnt } { incr ii } {
1550: set ans_char($ii) [lindex $ans_char_list $ii]
1551: }
1552: if { $question_cnt > $initialized } {
1553: for {set ii 0} {$ii < [expr {$question_cnt - 1}]} {incr ii} {
1554: set start [expr {($initialized>($ii+1)) ? $initialized : ($ii+1)}]
1555: for { set jj $start } { $jj < $question_cnt } { incr jj } {
1556: set index_key "$ii.$jj"
1557: set prod_xy($index_key) 0.0
1558: set sum_x($index_key) 0
1559: set sum_y($index_key) 0
1560: set sum_x2($index_key) 0
1561: set sum_y2($index_key) 0
1562: set valid_cnt($index_key) 0
1563: }
1564: }
1565: set initialized $question_cnt
1566: }
1567: for { set ii 0 } { $ii < [expr {$question_cnt - 1}] } { incr ii } {
1568: for { set jj [expr {$ii+1}] } { $jj < $question_cnt } { incr jj } {
1569: set index_key "$ii.$jj"
1570: if { $ans_char($ii) != "-" && $ans_char($ii) != "E" && \
1571: $ans_char($jj) != "-" && $ans_char($jj) != "E" } {
1572: ## $ans_char($ii) is one of 0 .. 9, Y, y, N, n
1573: ## $ans_char($jj) is one of 0 .. 9, Y, y, N, n
1574: if { $ans_char($ii) == "Y" || $ans_char($ii) == "y" } {
1575: set x_data [lindex $weights $ii]
1576: } elseif { $ans_char($ii) == "N" || $ans_char($ii) == "n" } {
1577: set x_data 0
1578: } else { ## must be in 0 .. 9
1579: set x_data $ans_char($ii)
1580: }
1581: if { $ans_char($jj) == "Y" || $ans_char($jj) == "y" } {
1582: set y_data [lindex $weights $jj]
1583: } elseif { $ans_char($jj) == "N" || $ans_char($jj) == "n" } {
1584: set y_data 0
1585: } else { ## must be in 0 .. 9
1586: set y_data $ans_char($jj)
1587: }
1588: set prod_xy($index_key) [expr {$x_data * $y_data +
1589: $prod_xy($index_key)} ]
1590: incr sum_x($index_key) $x_data
1591: incr sum_y($index_key) $y_data
1592: incr sum_x2($index_key) [expr {$x_data * $x_data}]
1593: incr sum_y2($index_key) [expr {$y_data * $y_data}]
1594: incr valid_cnt($index_key) 1
1595: }
1596: }
1597: }
1598: }
1599: set aline [gets $fileId]
1600: }
1601: close $fileId
1602: removeStatus $num
1603: # print out the correlation matrix
1.4 albertel 1604: #parray sum_x
1605: #parray sum_y
1606: #parray prod_xy
1607: #puts $question_cnt
1.1 albertel 1608: CTputs $num " "
1609: for { set ii 1 } { $ii < $question_cnt } { incr ii } {
1610: CTputs $num [format " %2d" [expr {$ii+1}] ]
1611: }
1612: CTputs $num "\n"
1613: # --------------------------------------
1614: for { set ii 0 } { $ii < [expr {$question_cnt -1}] } { incr ii } {
1615: CTputs $num [format " %2d:" [expr {$ii+1}] ]
1616: for { set jj 0 } { $jj < $ii } { incr jj } { CTputs $num " " }
1617: for { set jj [expr {$ii+1}] } { $jj < $question_cnt } { incr jj } {
1618: set index_key "$ii.$jj"
1619: if { $valid_cnt($index_key) != "0" } {
1620: set upper_part [ expr { $prod_xy($index_key) -
1621: ( ($sum_x($index_key) * $sum_y($index_key))
1622: / double($valid_cnt($index_key)))}]
1623: set lower_part [expr {$sum_x2($index_key) -
1624: ($sum_x($index_key) * $sum_x($index_key)
1625: / double($valid_cnt($index_key)))} ]
1626: set lower_part [expr {$lower_part * ($sum_y2($index_key) -
1627: ($sum_y($index_key) *
1628: $sum_y($index_key)
1629: /double($valid_cnt($index_key))))}]
1630: set lower_part [expr {sqrt($lower_part)}]
1631: if { $lower_part != 0.0 } {
1632: set ratio [expr {$upper_part / double($lower_part)}]
1633: CTputs $num [format " % .2f" $ratio]
1634: } else {
1635: CTputs $num " INF "
1636: }
1637: } else {
1638: CTputs $num " ----"
1639: }
1640: }
1641: CTputs $num "\n"
1642: }
1643: }
1644:
1645: ###########################################################
1646: # CTsubmissionsLaunch
1647: ###########################################################
1648: ###########################################################
1649: ###########################################################
1.9 albertel 1650: proc CTsubmissionsLaunch { num cmdnum type s_id s_nm index setlist } {
1.1 albertel 1651: global gCT gFile gUniqueNumber gCapaConfig
1652:
1.9 albertel 1653: set curset [lindex $setlist $index]
1654: CTputs $cmdnum "$type submissions for $s_nm for set $curset\n"
1.1 albertel 1655: if { $type == "telnet" } {
1.9 albertel 1656: set command "grep -i $s_id [file join $gFile($num) records submissions$curset.db]"
1.1 albertel 1657: set followtype web
1658: } else {
1659: set command "grep -i $s_id [file join $gFile($num) \
1.9 albertel 1660: records websubmissions$curset.db]"
1.1 albertel 1661: set followtype telnet
1.9 albertel 1662: incr index
1.1 albertel 1663: }
1664: set done 0
1665: set followcmd ""
1.9 albertel 1666: while { !$done && ($index <= [llength $setlist]) } {
1667: if { [lindex $setlist $index] != "" } {
1.1 albertel 1668: set followcmd "CTsubmissionsLaunch $num $cmdnum $followtype $s_id {$s_nm} \
1.9 albertel 1669: $index \"$setlist\""
1.1 albertel 1670: }
1.9 albertel 1671: if { ![catch {set fileId [open "|$command" "r"]} error ] } { set done 1 }
1.1 albertel 1672: }
1673: fconfigure $fileId -blocking 0
1674: fileevent $fileId readable "CTrunCommand $num $cmdnum $fileId {$followcmd}"
1675: }
1676:
1677: ###########################################################
1678: # CTreportDist
1679: ###########################################################
1680: ###########################################################
1681: ###########################################################
1682: proc CTreportDist { num file percentage sectionlist } {
1683: set fileId [open $file "r"]
1684: set aline [gets $fileId]
1685: set which [expr [llength [split $aline "\t"]] - 2]
1686: set maximum [lindex [lrange [split $aline "\t"] $which end] 1]
1687: if { $percentage } {
1688: for {set i 0} {$i<=100} {incr i} {
1689: set totals($i.score) 0
1690: set totals($i.stunum) ""
1691: }
1692: } else {
1693: for { set i 0 } { $i <= $maximum } { incr i } {
1694: set totals($i.score) 0
1695: set totals($i.stunum) ""
1696: }
1697: }
1698: while { ![eof $fileId]} {
1699: set temp [lrange [split $aline "\t"] $which end]
1700: set score [lindex $temp 0]
1701: regsub -- "-" $score "0" score
1702: set max [lindex $temp 1]
1703: set temp [lindex [split $aline "\t"] 1]
1704: set section [lindex $temp 1]
1705: set stunum [lindex $temp 0]
1706: if { ([lsearch $sectionlist $section] != -1) && ($max!=0) } {
1707: if { $percentage } {
1708: set percent [expr int($score/double($max)*100)]
1709: incr totals($percent.score)
1710: lappend totals($percent.stunum) $stunum
1711: } else {
1712: if { $max > $maximum } {
1713: for {set i [expr $maximum+1]} {$i<=$max} {incr i} {set totals($i) 0}
1714: set maximum $max
1715: }
1716: set score [string trim $score]
1717: incr totals($score.score)
1718: lappend totals($score.stunum) $stunum
1719: }
1720: }
1721: set aline [gets $fileId]
1722: }
1723: CTputs $num "Scores #acheived\n"
1724: set scorelist ""
1725: set templist [array names totals *.score]
1726: foreach temp $templist {lappend possiblescores [lindex [split $temp .] 0]}
1727: foreach score [lsort -integer $possiblescores] {
1728: CTputs $num [format "%5d:%6d\n" $score $totals($score.score)]
1729: lappend scorelist [list $totals($score.score) $score $totals($score.stunum)]
1730: }
1731: return $scorelist
1732: }
1733:
1734: ###########################################################
1735: # CTgradeDistribution
1736: ###########################################################
1737: ###########################################################
1738: ###########################################################
1739: proc CTgradeDistribution { num classpath setId } {
1740: set filename [file join $classpath records "set$setId.db"]
1741: if { ! [file readable $filename] } {
1742: CTputs $num "FILE: $filename does not exist!\n"
1743: return
1744: }
1745:
1746: displayStatus "Analyzing [file tail $filename]" both $num
1747: set maxLine [lindex [exec wc $filename] 0]
1748: set fileId [open "$filename" "r"]
1749: set valid_cnt 0
1750: set line_cnt 0
1751: set aline [gets $fileId]
1752: while {![eof $fileId]} {
1753: incr line_cnt
1754: if { ($line_cnt%20) == 0 } {
1755: updateStatusBar [expr $line_cnt/double($maxLine)] $num
1756: }
1757: if { $line_cnt == 2 } {
1758: set aline [string trim $aline]
1759: set weights [split $aline {}]
1760: set valid_weights 0
1761: foreach weight $weights { incr valid_weights $weight }
1762: for { set i 0 } { $i <= $valid_weights } { incr i } {
1763: set total_score($i) 0
1764: }
1765: } elseif { $line_cnt > 3} {
1766: set aline [string trim $aline]
1767: set prefix [lindex [split $aline ","] 0]
1768: set s_num [string toupper [lindex [split $aline " " ] 0 ] ]
1769: set ans_str [lindex [split $prefix " "] 1]
1770: set ans_char [split $ans_str {} ]
1771: set valid 0
1772: for { set ii 0 } { $ii < [llength $ans_char] } { incr ii } {
1773: if { [lindex $ans_char $ii] != "-"} { set valid 1 }
1774: }
1775: if { $valid } {
1776: incr valid_cnt
1777: set score 0
1778: for { set ii 0 } { $ii < [llength $ans_char] } { incr ii } {
1779: if { [lindex $ans_char $ii] == "Y" || \
1780: [lindex $ans_char $ii] == "y" } {
1781: incr score [lindex $weights $ii]
1782: }
1783: if { [lindex $ans_char $ii] >= 0 && \
1784: [lindex $ans_char $ii] <= 9 } {
1785: incr score [lindex $ans_char $ii]
1786: }
1787: }
1788: if { [catch {incr total_score($score)} ] } {
1789: puts "$aline:$prefix:$s_num:$ans_str:$ans_char"
1790: }
1791:
1792: }
1793: }
1794: set aline [gets $fileId]
1795: }
1796: close $fileId
1797: removeStatus $num
1798: displayStatus "Pondering data . . ." spinner $num
1799: CTputs $num " There are $valid_cnt entries in file $filename\n"
1800: CTputs $num "Score #acheived\n"
1801: set scorelist ""
1802: foreach score [lsort -integer [array names total_score]] {
1803: CTputs $num [format "%5d:%6d\n" $score $total_score($score)]
1804: lappend scorelist [list $total_score($score) $score]
1805: }
1806: removeStatus $num
1807: return $scorelist
1808: }
1809:
1810: ###########################################################
1811: # CTgetStudentScores
1812: ###########################################################
1813: ###########################################################
1814: ###########################################################
1815: proc CTgetStudentScores { studentScoresVar classpath setId num } {
1816: upvar $studentScoresVar studentScores
1817:
1818: set filename [file join $classpath records "set$setId.db"]
1819: if { ! [file readable $filename] } {
1820: CTputs $num "FILE: $filename does not exist!\n"
1821: error
1822: }
1823:
1824: displayStatus "Analyzing [file tail $filename]" both $num
1825: set maxLine [lindex [exec wc $filename] 0]
1826: set fileId [open "$filename" "r"]
1827: set valid_cnt 0
1828: set line_cnt 0
1829: set aline [gets $fileId]
1830: set aline [gets $fileId]
1831: set weights [split [string trim $aline] {}]
1832: set valid_weights 0
1833: foreach weight $weights { incr valid_weights $weight }
1834: set aline [gets $fileId]
1835: set aline [gets $fileId]
1836: while {![eof $fileId]} {
1837: incr line_cnt
1838: if { ($line_cnt%20) == 0 } {
1839: updateStatusBar [expr $line_cnt/double($maxLine)] $num
1840: }
1841: set aline [string trim $aline]
1842: set prefix [lindex [split $aline ","] 0]
1843: set s_num [string toupper [lindex [split $aline " " ] 0 ] ]
1844: set ans_str [lindex [split $prefix " "] 1]
1845: set ans_char [split $ans_str {} ]
1846: set valid 0
1847: for { set ii 0 } { $ii < [llength $ans_char] } { incr ii } {
1848: if { [lindex $ans_char $ii] != "-"} { set valid 1 }
1849: }
1850: if { $valid } {
1851: incr valid_cnt
1852: if {[array names studentScores $s_num] == ""} {set studentScores($s_num) 0}
1853: for { set ii 0 } { $ii < [llength $ans_char] } { incr ii } {
1854: if { [lindex $ans_char $ii] == "Y" || [lindex $ans_char $ii] == "y" } {
1855: incr studentScores($s_num) [lindex $weights $ii]
1856: }
1857: if { [lindex $ans_char $ii] >= 0 && [lindex $ans_char $ii] <= 9 } {
1858: incr studentScores($s_num) [lindex $ans_char $ii]
1859: }
1860: }
1861: }
1862: set aline [gets $fileId]
1863: }
1864: close $fileId
1865: removeStatus $num
1866: return $valid_weights
1867: }
1868:
1869: ###########################################################
1870: # CTgradeDistributionRange
1871: ###########################################################
1872: ###########################################################
1873: ###########################################################
1874: proc CTgradeDistributionRange { num classpath setIdstart setIdend } {
1875: set totalpoints 0
1876: for {set setId $setIdstart} {$setId <= $setIdend} {incr setId} {
1877: set points [CTgetStudentScores studentScores $classpath $setId $num]
1878: incr totalpoints $points
1879: # parray studentScores
1880: }
1881:
1882: displayStatus "Pondering data . . ." spinner $num
1883: for { set i 0 } { $i <= $totalpoints } { incr i } {
1884: set total_score($i) 0
1885: }
1886: foreach sNum [array names studentScores] { incr total_score($studentScores($sNum)) }
1887: CTputs $num "Scores #acheived\n"
1888: set scorelist ""
1889: foreach score [lsort -integer [array names total_score]] {
1890: CTputs $num [format "%5d:%6d\n" $score $total_score($score)]
1891: lappend scorelist [list $total_score($score) $score]
1892: }
1893: removeStatus $num
1894: return $scorelist
1895: }
1896:
1897: #common Input dialogs
1898:
1899: #common output methods
1900: proc CTdatestamp { cmdnum } {
1901: CTputs $cmdnum [clock format [clock seconds]]\n
1902: }
1903:
1904: ###########################################################
1905: # CTputs
1906: ###########################################################
1907: ###########################################################
1908: ###########################################################
1909: proc CTputs { num message {tag normal} } {
1910: global gCT
1911:
1912: lappend gCT(output.$num) [list $message $tag]
1913: }
1914:
1915: ###########################################################
1916: # CToutputWrap
1917: ###########################################################
1918: ###########################################################
1919: ###########################################################
1920: proc CToutputWrap { num } {
1921: global gCT
1922: if { $gCT($num.wrap) } {
1923: $gCT($num.output) configure -wrap char
1924: } else {
1925: $gCT($num.output) configure -wrap none
1926: }
1927: }
1928:
1929: ###########################################################
1930: # CToutput
1931: ###########################################################
1932: ###########################################################
1933: ###########################################################
1934: proc CToutput { num cmdnum } {
1935: global gCT
1936:
1937: if { ![winfo exists $gCT($num).output] } {
1938: set outputWin [toplevel $gCT($num).output]
1939:
1940: set buttonFrame [frame $outputWin.button]
1941: set textFrame [frame $outputWin.text]
1942: set bottomFrame [frame $outputWin.bottom]
1943: pack $buttonFrame $textFrame $bottomFrame
1944: pack configure $buttonFrame -anchor e -expand 0 -fill x
1945: pack configure $textFrame -expand 1 -fill both
1946: pack configure $bottomFrame -expand 0 -fill x
1947:
1948: set gCT($num.output) [text $textFrame.text \
1949: -yscrollcommand "$textFrame.scroll set" \
1950: -xscrollcommand "$bottomFrame.scroll set"]
1951: scrollbar $textFrame.scroll -command "$textFrame.text yview"
1952: pack $gCT($num.output) $textFrame.scroll -side left
1953: pack configure $textFrame.text -expand 1 -fill both
1954: pack configure $textFrame.scroll -expand 0 -fill y
1955:
1956: scrollbar $bottomFrame.scroll -command "$textFrame.text xview" -orient h
1957: pack $bottomFrame.scroll -expand 0 -fill x
1958:
1959: set gCT($num.wrap) 1
1960: checkbutton $buttonFrame.wrap -text "Wrap" -command "CToutputWrap $num" \
1961: -variable gCT($num.wrap)
1962: button $buttonFrame.save -text "Save Text" -command "CTsaveText $num"
1963: button $buttonFrame.print -text "Print Text" -command "CTprintText $num"
1964: button $buttonFrame.dismiss -text "Dismiss" -command "destroy $outputWin"
1965: pack $buttonFrame.wrap $buttonFrame.save $buttonFrame.print \
1966: $buttonFrame.dismiss -side left
1967: }
1.7 albertel 1968: set index [$gCT($num.output) index end-1c]
1.1 albertel 1969: foreach line $gCT(output.$cmdnum) {
1970: eval $gCT($num.output) insert end $line
1971: }
1972: unset gCT(output.$cmdnum)
1973: raise $gCT($num).output
1974: $gCT($num.output) see $index
1975: update idletasks
1976: }
1977:
1978: ###########################################################
1979: # CTsaveText
1980: ###########################################################
1981: # saves the contents of a text window
1982: ###########################################################
1983: # Arguments: num (the unique number of the path, and window)
1984: # Returns : nothing
1985: # Globals :
1986: ###########################################################
1987: proc CTsaveText { num } {
1988: global gFile gCT
1989:
1990: set window $gCT($num.output)
1991: if {![winfo exists $window]} { return }
1992: set dir $gFile($num)
1993: set file ""
1994:
1995: if { $dir == "" || $dir == "."} { set dir [pwd] }
1996: set file [tk_getSaveFile -title "Enter the name to Save As" \
1997: -initialdir "$dir" ]
1998: if { $file == "" } {
1999: displayError "File not saved"
2000: return
2001: }
2002: set fileId [open $file w]
2003: puts -nonewline $fileId [$window get 0.0 end-1c]
2004: close $fileId
2005: }
2006:
2007: ###########################################################
2008: # CTprintText
2009: ###########################################################
2010: # prints the contents of the text window, creates a temp file named
2011: # quiztemp.txt
2012: ###########################################################
2013: # Arguments: num (the unique number of the path, and window)
2014: # Returns : nothing
2015: # Globals : gFile gCT
2016: ###########################################################
2017: proc CTprintText { num } {
2018: global gFile gCT
2019:
2020: set window $gCT($num.output)
2021: if { ![winfo exists $window]} { return }
2022: catch {parseCapaConfig $num $gFile($num)}
2023: set lprCommand [getLprCommand [file join $gFile($num) managertemp.txt] $num]
2024: if {$lprCommand == "Cancel"} { return }
2025:
2026: set fileId [open [file join $gFile($num) managertemp.txt] w]
2027: puts -nonewline $fileId [$window get 0.0 end-1c]
2028: close $fileId
2029:
2030: set errorMsg ""
2031: if { [catch {set output [ eval "exec $lprCommand" ] } errorMsg ]} {
2032: displayError "An error occurred while printing: $errorMsg"
2033: } else {
2034: displayMessage "Print job sent to the printer.\n $output"
2035: }
2036: exec rm -f [file join $gFile($num) mangertemp.txt]
2037: }
2038:
2039: ###########################################################
2040: # CTprintCanvas
2041: ###########################################################
2042: ###########################################################
2043: ###########################################################
2044: proc CTprintCanvas { num window path } {
2045:
2046: if { ![winfo exists $window]} { return }
2047: catch {parseCapaConfig $num $gFile($num)}
2048: set lprCommand [getLprCommand [file join $path managertemp.txt] $num]
2049: if {$lprCommand == "Cancel"} { return }
2050:
2051: set rotate 0
2052: if { [tk_messageBox -title "Print in landscape mode" -message "Would you like to print in landscape mode?" -icon question -type yesno] == "yes" } { set rotate 1 }
2053: $window postscript -file [file join $path managertemp.txt] -rotate $rotate
2054:
2055: set errorMsg ""
2056: if { [catch {set output [ eval "exec $lprCommand" ] } errorMsg ]} {
2057: displayError "An error occurred while printing: $errorMsg"
2058: } else {
2059: displayMessage "Print job sent to the printer.\n $output"
2060: }
2061: exec rm -f [file join $path mangertemp.txt]
2062: }
2063:
2064: ###########################################################
2065: # CTsaveCanvas
2066: ###########################################################
2067: ###########################################################
2068: ###########################################################
2069: proc CTsaveCanvas { window path } {
2070: if { ![winfo exists $window] } { return }
2071: set dir $path
2072: set file ""
2073:
2074: if { $dir == "" } { set dir [pwd] }
2075: set file [tk_getSaveFile -title "Enter the name to Save As" \
2076: -initialdir "$dir" ]
2077: if { $file == "" } {
2078: displayError "File not saved"
2079: return
2080: }
2081: $window postscript -file $file
2082: }
2083:
2084: ###########################################################
2085: # CTbargraph
2086: ###########################################################
2087: ###########################################################
2088: ###########################################################
2089: proc CTbargraph {window num barnum data {path ""} {title "" } {xlabel ""} {ylabel ""}
2090: {suffix ""} } {
2091: global gBarGraph
2092: set height 300
2093: set width 500
2094:
2095: global gWindowMenu
2096:
2097: set bargraph [toplevel $window.bargraph$barnum]
2098: if { $title != "" } { wm title $bargraph $title }
2099: $gWindowMenu add command -label "$title $barnum" -command "capaRaise $bargraph"
2100:
2101: set buttonFrame [frame $bargraph.buttons]
2102: set canvasFrame [frame $bargraph.canvas]
2103: pack $buttonFrame $canvasFrame -side top
2104: pack configure $canvasFrame -expand 1 -fill both
2105:
2106: set canvas [canvas $canvasFrame.canvas -height $height -width $width -background white]
2107: pack $canvas -expand 1 -fill both
2108: bind $canvas <Configure> "CTdrawBargraph $barnum"
2109:
2110: button $buttonFrame.change -text "Change Graph" -command "CTchangeBargraph $window $barnum"
2111: button $buttonFrame.save -text "Save Graph" -command "CTsaveCanvas $canvas $path"
2112: button $buttonFrame.print -text "Print Graph" -command "CTprintCanvas $num $canvas $path"
2113: button $buttonFrame.dismiss -text "Dismiss" -command "CTdestroyBargraph $barnum"
2114: pack $buttonFrame.change $buttonFrame.save $buttonFrame.print \
2115: $buttonFrame.dismiss -side left
2116: bind $bargraph <Destroy> "CTdestroyBargraph $barnum"
2117:
2118: set gBarGraph($barnum.num) $num
2119: set gBarGraph($barnum.suffix) $suffix
2120: set gBarGraph($barnum) $data
2121: set gBarGraph($barnum.canvas) $canvas
2122: set gBarGraph($barnum.title) $title
2123: set gBarGraph($barnum.xlabel) $xlabel
2124: set gBarGraph($barnum.ylabel) $ylabel
2125: set gBarGraph($barnum.color) green
2126: set gBarGraph($barnum.bucketscores) 0
2127: CTautoscaleBargraph $barnum
2128: CTdrawBargraph $barnum
2129: }
2130:
2131: ###########################################################
2132: # CTautoscaleBargraph
2133: ###########################################################
2134: ###########################################################
2135: ###########################################################
2136: proc CTautoscaleBargraph { barnum } {
2137: global gBarGraph
2138: set data $gBarGraph($barnum)
2139: set max [lindex [lindex [lsort -decreasing -index 0 -real $data] 0] 0]
2140: if { $max > int($max) } { set max [expr int($max+1)] }
2141: set gBarGraph($barnum.yoften) [expr int([format "%1.e" [expr $max/10.0]])]
2142: if { $gBarGraph($barnum.yoften) == 0 } { set gBarGraph($barnum.yoften) 1 }
2143: set total [llength $data]
2144: set gBarGraph($barnum.xoften) [expr ($total/25) + 1]
2145: }
2146:
2147: ###########################################################
2148: # CTchangeBargraphData
2149: ###########################################################
2150: ###########################################################
2151: ###########################################################
2152: proc CTchangeBargraphData { barnum data } {
2153: global gBarGraph
2154: set gBarGraph($barnum) $data
2155: CTautoscaleBargraph $barnum
2156: CTdrawBargraph $barnum
2157: }
2158:
2159: ###########################################################
2160: # CTdestroyBargraph
2161: ###########################################################
2162: ###########################################################
2163: ###########################################################
2164: proc CTdestroyBargraph { num } {
2165: global gBarGraph
2166:
2167: if { [catch {set window [winfo toplevel $gBarGraph($num.canvas)]}]} { return }
2168: set window2 [file rootname $window].changeBarGraph$num
2169: foreach name [array names gBarGraph "$num.*" ] {
2170: unset gBarGraph($name)
2171: }
2172: unset gBarGraph($num)
2173: destroy $window
2174: catch {destroy $window2}
2175: }
2176:
2177: ###########################################################
2178: # CTdrawBargraph
2179: ###########################################################
2180: ###########################################################
2181: ###########################################################
2182: proc CTdrawBargraph { num } {
2183: global gBarGraph
2184:
2185: set data $gBarGraph($num)
2186: set canvas $gBarGraph($num.canvas)
2187: set suffix $gBarGraph($num.suffix)
2188:
2189: set height [winfo height $canvas]
2190: set width [winfo width $canvas]
2191: set titleoffset 0
2192: set titleheight 15
2193: set labelheight 15
2194: set tickheight 15
2195: set textheight [expr $labelheight+$tickheight]
2196: set textwidth 40
2197: set graphheight [expr $height - $textheight - $titleheight]
2198: set graphwidth [expr $width - $textwidth]
2199: $canvas delete all
2200:
2201: #draw data
2202: set total [llength $data]
2203: set eachwidth [expr $graphwidth/$total]
2204: # set howoften [expr ($total/$gBarGraph($num.numlabels)) + 1]
2205: set howoften $gBarGraph($num.xoften)
2206: set when [expr ($total-1)%$howoften]
2207: set max 0
2208: set i 0
2209: set value 0
2210: if { $gBarGraph($num.bucketscores) } {
2211: foreach datum $data {
2212: set value [expr {$value + [lindex $datum 0]}]
2213: if { $i % $howoften == $when } {
2214: if { $value > $max } { set max $value }
2215: set value 0
2216: }
2217: incr i
2218: }
2219: } else {
2220: set max [lindex [lindex [lsort -decreasing -index 0 -real $data] 0] 0]
2221: }
2222: if { $max > int($max) } { set max [expr int($max+1)] }
2223: if { [catch {set pixelvalue [expr ($graphheight-1)/double($max)]} ] } {
2224: set pixelvalue 10
2225: }
2226: set i 0
2227: set value 0
2228: foreach datum $data {
2229: set value [expr {$value + [lindex $datum 0]}]
2230: set which [lindex $datum 1]
2231: set y1 [expr {$graphheight + $titleheight}]
2232: set x2 [expr {$eachwidth * ($i+1) + $textwidth}]
2233: set y2 [expr {($graphheight-1) + $titleheight - $value * $pixelvalue}]
2234: set tag bar.$which.[expr $which-$howoften]
2235: if { [set color [lindex $datum 3]] == "" } {set color $gBarGraph($num.color)}
2236: if { $gBarGraph($num.bucketscores) && ($i % $howoften == $when) } {
2237: if { $i == $when } {
1.6 albertel 2238: # puts "$value-$which-$howoften"
1.1 albertel 2239: $canvas create rectangle $textwidth \
2240: $y1 $x2 $y2 -fill $color -tag $tag
2241: } else {
1.6 albertel 2242: # puts "$value:$which:$howoften"
1.1 albertel 2243: $canvas create rectangle [expr {$eachwidth*($i-$howoften+1)+$textwidth}]\
2244: $y1 $x2 $y2 -fill $color -tag $tag
2245: }
2246: } elseif { !$gBarGraph($num.bucketscores) } {
2247: $canvas create rectangle [expr {$eachwidth * $i + $textwidth}] \
2248: $y1 $x2 $y2 -fill $color -tag bar.$which.[expr $which-1]
2249: set value 0
2250: }
2251: if { $i % $howoften == $when } {
2252: $canvas create text [expr {$eachwidth * $i + $textwidth + $eachwidth/2}] \
2253: [expr $graphheight+(($tickheight)/2)+$titleheight] -text $which
2254: set value 0
2255: }
2256: incr i
2257: }
2258:
2259: #draw title
2260: $canvas create text [expr $textwidth+$titleoffset+($graphwidth/2)] 1 -anchor n\
2261: -text $gBarGraph($num.title)
2262: #draw axis
2263: $canvas create line $textwidth [expr {$graphheight + $titleheight}] \
2264: $textwidth [expr {$titleheight + 1}]
2265: #label xaxis
2266: $canvas create text [expr ($textwidth+($graphwidth/2))] \
2267: [expr $titleheight+$graphheight+$tickheight+($labelheight/2)] \
2268: -text $gBarGraph($num.xlabel)
2269: #label yaxis
2270: $canvas create text 1 1 -anchor nw -text $gBarGraph($num.ylabel)
2271: #draw tickmarks
2272: # set delta [format "%1.e" [expr ($max)/double($gBarGraph($num.numticks))]]
2273: set delta $gBarGraph($num.yoften)
2274: set start 0.0
2275: while { $start < $max } {
2276: set center [expr {($graphheight-1)*(($start)/$max)+$titleheight+1}]
2277: $canvas create line $textwidth $center [expr $textwidth - 20] $center
2278: $canvas create text [expr $textwidth-3] $center -anchor ne -text [expr int($max-$start)]
2279: set start [expr $start + $delta]
2280: }
2281: if { [llength [lindex $data 0]] > 2} {
2282: $canvas bind current <1> "CTbargraphClick$suffix $num"
2283: bind $canvas <Enter> "CTbargraphDisplayCreate $num"
2284: bind $canvas <Leave> "CTbargraphDisplayRemove $num"
2285: bind $canvas <Motion> "CTbargraphDisplayMove $num"
2286: $canvas bind all <Enter> "CTbargraphDisplay$suffix $num"
2287: }
2288: }
2289:
2290: ###########################################################
2291: # CTbargraphDisplayCreate
2292: ###########################################################
2293: ###########################################################
2294: ###########################################################
2295: proc CTbargraphDisplayCreate { barnum } {
2296: global gBarGraph gCT gFile
2297: set canvas $gBarGraph($barnum.canvas)
2298: if {[winfo exists $canvas.bubble$barnum]} { return }
2299: set bubble [toplevel $canvas.bubble$barnum]
2300: wm overrideredirect $bubble 1
2301: wm positionfrom $bubble program
2302: wm withdraw $bubble
2303: pack [label $bubble.l -highlightthickness 0 -relief raised -bd 1 -background yellow]
2304: }
2305: ###########################################################
2306: # CTbargraphDisplayRemove
2307: ###########################################################
2308: ###########################################################
2309: ###########################################################
2310: proc CTbargraphDisplayRemove { barnum } {
2311: global gBarGraph gCT gFile
2312: set canvas $gBarGraph($barnum.canvas)
2313: catch {destroy $canvas.bubble$barnum}
2314: }
2315: ###########################################################
2316: # CTbargraphDisplayBlank
2317: ###########################################################
2318: ###########################################################
2319: ###########################################################
2320: proc CTbargraphDisplayBlank { barnum } {
2321: global gBarGraph gCT gFile
2322: set canvas $gBarGraph($barnum.canvas)
2323: catch {$canvas.bubble$barnum.l configure -text ""}
2324: }
2325: ###########################################################
2326: # CTbargraphDisplayMove
2327: ###########################################################
2328: ###########################################################
2329: ###########################################################
2330: proc CTbargraphDisplayMove { barnum } {
2331: global gBarGraph gCT gFile
2332: set canvas $gBarGraph($barnum.canvas)
2333: catch {wm geometry $canvas.bubble$barnum +[expr 20+[winfo pointerx .]]+[expr 20+[winfo pointery .]]}
2334: if {[$canvas gettags current] == ""} {CTbargraphDisplayRemove $barnum}
2335: }
2336: ###########################################################
2337: # CTbargraphDisplayShowresponse
2338: ###########################################################
2339: ###########################################################
2340: ###########################################################
2341: proc CTbargraphDisplayShowresponse { barnum } {
2342: global gBarGraph gCT gFile
2343: set num $gBarGraph($barnum.num)
2344: set canvas $gBarGraph($barnum.canvas)
2345:
2346: set high [lindex [split [lindex [$canvas gettags current] 0] .] 1]
2347: foreach datum $gBarGraph($barnum) {
2348: set bar [lindex $datum 1]
2349: if { $bar != $high } { continue }
2350: if {![winfo exists $canvas.bubble$barnum.l]} {CTbargraphDisplayCreate $barnum}
2351: $canvas.bubble$barnum.l configure -text "[lindex $datum 0] - \"[splitline [lindex $datum 2] 35]\""
2352: wm geometry $canvas.bubble$barnum +[expr 20+[winfo pointerx .]]+[expr 20+[winfo pointery .]]
2353: wm deiconify $canvas.bubble$barnum
2354: return
2355: }
2356: CTbargraphDisplayRemove $barnum
2357: }
2358: ###########################################################
2359: # CTbargraphDisplaySCP
2360: ###########################################################
2361: ###########################################################
2362: ###########################################################
2363: proc CTbargraphDisplaySCP { barnum } {
2364: global gBarGraph gCT gFile
2365: set num $gBarGraph($barnum.num)
2366: set canvas $gBarGraph($barnum.canvas)
2367:
2368: set high [lindex [split [lindex [$canvas gettags current] 0] .] 1]
2369: foreach datum $gBarGraph($barnum) {
2370: set bar [lindex $datum 1]
2371: if { $bar != $high } { continue }
2372: if {![winfo exists $canvas.bubble$barnum.l]} {CTbargraphDisplayCreate $barnum}
2373: $canvas.bubble$barnum.l configure -text "[lindex $datum 0]"
2374: wm geometry $canvas.bubble$barnum +[expr 20+[winfo pointerx .]]+[expr 20+[winfo pointery .]]
2375: wm deiconify $canvas.bubble$barnum
2376: return
2377: }
2378: CTbargraphDisplayRemove $barnum
2379: }
2380:
2381: ###########################################################
2382: # CTbargraphClickSCP
2383: ###########################################################
2384: ###########################################################
2385: ###########################################################
2386: proc CTbargraphClickSCP { barnum } {
2387: global gBarGraph gCT gFile
2388:
2389: set num $gBarGraph($barnum.num)
2390: set canvas $gBarGraph($barnum.canvas)
2391: set bucket $gBarGraph($barnum.bucketscores)
2392:
2393: set high [lindex [split [lindex [$canvas gettags current] 0] .] 1]
2394: set low [lindex [split [lindex [$canvas gettags current] 0] .] 2]
2395: set stunums ""
2396: if { $high == "" || $low == "" } { return }
2397: foreach datum $gBarGraph($barnum) {
2398: set bar [lindex $datum 1]
2399: if { $bar > $high || $bar <= $low } { continue }
2400: set stunums [concat $stunums [lindex $datum 2]]
2401: }
2402: if { $stunums == "" } { return }
2403: if {"" == [set stuSCP [multipleChoice $gCT($num) "Select a student" $stunums 0]]} {
2404: return
2405: }
2406: set loginAnalysis [expr {"Yes" == [makeSure "Do you wish to do a Login Analysis? It may take a while." ]}]
2407: foreach s_id $stuSCP {
2408: CTstudentCourseProfile $num $s_id \
2409: [findByStudentNumber $s_id $gFile($num)] $loginAnalysis
2410: }
2411: }
2412:
2413: ###########################################################
2414: # CTbargraphClickShowresponse
2415: ###########################################################
2416: ###########################################################
2417: ###########################################################
2418: proc CTbargraphClickShowresponse { barnum } {
2419: global gBarGraph gCT gFile gUniqueNumber
2420:
2421: set num $gBarGraph($barnum.num)
2422: set canvas $gBarGraph($barnum.canvas)
2423: set bucket $gBarGraph($barnum.bucketscores)
2424:
2425: if { [catch {set datanum $gBarGraph($barnum.shownum1)}] } {
2426: set datanum [set gBarGraph($barnum.shownum1) [incr gUniqueNumber]]
2427: set winnum [set gBarGraph($barnum.shownum2) [incr gUniqueNumber]]
2428: } else {
2429: set winnum $gBarGraph($barnum.shownum2)
2430: }
2431: set gCT($winnum) ""
2432: set high [lindex [split [lindex [$canvas gettags current] 0] .] 1]
2433: foreach datum $gBarGraph($barnum) {
2434: set bar [lindex $datum 1]
2435: if { $bar != $high } { continue }
2436: CTputs $datanum "[lindex $datum 0] responses \"[lindex $datum 2]\"\n"
2437: }
2438: CToutput $winnum $datanum
2439: }
2440:
2441: ###########################################################
2442: # CTchangeBargraph
2443: ###########################################################
2444: ###########################################################
2445: ###########################################################
2446: proc CTchangeBargraph { window num } {
2447: global gBarGraph
2448:
2449: set change [toplevel $window.changeBarGraph$num]
2450:
2451: set infoFrame [frame $change.info]
2452: set buttonFrame [frame $change.button]
2453: set title [frame $change.title]
2454: set xlabel [frame $change.xlabel]
2455: set ylabel [frame $change.ylabel]
2456: set xoften [frame $change.xoften]
2457: set yoften [frame $change.yoften]
2458: set color [frame $change.color]
2459: set bucket [frame $change.bucket]
2460: set font [frame $change.font]
2461: pack $infoFrame $buttonFrame $title $xlabel $ylabel $xoften $yoften $color $bucket
2462: pack configure $title $xlabel $ylabel $xoften $yoften -anchor e -expand 1 -fill both
2463: button $buttonFrame.update -text Update -command "CTdrawBargraph $num"
2464: bind $change <Return> "CTdrawBargraph $num"
2465: button $buttonFrame.dismiss -text Dismiss -command "destroy $change"
2466: pack $buttonFrame.update $buttonFrame.dismiss -side left
2467:
2468: foreach {frame label var
2469: } "$title { Title} title
2470: $xlabel { X-Axis Label} xlabel
2471: $ylabel { Y-Axis Label} ylabel
2472: $xoften {Increment on X-Axis} xoften
2473: $yoften {Increment on Y-Axis} yoften" {
2474: label $frame.label -text $label
2475: set entryFrame [frame $frame.entry]
2476: pack $frame.label $entryFrame -side left
2477: pack configure $entryFrame -expand 1 -fill both
2478: entry $entryFrame.entry -textvariable gBarGraph($num.$var) \
2479: -xscrollcommand "$entryFrame.scroll set"
2480: scrollbar $entryFrame.scroll -orient h -command \
2481: "$entryFrame.entry xview"
2482: pack $entryFrame.entry $entryFrame.scroll -fill x
2483: }
2484:
2485: label $color.label -text "Color of Bars"
2486: label $color.color -relief ridge -background $gBarGraph($num.color) \
2487: -text " "
2488: button $color.change -text "Change" -command "CTchangeBargraphColor $color $num"
2489: pack $color.label $color.color $color.change -side left
2490:
2491: checkbutton $bucket.bucket -text "Bucket Scores" -variable \
2492: gBarGraph($num.bucketscores) -command "CTdrawBargraph $num"
2493: pack $bucket.bucket
2494: }
2495:
2496: ###########################################################
2497: # CTchangeBargraphColor
2498: ###########################################################
2499: ###########################################################
2500: ###########################################################
2501: proc CTchangeBargraphColor { color num } {
2502: global gBarGraph
2503: set temp [tk_chooseColor -initialcolor $gBarGraph($num.color)]
2504: if { $temp != "" } {
2505: $color.color configure -background [set gBarGraph($num.color) $temp]
2506: }
2507: CTdrawBargraph $num
2508: }
2509:
2510: ###########################################################
2511: # CTdisplayStudent
2512: ###########################################################
2513: ###########################################################
2514: ###########################################################
2515: proc CTdisplayStudent { num window path id } {
2516:
2517: if { ![file exists [file join $path photo gif $id.gif]] } {
2518: if { [file exists [file join $path photo jpg $id.jpg]] } {
2519: exec /usr/local/bin/djpeg -outfile [file join $path photo gif $id.gif] \
2520: [file join $path photo jpg $id.jpg]
2521: } else {
2522: return
2523: }
2524: }
2525: set image [image create photo]
2526: $image read [file join $path photo gif $id.gif]
2527:
2528: set imageWin [toplevel $window.image$num]
2529:
2530: set buttonFrame [frame $imageWin.button]
2531: set infoFrame [frame $imageWin.info]
2532: set imageFrame [frame $imageWin.image]
2533: pack $buttonFrame $infoFrame $imageFrame
2534:
2535: button $buttonFrame.dismiss -command "destroy $imageWin" -text Dismiss
2536: pack $buttonFrame.dismiss
2537:
2538: label $infoFrame.label -text $id
2539: pack $infoFrame.label
2540:
2541: set canvas [canvas $imageFrame.canvas]
2542: pack $canvas
2543: $canvas create image 1 1 -image $image -anchor nw
2544: }
2545:
2546: ###########################################################
2547: # CTgetWhen
2548: ###########################################################
2549: ###########################################################
2550: ###########################################################
2551: proc CTgetWhen { num } {
2552: set day [getString . "Enter a date"]
2553: update
2554: return $day
2555: }
2556:
2557: ###########################################################
2558: # CTscanDB
2559: ###########################################################
2560: ###########################################################
2561: ###########################################################
2562: proc CTscanDB { num file outId startdate enddate } {
2563: global answerArray exist
2564: set fileId [open $file r]
2565: set Yes_cnt 0
2566: set No_cnt 0
2567: set line_cnt 0
2568: set prob_cnt 0
2569: set maxLine [lindex [exec wc $file] 0]
2570: puts $maxLine
2571: set aline [gets $fileId]
2572: while { ! [eof $fileId] } {
2573: incr line_cnt
2574: if { ($line_cnt%20) == 0 } {
2575: puts $curdate
2576: updateStatusBar [expr $line_cnt/double($maxLine)] $num
2577: }
2578: set length [llength $aline]
2579: set date [lrange $aline 1 [expr $length - 2]]
2580: set curdate [clock scan $date]
2581: if { $curdate < $startdate } { set aline [gets $fileId]; continue }
2582: if { $curdate > $enddate } { break }
2583: set s_num [string toupper [lindex $aline 0]]
2584: set ans_char [split [lindex $aline end] ""]
2585: set usr_ans "$s_num.ans"
2586: set usr_try "$s_num.try"
2587: if {$prob_cnt == 0} { set prob_cnt [llength $ans_char] }
2588: if { [array names answerArray "$usr_ans.*"] == "" } {
2589: for {set ii 0} { $ii <= $prob_cnt } { incr ii} {
2590: set answerArray($usr_ans.$ii) "-"
2591: }
2592: }
2593: if { [array names answerArray "$usr_try.*"] == "" } {
2594: for {set ii 0} { $ii <= $prob_cnt } { incr ii} {
2595: set answerArray($usr_try.$ii) 0
2596: }
2597: }
2598: for {set ii 0} { $ii <= $prob_cnt } { incr ii} {
2599: if { [lindex $ans_char $ii] == "Y" } {
2600: set answerArray($usr_ans.$ii) "Y"
2601: incr answerArray($usr_try.$ii)
2602: }
2603: if { [lindex $ans_char $ii] == "N"} {
2604: if {$answerArray($usr_ans.$ii) != "Y"} {
2605: set answerArray($usr_ans.$ii) "Y"
2606: }
2607: incr answerArray($usr_try.$ii)
2608: }
2609: }
2610: if { [array names exist $s_num] == "" } { set exist($s_num) $s_num }
2611: set aline [gets $fileId]
2612: }
2613: close $fileId
2614: return $prob_cnt
2615: }
2616:
2617: ###########################################################
2618: # CTcreateSubset
2619: ###########################################################
2620: ###########################################################
2621: ###########################################################
2622: proc CTcreateSubset { num cmdnum day setId } {
2623: global gFile gCT answerArray exist
2624:
2625: set outId [open [file join $gFile($num) records "subset$setId.db"] w]
2626: set inId [open [file join $gFile($num) records "set$setId.db"] r]
2627:
2628: set startdate [clock scan "$day 12:00 AM"]
2629: set enddate [clock scan "$day 11:59 PM"]
2630:
2631: puts $startdate:$enddate
2632: set prob_cntt [CTscanDB $cmdnum [file join $gFile($num) records log$setId.db] $outId $startdate $enddate]
2633: puts $startdate:$enddate
2634: set prob_cntw [CTscanDB $cmdnum [file join $gFile($num) records weblog$setId.db] $outId $startdate $enddate]
2635: puts $startdate:$enddate
2636: puts "$day 12:00 AM : $day 11:59 PM"
2637: if { $prob_cntt > $prob_cntw } {
2638: set prob_cnt $prob_cntt
2639: } else {
2640: set prob_cnt $prob_cntw
2641: }
2642:
2643: puts $outId [gets $inId]
2644: puts $outId [gets $inId]
2645: puts $outId [gets $inId]
2646: foreach s_num [lsort [array names exist]] {
2647: set usr_ans $s_num.ans
2648: set usr_try $s_num.try
2649: puts -nonewline $outId "$s_num "
2650: for { set ii 0 } { $ii< $prob_cnt } { incr ii } {
2651: puts -nonewline $outId $answerArray($usr_ans.$ii)
2652: }
2653: for { set ii 0 } { $ii< $prob_cnt } { incr ii } {
2654: puts -nonewline $outId [format ",%2d" $answerArray($usr_try.$ii)]
2655: }
2656: puts $outId ""
2657: }
2658: close $outId
2659: close $inId
2660: catch {unset answerArray}
2661: catch {unset exist}
2662: }
1.2 albertel 2663:
2664: ###########################################################
2665: # CTdiscussForum
2666: ###########################################################
2667: ###########################################################
2668: ###########################################################
1.3 albertel 2669: proc CTdiscussForum { num file dir resultVar {specificSet 0}} {
2670: global gCT
2671: upvar $resultVar result
1.2 albertel 2672:
1.3 albertel 2673: if { $specificSet == 0 } {
2674: set start 1
2675: } else {
2676: set start $specificSet
2677: }
1.2 albertel 2678: set fileId [open $file r]
2679: set maxLine [lindex [exec wc $file] 0]
2680: set aline [gets $fileId]
2681: set last 0
2682: set line_cnt 0
2683: while {![eof $fileId]} {
2684: incr line_cnt
2685: if { ($line_cnt%20) == 0 } { updateStatusBar [expr $line_cnt/double($maxLine)] $num }
2686: foreach {stunum capaid name email action set prob date time} [split $aline "|"] {}
1.3 albertel 2687: if {$specificSet && ($specificSet == $set)} {set aline [gets $fileId];continue}
1.2 albertel 2688: if { $action == "ViewProblem" } {
2689: if { [catch {incr count($set,$prob)}]} {
2690: set count($set,$prob) 1
2691: if { $set > $last } { set last $set }
2692: if { [catch {set max($set)}]} { set max($set) 0 }
2693: if { $prob > $max($set)} { set max($set) $prob }
2694: if { [catch {set posts($set,$prob) [llength [glob $dir/discussion/$set/[format "%06d" $prob]-*-*-*.msg]]}]} { set posts($set,$prob) 0 }
2695: }
2696: set ever($name) 1
2697: set names($set,$name) 1
2698: set nameprob($set,$prob,$name) 1
2699: }
2700: set aline [gets $fileId]
2701: }
2702:
1.3 albertel 2703: updateStatusMessage "Summarizing Data" $num
1.2 albertel 2704: updateStatusBar 0 $num
2705: for {set i 1} { $i <= $last } { incr i } {
2706: updateStatusBar [expr $i/$last] $num
2707: set total($i) 0
1.3 albertel 2708: for {set j 1} { $j <= $max($i) } { incr j } {
1.2 albertel 2709: set message ""
1.3 albertel 2710: if {[catch { set result($num.$i.$j.posts) $posts($i,$j) }]} {
2711: set result($num.$i.$j.posts) 0
2712: }
2713: if {[catch {set result($num.$i.$j.views) $count($i,$j)}]} {
2714: set result($num.$i.$j.views) 0
2715: }
2716: catch {incr total($i) $count($i,$j)}
2717: if { [catch { set result($num.$i.$j.ratio) \
2718: [expr $result($num.$i.$j.views)/double($result($num.$i.$j.posts))]} error]} {
2719: set result($num.$i.$j.ratio) 0.0
1.2 albertel 2720: }
1.3 albertel 2721: set result($num.$i.$j.viewers) [llength [array names nameprob $i,$j,*]]
1.2 albertel 2722: }
1.3 albertel 2723: set result($num.$i.views) $total($i)
2724: set result($num.$i.max) $max($i)
1.2 albertel 2725: }
2726:
1.3 albertel 2727: for {set i 1} { $i<=$last } { incr i } {
2728: set result($num.$i.viewers) [llength [array names names $i,*]]
1.2 albertel 2729: }
2730: close $fileId
1.3 albertel 2731: set result($num.viewers) [llength [array names ever]]
2732: set result($num.last) $last
1.2 albertel 2733: #IDEAS: stick into capastats
2734: # : howmany viws are repeats
2735: # : Student Course Profile, add #ViewProblems #Posts
2736: # : add some portion of these stats to analyze log files?
1.3 albertel 2737: }
2738:
2739: ###########################################################
2740: # CTputsDiscussResults
2741: ###########################################################
2742: ###########################################################
2743: proc CTputsDiscussResults { num resultsVar } {
2744: upvar $resultsVar result
2745: for {set i 1} { $i <= $result($num.last) } { incr i } {
2746: CTputs $num "For Set $i #Visitors:$result($num.$i.viewers) did #views:$result($num.$i.views)\n"
2747: CTputs $num "Prob# #Posts #Views Ratio #UniqueStu\n"
2748: CTputs $num "------------------------------------\n"
2749: for {set j 1} { $j <= $result($num.$i.max)} { incr j } {
2750: CTputs $num [format "%5d %6d %6d %5s %6d\n" $j \
2751: $result($num.$i.$j.posts) $result($num.$i.$j.views) \
2752: [if {$result($num.$i.$j.ratio) == 0.0} {set temp " "} \
2753: {format %.1f $result($num.$i.$j.ratio)}] \
2754: $result($num.$i.$j.viewers)]
2755: }
2756: }
2757: CTputs $num "Overall Unique #viewers: $result($num.viewers)\n"
1.6 albertel 2758: }
2759:
2760: ###########################################################
2761: # CTcreateReportDialog
2762: ###########################################################
2763: ###########################################################
2764: ###########################################################
2765: proc CTcreateReportDialog { num cmdnum } {
2766: global gCT gFile
2767:
2768:
2769: set gCT(summary.section.$cmdnum) 1
2770: set gCT(summary.set.$cmdnum) 1
2771:
2772: set summary [toplevel $gCT($num).summary]
2773: set whoFrame [frame $summary.whoFrame -borderwidth 4 -relief groove]
2774: set whichFrame [frame $summary.whichFrame -borderwidth 4 -relief groove]
2775: set sortFrame [frame $summary.sortFrame]
2776: set file2Frame [frame $summary.file2Frame]
2777: set buttonFrame [frame $summary.buttonFrame]
2778: pack $whoFrame $whichFrame $sortFrame $file2Frame $buttonFrame -side top
2779: pack configure $whoFrame $whichFrame -padx 10 -pady 10
2780:
2781: set sectionFrame [frame $whoFrame.section]
2782: set allFrame [frame $whoFrame.all]
2783: pack $sectionFrame $allFrame -side top
2784:
2785: set gCT(summary.who.$cmdnum) section
2786:
2787: radiobutton $sectionFrame.section -text \
2788: "For students in default section:" -variable gCT(summary.who.$cmdnum) \
2789: -value section
2790: entry $sectionFrame.entry -textvariable gCT(summary.section.$cmdnum) -width 3
2791: pack $sectionFrame.section $sectionFrame.entry -side left
2792:
2793: radiobutton $allFrame.all -text "For all students in the class" \
2794: -variable gCT(summary.who.$cmdnum) -value all
2795: pack $allFrame.all
2796:
2797: set sectionFrame [frame $whichFrame.section]
2798: set allFrame [frame $whichFrame.all]
2799: pack $sectionFrame $allFrame -side top
2800:
2801: set gCT(summary.which.$cmdnum) specific
2802:
2803: radiobutton $sectionFrame.section -text "For set:" \
2804: -variable gCT(summary.which.$cmdnum) -value specific
2805: entry $sectionFrame.entry -textvariable gCT(summary.set.$cmdnum) -width 3
2806: pack $sectionFrame.section $sectionFrame.entry -side left
2807:
2808: radiobutton $allFrame.all -text "For all sets up to:" -variable \
2809: gCT(summary.which.$cmdnum) -value upto
2810: entry $allFrame.entry -textvariable gCT(summary.set.$cmdnum) -width 3
2811: pack $allFrame.all $allFrame.entry -side left
2812:
2813: set firstFrame [frame $sortFrame.firstFrame -borderwidth 4 -relief groove]
2814: set secondFrame [frame $sortFrame.secondFrame -borderwidth 4 \
2815: -relief groove]
2816: pack $firstFrame $secondFrame -side left
2817:
2818: set gCT(summary.first.$cmdnum) name
2819:
2820: label $firstFrame.label -text "Sorting Order - Primary"
2821: radiobutton $firstFrame.name -text "Student Name" -variable \
2822: gCT(summary.first.$cmdnum) -value name
2823: radiobutton $firstFrame.number -text "Student Number" -variable \
2824: gCT(summary.first.$cmdnum) -value number
2825: radiobutton $firstFrame.section -text "Section" -variable \
2826: gCT(summary.first.$cmdnum) -value section
2827: radiobutton $firstFrame.grade -text "Grade" -variable gCT(summary.first.$cmdnum) \
2828: -value grade
2829: pack $firstFrame.label $firstFrame.name $firstFrame.number \
2830: $firstFrame.section $firstFrame.grade -side top -anchor w
2831:
2832: set gCT(summary.second.$cmdnum) number
2833:
2834: label $secondFrame.label -text "Sorting Order - Secondary"
2835: radiobutton $secondFrame.name -text "Student Name" -variable \
2836: gCT(summary.second.$cmdnum) -value name
2837: radiobutton $secondFrame.number -text "Student Number" -variable \
2838: gCT(summary.second.$cmdnum) -value number
2839: radiobutton $secondFrame.section -text "Section" -variable \
2840: gCT(summary.second.$cmdnum) -value section
2841: radiobutton $secondFrame.grade -text "Grade" -variable gCT(summary.second.$cmdnum) \
2842: -value grade
2843: pack $secondFrame.label $secondFrame.name $secondFrame.number \
2844: $secondFrame.section $secondFrame.grade -side top -anchor w
2845:
2846: set defaultFrame [frame $file2Frame.defaultFrame]
2847: set fileFrame [frame $file2Frame.fileFrame]
2848: pack $defaultFrame $fileFrame -side top
2849:
2850: set gCT(summary.filename.$cmdnum) default
2851:
2852: radiobutton $defaultFrame.default -text "Grader Chooses File Name" \
2853: -variable gCT(summary.filename.$cmdnum) -value default
2854: pack $defaultFrame.default
2855:
2856: radiobutton $fileFrame.label -text "Specified Output File:" \
2857: -variable gCT(summary.filename.$cmdnum) -value specified
2858: set entryFrame [frame $fileFrame.entryFrame]
2859: button $fileFrame.select -text "Select File" \
1.7 albertel 2860: -command "CTselectOutputFile $cmdnum"
1.6 albertel 2861: pack $fileFrame.label $entryFrame $fileFrame.select -side left
2862: entry $entryFrame.entry -textvariable gCT(summary.file.$cmdnum) \
2863: -xscrollcommand "$entryFrame.scroll set"
2864: scrollbar $entryFrame.scroll -orient h -command \
2865: "$entryFrame.entry xview"
2866: pack $entryFrame.entry $entryFrame.scroll
2867: pack configure $entryFrame.scroll -fill x
2868:
2869: button $buttonFrame.create -text "Create" -command \
2870: "removeWindowEntry Summary
2871: destroy $summary
2872: CTcreateSummaryReport $num $cmdnum"
2873: button $buttonFrame.cancel -text "Cancel" -command \
2874: "removeWindowEntry Summary
2875: destroy $summary"
2876: pack $buttonFrame.create $buttonFrame.cancel -side left
2877:
2878: Centre_Dialog $summary default
2879: }
1.7 albertel 2880:
2881: ###########################################################
2882: # CTselectOutputFile
2883: ###########################################################
2884: ###########################################################
2885: ###########################################################
2886: proc CTselectOutputFile { num } {
2887: global gCT
2888: set gCT(summary.filename.$num) specified
2889: if { "" != [ set temp [tk_getSaveFile] ] } {set gCT(summary.file.$num) $temp}
2890: }
1.6 albertel 2891:
2892: ###########################################################
2893: # CTcreateSummaryReport
2894: ###########################################################
2895: ###########################################################
2896: ###########################################################
2897: proc CTcreateSummaryReport { num cmdnum } {
2898: global gCT gFile
2899:
2900: displayStatus "Opening File" both $cmdnum
2901:
2902: switch $gCT(summary.who.$cmdnum) {
2903: all {
2904: set file ClassSet$gCT(summary.set.$cmdnum).rpt
2905: }
2906: section {
2907: set file Sec$gCT(summary.section.$cmdnum)Set$gCT(summary.set.$cmdnum).rpt
2908: }
2909: default {
1.10 ! albertel 2910: displayError "An error has occurred while creating a summary \
1.6 albertel 2911: report $gCT(summary.section.$cmdnum)"
2912: return
2913: }
2914: }
2915:
2916: if { $gCT(summary.filename.$cmdnum) == "specified" } {
2917: set file $gCT(summary.file.$cmdnum)
2918: }
2919: if { $file == "" } {
2920: removeStatus
2921: displayError "Must specify a valid filename"
2922: return
2923: }
2924: updateStatusMessage "Creating Summary" $cmdnum
2925:
2926: set cwd [pwd]
2927: cd $gFile($num)
2928: set error [ catch {CTcreateSummary $file $cmdnum} ]
2929: cd $cwd
2930:
2931: removeStatus $cmdnum
2932:
1.9 albertel 2933: if {!$error && "Yes" == [makeSure \
2934: "Created summary file $file, would you like to see it?"]} {
1.6 albertel 2935: set fileId [open [file join $gFile($num) $file] r]
2936: CTputs $cmdnum [read $fileId]
2937: CToutput $num $cmdnum
2938: }
1.8 albertel 2939: }
2940:
2941: ###########################################################
2942: # CTsetList
2943: ###########################################################
2944: ###########################################################
2945: ###########################################################
1.9 albertel 2946: proc CTsetList { file } {
1.8 albertel 2947: set list ""
1.9 albertel 2948: for { set i 0 } { $i < 100 } { incr i } {
2949: if { [file readable [file join $file records set$i.db]] } {
2950: lappend list $i
2951: }
1.8 albertel 2952: }
1.9 albertel 2953: return $list
1.10 ! albertel 2954: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>