########################################################### # runCapaTools ########################################################### ########################################################### ########################################################### proc runCapaTools { classDirConfigFile } { global gUniqueNumber gWindowMenu gFile gCT set num [incr gUniqueNumber] set classDir [file dirname $classDirConfigFile] set gFile($num) $classDir set utilsMenu [menu .utilsMenu$num -tearoff 0 -type tearoff -font 8x13bold \ -disabledforeground grey85 ] set gCT($num) $utilsMenu set pathLength [string length $gFile($num)] if { $pathLength > 22 } { set pathSubset ...[string range $gFile($num) [expr $pathLength - 22 ] end] } else { set pathSubset $gFile($num) } $utilsMenu add command -label "CapaUtils Ver 1.1" -foreground grey85 -background \ black -state disabled $utilsMenu add command -label $pathSubset -foreground white -background \ grey30 -state disabled $utilsMenu add command -label "Change Class path" -command "CTchangePath $num" $utilsMenu add command -label "Run capastat" -command "CTcapaStat $num" $utilsMenu add command -label "Run capastat2" -command "CTcapaStat2 $num" $utilsMenu add command -label "Summarize Log files" -command "CTlogAnalysis $num" $utilsMenu add command -label "Student Course Profile" -command \ "CTstartStudentCourseProfile $num" $utilsMenu add command -label "CAPA IDs for one student" \ -command "CToneStudentCapaID $num" $utilsMenu add command -label "All CAPA IDs" -command "CTclassCapaID $num" $utilsMenu add command -label "Item Analysis" -command "CTitemAnalysisStart $num" $utilsMenu add command -label "Item Correlation" \ -command "CTitemCorrelationStart $num" # $utilsMenu add command -label "Email" -command "" # $utilsMenu add command -label "View Score File" -command "" $utilsMenu add command -label "View Submissions" -command "CTsubmissions $num" $utilsMenu add command -label "Create a Class Report" -command "CTcreateReport $num" $utilsMenu add command -label "Analyze Class Report" -command "CTanalyzeReport $num" $utilsMenu add command -label "Analyze Responses" -command "CTanalyzeScorer $num" $utilsMenu add command -label "Graph a Responses Analysis" -command "CTgraphAnalyzeScorer $num" $utilsMenu add command -label "Discussion Stats" -command "CTdiscussStats $num" $utilsMenu add command -label "Quit" -command "CTquit $num" $utilsMenu post 0 0 Centre_Dialog $utilsMenu default set geometry [wm geometry $utilsMenu] wm geometry $utilsMenu +0+[lindex [split $geometry +] end] parseCapaConfig $num $gFile($num) parseCapaUtilsConfig $num $gFile($num) } #menu commands ########################################################### # CTchangePath ########################################################### ########################################################### ########################################################### #FIXME need to wait unit all running commands are done proc CTchangePath { num } { global gFile gCapaConfig set path [tk_getOpenFile -title "Please select a capa.config file" -filetypes \ { { {Capa Config} {capa.config} } }] if { $path == "" } { return } set gFile($num) [file dirname $path] foreach temp [array names gCapaConfig "$num.*"] { unset gCapaConfig($temp) } parseCapaConfig $num $gFile($num) parseCapaUtilsConfig $num $gFile($num) set pathLength [string length $gFile($num)] if { $pathLength > 22 } { set pathSubset ...[string range $gFile($num) [expr $pathLength - 22 ] end] } else { set pathSubset $gFile($num) } .utilsMenu$num entryconfigure 1 -label $pathSubset } ########################################################### # CTcapaStat2 ########################################################### ########################################################### ########################################################### proc CTcapaStat2 { num } { global gFile gCT gUniqueNumber if { [set setId [getOneSet $gCT($num) $gFile($num)]] == "" } { return } set cmdnum [incr gUniqueNumber] set gCT(cmd.$cmdnum) capastat if { [ catch { CTdatestamp $cmdnum set day [CTgetWhen $cmdnum] set file [file join $gFile($num) records "subset$setId.db"] displayStatus "Generating [file tail $file]" both $cmdnum CTcreateSubset $num $cmdnum $day $setId updateStatusBar 0.0 $cmdnum updateStatusMessage "Generating Stats [file tail $file]" $cmdnum CTscanSetDB $cmdnum $file Q_cnt L_cnt updateStatusBar 0.0 $cmdnum updateStatusMessage "Generating Averages [file tail $file]" $cmdnum CTpercentageScores $cmdnum $setId $L_cnt CTaverage $cmdnum $Q_cnt $L_cnt faillist dodifflist numyes if { $L_cnt != 0 } { CTbargraph $gCT($num) $num [incr gUniqueNumber] $faillist $gFile($num) "Not-Yet-Correct Distribution for set $setId" "Problem \#" "%Wrong" CTbargraph $gCT($num) $num [incr gUniqueNumber] $dodifflist $gFile($num) "Degree of Difficulty Distribution for set $setId" "Problem \#" "Degree Of Diff." CTbargraph $gCT($num) $num [incr gUniqueNumber] $numyes $gFile($num) "Number of Yeses received for set $setId" "Problem \#" "\#Students" } removeStatus $cmdnum CToutput $num $cmdnum } errors ] } { global errorCode errorInfo displayError "$errors\n$errorCode\n$errorInfo" unset gCT(cmd.$cmdnum) } else { unset gCT(cmd.$cmdnum) } } ########################################################### # CTcapaStat ########################################################### ########################################################### ########################################################### proc CTcapaStat { num } { global gFile gCT gUniqueNumber if { [set setId [getOneSet $gCT($num) $gFile($num)]] == "" } { return } set cmdnum [incr gUniqueNumber] set gCT(cmd.$cmdnum) capastat if { [ catch { CTdatestamp $cmdnum set file [file join $gFile($num) records "set$setId.db"] displayStatus "Generating Stats [file tail $file]" both $cmdnum CTscanSetDB $cmdnum $file Q_cnt L_cnt updateStatusBar 0.0 $cmdnum updateStatusMessage "Generating Averages [file tail $file]" $cmdnum CTpercentageScores $cmdnum $setId $L_cnt CTaverage $cmdnum $Q_cnt $L_cnt faillist dodifflist numyes CTbargraph $gCT($num) $num [incr gUniqueNumber] $faillist $gFile($num) "Not-Yet-Correct Distribution for set $setId" "Problem \#" "%Wrong" CTbargraph $gCT($num) $num [incr gUniqueNumber] $dodifflist $gFile($num) "Degree of Difficulty Distribution for set $setId" "Problem \#" "Degree Of Diff." CTbargraph $gCT($num) $num [incr gUniqueNumber] $numyes $gFile($num) "Number of Yeses received for set $setId" "Problem \#" "\#Students" removeStatus $cmdnum CToutput $num $cmdnum } errors ] } { global errorCode errorInfo displayError "$errors\n$errorCode\n$errorInfo" unset gCT(cmd.$cmdnum) } else { unset gCT(cmd.$cmdnum) } } ########################################################### # CTlogAnalysis ########################################################### ########################################################### ########################################################### proc CTlogAnalysis { num } { global gFile gUniqueNumber gCT if { [set setId [getOneSet $gCT($num) $gFile($num)]] == "" } { return } set cmdnum [incr gUniqueNumber] set gCT(cmd.$cmdnum) loganalysis CTdatestamp $cmdnum if { [ catch { CTlogAnalysis2 $num $cmdnum $setId } errors ] } { displayError $errors unset gCT(cmd.$cmdnum) } else { unset gCT(cmd.$cmdnum) } CToutput $num $cmdnum } ########################################################### # CTstartStudentCourseProfile ########################################################### ########################################################### ########################################################### proc CTstartStudentCourseProfile { num } { global gFile gCT getOneStudent $gCT($num) $gFile($num) s_id s_name if { $s_id == "" } { return } CTstudentCourseProfile $num $s_id $s_name } ########################################################### # CTstudentCourseProfile ########################################################### ########################################################### ########################################################### proc CTstudentCourseProfile { num s_id s_name {loginAnalysis 2} } { global gFile gUniqueNumber gCapaConfig gCT set cmdnum [incr gUniqueNumber] set gCT(cmd.$cmdnum) studentcourseprofile displayStatus "Collecting homework scores for $s_name" both $cmdnum CTdatestamp $cmdnum CTputs $cmdnum "$s_name\n" if { [ catch { CTcollectSetScores $cmdnum $gFile($num) $s_id 1 \ $gCapaConfig($num.homework_scores_limit_set) } error ] } { global errorCode errorInfo displayError "$error \n $errorCode \n $errorInfo" } foreach type { quiz exam supp others } { updateStatusMessage "Collecting $type scores for $s_name" $cmdnum catch { if { [file isdirectory $gCapaConfig($num.[set type]_path)] } { CTcollectSetScores $cmdnum $gCapaConfig($num.[set type]_path) $s_id 1 \ $gCapaConfig($num.[set type]_scores_limit_set) } } } removeStatus $cmdnum if { ($loginAnalysis == 2 && "Yes" == [makeSure \ "Do you wish to do a Login Analysis? It may take a while." ]) || ($loginAnalysis == 1) } { displayStatus "Analyzing login data." both $cmdnum if { [catch { CTloginAnalysis $cmdnum $gFile($num) $s_id \ $gCapaConfig($num.homework_scores_limit_set) } error] } { displayError error } if { [catch { CTstudentSetAnalysis $cmdnum $gFile($num) $s_id \ $gCapaConfig($num.homework_scores_limit_set) } error] } { displayError error } removeStatus $cmdnum } CTdisplayStudent $cmdnum $gCT($num) $gFile($num) $s_id unset gCT(cmd.$cmdnum) CToutput $num $cmdnum } ########################################################### # CToneStudentCapaID ########################################################### ########################################################### ########################################################### proc CToneStudentCapaID { num } { global gFile gUniqueNumber gCapaConfig gCT getOneStudent $gCT($num) $gFile($num) s_id s_name if { $s_id == "" } { return } set cmdnum [incr gUniqueNumber] set gCT(cmd.$cmdnum) onestudentcapaid set setlist [getSetRange $gCT($num) $gFile($num)] set command "$gCapaConfig($num.allcapaid_command) -i -stu $s_id -s [lindex $setlist 0] -e [lindex $setlist 1] -c $gFile($num)" if { "Yes" == [makeSure "CMD: $command\n Do you wish to execute this command?"] } { CTdatestamp $cmdnum CTputs $cmdnum "CapaIDs for: $s_id, $s_name\n" displayStatus "Getting CapaIDs" spinner $cmdnum set fileId [open "|$command" "r"] fconfigure $fileId -blocking 0 fileevent $fileId readable "CTrunCommand $num $cmdnum $fileId" } } ########################################################### # CTclassCapaID ########################################################### ########################################################### ########################################################### proc CTclassCapaID { num } { global gFile gUniqueNumber gCapaConfig gCT set cmdnum [incr gUniqueNumber] set gCT(cmd.$cmdnum) classcapaid set setlist [getSetRange $gCT($num) $gFile($num)] if { $setlist == "" } { return } set command "$gCapaConfig($num.allcapaid_command) -i -s [lindex $setlist 0] -e [lindex $setlist 1] -c $gFile($num)" if { "Yes" == [makeSure "CMD: $command\n Do you wish to execute this command?"] } { CTdatestamp $cmdnum displayStatus "Getting all CapaIDs" spinner $cmdnum set fileId [open "|$command" "r"] fconfigure $fileId -blocking 0 fileevent $fileId readable "CTrunCommand $num $cmdnum $fileId" } } ########################################################### # CTitemAnalysisStart ########################################################### ########################################################### ########################################################### proc CTitemAnalysisStart { num } { global gFile gUniqueNumber gCapaConfig gCT set cmdnum [incr gUniqueNumber] set gCT(cmd.$cmdnum) itemanalysis set paths "" lappend paths [list "classpath" $gFile($num)] foreach path [lsort [array names gCapaConfig "$num.*_path"]] { lappend paths [list [lindex [split $path "."] 1] $gCapaConfig($path) ] } if {[set select [multipleChoice $gCT($num) "Select a class path" $paths ] ] == ""} { unset gCT(cmd.$cmdnum) return } if { [set sets [getSetRange $gCT($num) [lindex $select 1]]] == "" } { unset gCT(cmd.$cmdnum) return } CTdatestamp $cmdnum if { [ catch {CTitemAnalysisRange $cmdnum [lindex $select 1] \ [lindex $sets 0] [lindex $sets 1] } errors ] } { displayError $errors } unset gCT(cmd.$cmdnum) CToutput $num $cmdnum } ########################################################### # CTitemCorrelationStart ########################################################### ########################################################### ########################################################### proc CTitemCorrelationStart { num } { global gFile gUniqueNumber gCapaConfig gCT ## FIXME: ## Let user specify how many categories to calculate correlation ## For each category, the user can specify problem numbers to ## be in that category ## Then, the correlations between each category is calculated ## set cmdnum [incr gUniqueNumber] set gCT(cmd.$cmdnum) itemanalysis set paths "" lappend paths [list "classpath" $gFile($num)] foreach path [lsort [array names gCapaConfig "$num.*_path"]] { lappend paths [list [lindex [split $path "."] 1] $gCapaConfig($path) ] } if { [set select [multipleChoice $gCT($num) "Select a class path" $paths ] ] == "" } { unset gCT(cmd.$cmdnum) return } if { [set setId [getOneSet $gCT($num) [lindex $select 1]]] == "" } { unset gCT(cmd.$cmdnum) return } CTdatestamp $cmdnum if { [ catch { CTitemCorrelation $cmdnum [lindex $select 1] \ $setId } errors ] } { displayError $errors } unset gCT(cmd.$cmdnum) CToutput $num $cmdnum } ########################################################### # CTsubmissions ########################################################### ########################################################### ########################################################### proc CTsubmissions { num } { global gCT gFile gUniqueNumber gCapaConfig getOneStudent $gCT($num) $gFile($num) s_id s_name if { $s_id == "" } { return } set cmdnum [incr gUniqueNumber] set gCT(cmd.$cmdnum) submissions if { "" == [set setlist [getSetRange $gCT($num) $gFile($num)]] } { return } CTdatestamp $cmdnum CTputs $cmdnum "Submissions for: $s_id, $s_name\n" displayStatus "Getting submissions" spinner $cmdnum CTsubmissionsLaunch $num $cmdnum telnet $s_id $s_name \ [lindex $setlist 0] [lindex $setlist 1] } ########################################################### # CTcreateReport ########################################################### ########################################################### ########################################################### proc CTcreateReport { num } { global gUniqueNumber gCT gFile set cmdnum [incr gUniqueNumber] set gCT(cmd.$cmdnum) createreport CTcreateReportDialog $num $cmdnum } ########################################################### # CTanalyzeReport ########################################################### ########################################################### ########################################################### proc CTanalyzeReport { num } { global gUniqueNumber gCT gFile set cmdnum [incr gUniqueNumber] set gCT(cmd.$cmdnum) analyzereport set reportFile [tk_getOpenFile -title "Please select the Report file" \ -filetypes { {{Capa Reports} {*.rpt}} {{All Files} {*}} }] if { $reportFile == "" } { return } set percentage [tk_dialog $gCT($num).dialog "How would you like scores displayed?" \ "How would you like scores displayed?" "" "" "Points Earned" \ "Percentage" "Cancel"] if { $percentage == 2 } { return } set pwd [pwd];cd $gFile($num) set sectionList [pickSections [getExistingSections] "Select Sections To Analyze:" $gCT($num) ] CTdatestamp $cmdnum CTputs $cmdnum "Analyzing Report File $reportFile\n" CTputs $cmdnum " For Sections $sectionList\n" CTputs $cmdnum " Report Created at [clock format [file mtime $reportFile]]\n" cd $pwd set scorelist [CTreportDist $cmdnum $reportFile $percentage $sectionList] set label [lindex "{Grade} {Grade(%)}" $percentage] set ptsearned 0 set totalnumstu 0 foreach element $scorelist { set numstu [lindex $element 0] set score [lindex $element 1] set ptsearned [expr $ptsearned + ($numstu*$score)] incr totalnumstu $numstu } set average [expr $ptsearned / double($totalnumstu)] set avgmsg [format "Average: %.2f" $average] CTputs $cmdnum $avgmsg\n CTbargraph $gCT($num) $num $cmdnum $scorelist $gFile($num) "Score Distribution for [file tail $reportFile] $avgmsg" $label "\# Students" SCP unset gCT(cmd.$cmdnum) CToutput $num $cmdnum } ########################################################### # CTanalyzeScorer ########################################################### ########################################################### ########################################################### proc CTanalyzeScorer { num } { global gFile gUniqueNumber gCapaConfig gCT set cmdnum [incr gUniqueNumber] set gCT(cmd.$cmdnum) analyzescorer if { "" == [set file [tk_getOpenFile -title "Pick a scorer.output file" -filetypes { { {scorer.output} {scorer.output.*} } { {Submissions File} {*submissions*.db} } { {All Files} {*} } }]] } { return } set path [file dirname [file dirname $file]] if { "" == [set gCT($cmdnum.questNum) [getString $gCT($num) "Which questions?"]]} { return } set gCT($cmdnum.max) [lindex [exec wc -l $file] 0] set gCT($cmdnum.done) 1 set gCT($cmdnum.graphup) 0 set gCT($cmdnum.num) $num displayStatus "Getting student reponses" both $cmdnum set gCT($cmdnum.fileId) [open $file r] if { [regexp {scorer\.output\.([0-9]|([0-9][0-9]))} $file] } { set gCT($cmdnum.setId) [string range [file extension $file] 1 end] set gCT($cmdnum.parse) CTparseScorerOutputLine set aline [gets $gCT($cmdnum.fileId)] } else { set gCT($cmdnum.setId) [lindex [split [file tail $file] s.] 4] set gCT($cmdnum.parse) CTparseSubmissionsLine } set aline [gets $gCT($cmdnum.fileId)] $gCT($cmdnum.parse) $aline $cmdnum set pwd [pwd];cd $path getSet $gCT($cmdnum.question) $gCT($cmdnum.setId) "CTcontinueAnalyze $cmdnum $path" cd $pwd } proc CTcontinueAnalyze { num path arrayVar } { global gCT gResponse upvar $arrayVar question CTgetQuestions $num question set numAdded 0 foreach which $gCT($num.questNum) { incr numAdded [CTgetStudentResponses $num [lindex $gCT($num.response) \ [expr $which-1]] $which \ question] } updateStatusBar [expr $gCT($num.done)/double($gCT($num.max))] $num if { $numAdded > 0 } { CTupdateAnalyzeScorer $num } set interesting 0 while {!$interesting} { incr gCT($num.done) set stunum $gCT($num.question) set aline [gets $gCT($num.fileId)] if { [eof $gCT($num.fileId)] } { CTfinishAnalyzeScorer $num; return } set interesting [$gCT($num.parse) $aline $num] } if { $stunum != $gCT($num.question) } { set pwd [pwd];cd $path getSet $gCT($num.question) $gCT($num.setId) "CTcontinueAnalyze $num $path" cd $pwd } else { CTcontinueAnalyze $num $path question } } proc CTupdateAnalyzeScorer { cmdnum } { global gCT gResponse gUniqueNumber gFile set num $gCT($cmdnum.num) set i 0 foreach correct [array names gResponse "$cmdnum.correct.*"] { set probnum [lindex [split $correct .] 2] set answer [join [lrange [split $correct .] 3 end] .] if { $gResponse($correct) } { set color($probnum.$answer) green } else { set color($probnum.$answer) red } } set results "" set oldprobnum [lindex [split [lindex [lsort [array names gResponse $cmdnum.\[0-9\]*]] 0] .] 1] foreach response [lsort -dictionary [array names gResponse $cmdnum.\[0-9\]*]] { incr i set probnum [lindex [split $response .] 1] if { $probnum > $oldprobnum } { set oldprobnum $probnum lappend results [list 0 0 "Problem Divider" white] } set answer [join [lrange [split $response .] 2 end] .] lappend results [list $gResponse($response) $i $answer $color($probnum.$answer)] } if { $results == "" } { return } if { $gCT($cmdnum.graphup)} { CTchangeBargraphData $cmdnum $results } else { CTbargraph $gCT($num) $num $cmdnum $results $gFile($num) "Reponse Distribution" "Which Response" "\#Picked" "Showresponse" set gCT($cmdnum.graphup) 1 } update idletasks } proc CTsaveAnalyzeScorer { num cmdnum } { global gResponse gCT gFile set file [tk_getSaveFile -initialdir $gFile($num)] set fileId [open $file w] puts $fileId [array get gResponse "$cmdnum.*"] close $fileId } proc CTfinishAnalyzeScorer { cmdnum } { global gCT gResponse gUniqueNumber gFile set num $gCT($cmdnum.num) set i 0 removeStatus $cmdnum foreach correct [array names gResponse "$cmdnum.correct.*"] { set probnum [lindex [split $correct .] 2] set answer [join [lrange [split $correct .] 3 end] .] if { $gResponse($correct) } { set color($probnum.$answer) green } else { set color($probnum.$answer) red } } foreach response [lsort -dictionary [array names gResponse $cmdnum.\[0-9\]*]] { incr i set probnum [lindex [split $response .] 1] set answer [join [lrange [split $response .] 2 end] .] lappend results($probnum) [list $gResponse($response) $i $answer $color($probnum.$answer)] } foreach probnum [lsort -dictionary [array names results]] { CTputs $cmdnum "\nFor Problem $probnum #, Responses:\n" foreach response $results($probnum) { CTputs $cmdnum "[lindex $response 0], [lindex $response 2]\n" } } if { "Yes" ==[makeSure "Would you like to save the results to a file?"] } { CTsaveAnalyzeScorer $num $cmdnum } unset gCT(cmd.$cmdnum) CToutput $num $cmdnum } proc CTparseScorerOutputLine { aline num } { global gCT set gCT($num.stunum) [lindex $aline 0] set aline [string range $aline 40 end] set length [llength [split [lrange $aline 3 end] ,] ] set gCT($num.response) [lrange [split [lrange $aline 3 end] ,] 0 \ [expr {$length-2}]] set gCT($num.question) [lindex [lindex [split $aline ,] end] 0] return 1 } proc CTparseSubmissionsLine { aline num } { global gCT set aline [split $aline \t] set gCT($num.stunum) [lindex $aline 0] set gCT($num.question) $gCT($num.stunum) set gCT($num.response) "" set interesting 0 set current 1 foreach {quest response} [lrange $aline 2 end] { if { $quest == "" } break while { $quest > $current } { lappend gCT($num.response) {} incr current } if { [lsearch $gCT($num.questNum) $quest] != -1} { set interesting 1 } lappend gCT($num.response) [string toupper $response] incr current } return $interesting } proc CTgetQuestions { num questionVar } { global gCT upvar $questionVar question # parray question foreach quest $gCT($num.questNum) { foreach line $question($quest.quest) { if { [regexp {^ *([A-Z])\)(.*)} $line temp letter rest] } { set question($quest.$letter) $rest if { [string first $letter $question($quest.ans)] != -1} { set question($quest.correct.$letter) 1 set question($quest.$letter) "$rest - Correct" } else { set question($quest.correct.$letter) 0 set question($quest.$letter) "$rest - Incorrect" } } } } } proc CTgetStudentResponses { num responses which questionVar } { global gCT gResponse upvar $questionVar question # parray question set i 0 foreach response [split $responses {}] { if { $response == "" || $response == " "} { continue } incr i if { [catch {incr gResponse($num.$which.$question($which.$response))}] } { if {[catch {set gResponse($num.$which.$question($which.$response)) 1}]} { #set gResponse($num.$which.Illegal\ Bubble) 1 puts "not an option $response $which" continue } } if { $question($which.correct.$response) } { set gResponse($num.correct.$which.$question($which.$response)) 1 } else { set gResponse($num.correct.$which.$question($which.$response)) 0 } } return $i } ########################################################### # CTgraphAnalyzeScorer ########################################################### ########################################################### ########################################################### proc CTgraphAnalyzeScorer { num } { global gFile gUniqueNumber gCapaConfig gCT gResponse set cmdnum [incr gUniqueNumber] set gCT(cmd.$cmdnum) graphanalyzescorer if { "" == [set file [tk_getOpenFile -title "Pick a Output file" -filetypes { { {All Files} {*} } } -initialdir $gFile($num)]] } { return } set fileId [open $file r] set temp [read $fileId [file size $file]] close $fileId foreach {name value} $temp { set name [join "$cmdnum [lrange [split $name .] 1 end]" .] set gResponse($name) $value } unset temp foreach name [array names gResponse $cmdnum.\[0-9\]*] { puts "[split $name .]" puts "[lindex [split $name .] 1]" lappend probnums [lindex [split $name .] 1] } set probnums [lsort [lunique $probnums]] event generate . <1> -x 1 -y 1 event generate . if { "" == [set probnums [multipleChoice $gCT($num) "Select which problems" $probnums 0]] } { return } foreach name [array names gResponse $cmdnum.\[0-9\]*] { set probnum [lindex [split $name .] 1] if { -1 == [lsearch $probnums $probnum] } { set answer [join [lrange [split $name .] 2 end] .] unset gResponse($name) unset gResponse($cmdnum.correct.$probnum.$answer) } } set gCT($cmdnum.num) $num set gCT($cmdnum.graphup) 0 CTupdateAnalyzeScorer $cmdnum unset gCT(cmd.$cmdnum) } ########################################################### # CTdiscussStats ########################################################### ########################################################### ########################################################### proc CTdiscussStats { num } { global gCT gUniqueNumber gFile set cmdnum [incr gUniqueNumber] set gCT(cmd.$cmdnum) discussstats set file [file join $gFile($num) discussion logs access.log] displayStatus "Generating discussion Stats" both $cmdnum CTdiscussForum $cmdnum $file $gFile($num) discussData 0 CTputsDiscussResults $cmdnum discussData CToutput $num $cmdnum removeStatus $cmdnum unset gCT(cmd.$cmdnum) } ########################################################### # CTquit ########################################################### ########################################################### ########################################################### proc CTquit { num } { global gCT destroy $gCT($num) } #menu command helpers ########################################################### # CTscanSetDB ########################################################### ########################################################### ########################################################### proc CTscanSetDB { num file Q_cntVar L_cntVar } { global gMaxSet gTotal_try gYes_cnt gyes_cnt gStudent_cnt gStudent_try \ gTotal_weight gTotal_scores gEntry gScore gNewStudent_cnt upvar $Q_cntVar Q_cnt upvar $L_cntVar L_cnt set line_cnt 0 set valid_cnt 0 for { set ii 0 } { $ii <= $gMaxSet } { incr ii } { set gTotal_try($num.$ii) 0 set gYes_cnt($num.$ii) 0 set gyes_cnt($num.$ii) 0 for { set jj 0 } { $jj <= $gMaxSet } { incr jj } { set gStudent_cnt($num.$ii.$jj) 0 set gStudent_try($num.$ii.$jj) 0 } set gNewStudent_cnt($num.$ii) 0 } set gTotal_weight($num) 0 set gTotal_scores($num) 0 set maxLine [lindex [exec wc $file] 0] set tries "" set fileId [open $file "r"] set aline [gets $fileId] while { ! [eof $fileId] } { incr line_cnt if { ($line_cnt%20) == 0 } { updateStatusBar [expr $line_cnt/double($maxLine)] $num } if { $line_cnt == 2 } { set aline [string trim $aline] set weight [split $aline {}] } if { $line_cnt > 3 } { catch { set aline [string trim $aline] set prefix [lindex [split $aline ,] 0] set s_num [lindex [split $aline " "] 0] set ans_str [lindex [split $prefix " "] 1] set ans_char [split $ans_str {} ] set tries [lrange [split $aline ,] 1 end] for { set valid 0; set ii 0 } { $ii < [llength $ans_char] } { incr ii } { if {([lindex $ans_char $ii] != "-")&&([lindex $ans_char $ii] != "E") && ([lindex $ans_char $ii] != "e") } { set valid 1 } } if { $valid } { for {set score 0; set ii 0} { $ii < [llength $tries] } { incr ii } { set triesii 0 incr gTotal_weight($num) [lindex $weight $ii] if { [lindex $ans_char $ii] == "Y" } { set triesii [string trim [lindex $tries $ii]] incr gYes_cnt($num.$ii) incr score [lindex $weight $ii] incr gNewStudent_cnt($num.$ii) } elseif { [lindex $ans_char $ii] == "y" } { set triesii [string trim [lindex $tries $ii]] incr triesii incr gyes_cnt($num.$ii) incr score [lindex $weight $ii] incr gNewStudent_cnt($num.$ii) } elseif { ( [lindex $ans_char $ii] > 0 ) && \ ( [lindex $ans_char $ii] <= 9) } { set triesii [string trim [lindex $tries $ii]] incr score [lindex $ans_char $ii] incr gYes_cnt($num.$ii) incr gNewStudent_cnt($num.$ii) } elseif { ( [lindex $ans_char $ii] == 0 ) } { set triesii [string trim [lindex $tries $ii]] incr gNewStudent_cnt($num.$ii) } elseif {([lindex $ans_char $ii]=="n") || \ ([lindex $ans_char $ii]=="N")} { set triesii [string trim [lindex $tries $ii]] if { [lindex $ans_char $ii] == "n" } { incr triesii } incr gNewStudent_cnt($num.$ii) } set gStudent_try($num.$valid_cnt.$ii) $triesii incr gTotal_try($num.$ii) $triesii incr gStudent_cnt($num.$ii.$triesii) } incr gTotal_scores($num) $score set gEntry($num.$valid_cnt) "$aline" set gScore($num.$valid_cnt) $score incr valid_cnt } } } set aline [gets $fileId] } close $fileId set Q_cnt [llength $tries] set L_cnt $valid_cnt return } ########################################################### # CTpercentageScores ########################################################### ########################################################### ########################################################### proc CTpercentageScores { num setId valid_cnt } { global gTotal_weight gTotal_scores if { $gTotal_weight($num) > 0 } { set ratio [expr double($gTotal_scores($num)) / double($gTotal_weight($num))] set ratio [expr $ratio * 100.0 ] CTputs $num "\nScore (total scores / total valid weights) for set$setId.db: [format %7.2f%% $ratio]\n" } CTputs $num "The number of valid records for set$setId.db is: $valid_cnt\n" } ########################################################### # CTaverage ########################################################### ########################################################### ########################################################### proc CTaverage { num q_cnt l_cnt faillistVar dodifflistVar numyesVar} { upvar $faillistVar faillist $dodifflistVar dodifflist $numyesVar numyes global gMaxTries gStudent_cnt gStudent_try gTotal_try gYes_cnt gyes_cnt \ gNewStudent_cnt set maxIter [expr $q_cnt * 4] for { set ii 0 } { $ii < $q_cnt } { incr ii } { updateStatusBar [expr $ii/double($maxIter)] $num set s_cnt($ii) 0 set avg($ii) 0.0 set max_try($ii) 0 for { set jj 1 } { $jj < $gMaxTries } { incr jj } { if { $gStudent_cnt($num.$ii.$jj) > 0 } { set avg($ii) [expr $avg($ii) + ($jj * $gStudent_cnt($num.$ii.$jj))] incr s_cnt($ii) $gStudent_cnt($num.$ii.$jj) } } set s_cnt($ii) $gNewStudent_cnt($num.$ii) if { $s_cnt($ii) > 0 } { set avg($ii) [expr $avg($ii) / $s_cnt($ii)] } } for { set ii 0 } { $ii < $q_cnt } { incr ii } { updateStatusBar [expr ($ii+$q_cnt)/double($maxIter)] $num set sd($ii) 0.0 set sum 0.0 for { set jj 0 } { $jj < $l_cnt } { incr jj } { if { $gStudent_try($num.$jj.$ii) > $max_try($ii) } { set max_try($ii) $gStudent_try($num.$jj.$ii) } if { $gStudent_try($num.$jj.$ii) > 0 } { set sq [expr ( $gStudent_try($num.$jj.$ii) - $avg($ii) ) * \ ( $gStudent_try($num.$jj.$ii) - $avg($ii)) ] set sum [expr $sum + $sq] } if { $s_cnt($ii) > 1 } { set sd($ii) [expr $sum / ( $s_cnt($ii) - 1.0 )] } if { $sd($ii) > 0 } { set sd($ii) [ expr sqrt($sd($ii)) ] } } } for { set ii 0 } { $ii < $q_cnt } { incr ii } { updateStatusBar [expr ($ii+(2*$q_cnt))/double($maxIter)] $num set sd3($ii) 0.0 set sum 0.0 for { set jj 0 } { $jj < $l_cnt } { incr jj } { if { $gStudent_try($num.$jj.$ii) > 0 } { set tmp1 [expr $gStudent_try($num.$jj.$ii) - $avg($ii)] set tmp2 [expr $tmp1 * $tmp1 * $tmp1] set sum [expr $sum + $tmp2] } if { ( $s_cnt($ii) > 0 ) && ( $sd($ii) != 0.0 ) } { set sd3($ii) [expr $sum / $s_cnt($ii) ] set sd3($ii) [expr $sd3($ii) / ($sd($ii) * $sd($ii) * $sd($ii)) ] } } } CTputs $num "This is the statistics for each problem: \n" CTputs $num "Prob\# MxTries avg. s.d. s.k. \#Stdnts" CTputs $num " \#Yes \#yes Tries DoDiff %Wrong\n" set numyes [set dodifflist [set faillist ""]] # parray s_cnt for { set ii 0 } { $ii < $q_cnt } { incr ii } { updateStatusBar [expr ($ii+(3*$q_cnt))/double($maxIter)] $num if { $gTotal_try($num.$ii) > 0 } { set dod [expr $gTotal_try($num.$ii)/(0.1 + $gYes_cnt($num.$ii) \ + $gyes_cnt($num.$ii))] } else { set dod 0.0 } if {[catch {set success [expr 100.0*($s_cnt($ii)-($gYes_cnt($num.$ii)+ \ $gyes_cnt($num.$ii)))/$s_cnt($ii)]}]} { set success 0.0 set s_cnt($ii) 0 } CTputs $num [format "P %2d" [expr int($ii + 1)] ] CTputs $num [format "%6d %8.2f %7.2f %6.2f %5d %5d %5d %5d %5.1f %6.2f\n"\ $max_try($ii) $avg($ii) $sd($ii) $sd3($ii) $s_cnt($ii) \ $gYes_cnt($num.$ii) $gyes_cnt($num.$ii) \ $gTotal_try($num.$ii) $dod $success] if { $success < 0 } { set success 0 } lappend faillist [list $success [expr int($ii + 1)]] lappend dodifflist [list $dod [expr int($ii + 1)]] lappend numyes [list [expr $gYes_cnt($num.$ii)+$gyes_cnt($num.$ii)] \ [expr int($ii + 1)]] } } ########################################################### # CTlogAnalysis2 ########################################################### ########################################################### ########################################################### proc CTlogAnalysis2 { num cmdnum setId } { global gFile set logFile [file join $gFile($num) records "log$setId.db"] if { [file exists $logFile] } { CTputs $cmdnum "Log analysis for telnet session log$setId.db\n" CTscanLogDB $cmdnum $logFile l(Y) l(N) l(S) l(U) l(u) l(A) l(F) } else { set l(Y) [set l(N) [set l(S) [set l(U) [set l(u) [set l(A) [set l(F) 0]]]]]] } set webLogFile [file join $gFile($num) records "weblog$setId.db" ] if { [file exists $webLogFile] } { CTputs $cmdnum "===============================================\n" CTputs $cmdnum "Log analysis for web session weblog$setId.db\n" CTscanLogDB $cmdnum $webLogFile w(Y) w(N) w(S) w(U) w(u) w(A) w(F) } else { set w(Y) [set w(N) [set w(S) [set w(U) [set w(u) [set w(A) [set w(F) 0]]]]]] } set telnet_total [expr $l(Y)+$l(N)+$l(S)+$l(U)+$l(u)+$l(A)+$l(F)] set web_total [expr $w(Y)+$w(N)+$w(S)+$w(U)+$w(u)+$w(A)+$w(F)] CTputs $cmdnum "============== SUMMARY ====================\n" CTputs $cmdnum " #Y #N #S #U #u #A #F Total\n" CTputs $cmdnum [format "telnet: %6d %6d %6d %6d %6d %6d %6d %6d\n" \ $l(Y) $l(N) $l(S) $l(U) $l(u) $l(A) $l(F) $telnet_total ] CTputs $cmdnum [format " web: %6d %6d %6d %6d %6d %6d %6d %6d\n" \ $w(Y) $w(N) $w(S) $w(U) $w(u) $w(A) $w(F) $web_total] foreach v { Y N S U u A F} { set sum($v) [expr $l($v) + $w($v)] if { $sum($v) > 0 } { set ratio($v) [expr 100.0*$w($v)/double($sum($v))] } else { set ratio($v) 0.0 } } set overall_entries [expr $telnet_total + $web_total] if { $overall_entries > 0 } { set ratio(web) [expr 100.0*(double($web_total)/double($overall_entries))] } else { set ratio(web) 0.0 } CTputs $cmdnum [format " %%web: % 6.1f % 6.1f % 6.1f % 6.1f % 6.1f % 6.1f % 6.1f % 6.1f\n" \ $ratio(Y) $ratio(N) $ratio(S) $ratio(U) $ratio(u) $ratio(A) $ratio(F) $ratio(web) ] } ########################################################### # CTscanLogDB ########################################################### ########################################################### ########################################################### proc CTscanLogDB { num file Y_lVar N_lVar S_lVar U_lVar u_lVar A_lVar F_lVar } { upvar $Y_lVar Y_l upvar $N_lVar N_l upvar $S_lVar S_l upvar $U_lVar U_l upvar $u_lVar u_l upvar $A_lVar A_l upvar $F_lVar F_l set line_cnt 0 displayStatus "Analyzing [file tail $file]" both $num set maxLine [lindex [exec wc $file] 0] set fileId [open $file "r"] set aline [gets $fileId] while { ! [eof $fileId] } { incr line_cnt if { ($line_cnt%20) == 0 } { updateStatusBar [expr $line_cnt/double($maxLine)] $num } set aline [string trim $aline] set ans_str [string range $aline 35 end] set ans_char [split $ans_str {}] if { ! [info exists count] } { for { set i 0 } { $i < [llength $ans_char] } { incr i } { set count(Y.$i) 0; set count(N.$i) 0; set count(S.$i) 0 set count(U.$i) 0; set count(u.$i) 0; set count(A.$i) 0 set count(F.$i) 0 } set count(Y.total) 0; set count(N.total) 0; set count(S.total) 0 set count(U.total) 0; set count(u.total) 0; set count(A.total) 0 set count(F.total) 0 } set i -1 foreach char $ans_char { incr i if { $char == "-" } { continue } if { [catch {incr count($char.$i)}] } { set count(Y.$i) 0; set count(N.$i) 0; set count(S.$i) 0 set count(U.$i) 0; set count(u.$i) 0; set count(A.$i) 0 set count(F.$i) 0 incr count($char.$i) } incr count($char.total) } set aline [gets $fileId] } close $fileId removeStatus $num CTputs $num "Prob #: #Y #N #S #U #u #A #F\n" for { set i 0 } { $i < [llength $ans_char] } { incr i } { CTputs $num [format " %2d: %6d %6d %6d %6d %6d %6d %6d\n" [expr $i + 1] \ $count(Y.$i) $count(N.$i) $count(S.$i) $count(U.$i) $count(u.$i) \ $count(A.$i) $count(F.$i) ] } CTputs $num "===========================================\n" CTputs $num [format " Total: %6d %6d %6d %6d %6d %6d %6d\n" $count(Y.total) \ $count(N.total) $count(S.total) $count(U.total) $count(u.total) \ $count(A.total) $count(F.total) ] set Y_l $count(Y.total) set N_l $count(N.total) set S_l $count(S.total) set U_l $count(U.total) set u_l $count(u.total) set A_l $count(A.total) set F_l $count(F.total) return } ########################################################### # CTcollectSetScores ########################################################### ########################################################### ########################################################### proc CTcollectSetScores { num path id on_screen limit } { set id [ string toupper $id ] set total_scores 0 set total_weights 0 set set_idx 0 set done 0 while { ! $done } { incr set_idx if { $set_idx > $limit } { set done 1; continue } updateStatusBar [expr $set_idx/double($limit)] $num set filename [file join $path records "set$set_idx.db"] if { ![file readable $filename ] } { continue } set fileId [open $filename "r"] set line_cnt 0 set found 0 set aline [ gets $fileId ] while { ! [eof $fileId] && ! $found } { incr line_cnt if { $line_cnt > 3 } { set aline [string trim $aline] set prefix [lindex [split $aline ","] 0] set s_num [string toupper [lindex [split $aline " "] 0] ] set ans_str [lindex [split $prefix " "] 1] if { $id == $s_num } { set ans_char [split $ans_str {} ] set valid 0 foreach char $ans_char { if { $char != "-" } { set valid 1; break } } if { ! $valid } { set score "-" } else { set score 0 for {set i 0} { $i < [llength $ans_char] } { incr i } { set char [lindex $ans_char $i] if { $char == "N" || $char == "n"} { set found 1 } if { $char == "Y" || $char == "y"} { incr score [lindex $weights $i];set found 1 } if { $char >= 0 && $char <= 9 } { incr score $char;set found 1 } if { $char == "E" } { incr valid_weights "-[lindex $weights $i]" } } incr total_scores $score } } } elseif { $line_cnt == 2 } { set aline [string trim $aline] set weights [split $aline {} ] set valid_weights 0 foreach weight $weights { incr valid_weights $weight } } else { #do nothing for line 1 and 3 } set aline [ gets $fileId ] } close $fileId incr total_weights $valid_weights set set_weights([expr $set_idx - 1]) $valid_weights if { $found } { set set_scores([expr $set_idx - 1]) $score } else { set set_scores([expr $set_idx - 1]) "-" } } set abscent_cnt 0 set present_cnt 0 set summary_str "" if { $on_screen } { CTputs $num " " } foreach i [lsort -integer [array names set_scores]] { if { $set_scores($i) == "-" || $set_scores($i) == "" } { if { $on_screen } { CTputs $num " - " } append summary_str "x/$set_weights($i) " incr abscent_cnt } else { if { $on_screen } { CTputs $num [format " %3d" $set_scores($i)] } append summary_str "$set_scores($i)/$set_weights($i) " incr present_cnt } } if { $on_screen } { CTputs $num "\n [file tail $path]:" foreach i [lsort -integer [array names set_scores]] { CTputs $num " ---" } CTputs $num "\n " if { [info exists set_weights] } { set num_set_weights [llength [array names set_weights]] } else { set num_set_weights 0 } for {set i 0} {$i < $num_set_weights} {incr i} { if { [info exists set_weights($i)] } { CTputs $num [format " %3d" $set_weights($i)] } else { set num_set_weights $i } } CTputs $num "\n" if { $total_weights != 0 } { set ratio [expr 100.0 * $total_scores / double($total_weights) ] CTputs $num [format " %5d\n" $total_scores] if { [info exists set_scores] } { CTputs $num [format " ------- = %3.2f%%, scores absent in %d/%d\n" \ $ratio $abscent_cnt [llength [array names set_scores]]] } else { CTputs $num [format " ------- = %3.2f%%, scores absent in %d/%d\n" \ $ratio $abscent_cnt 0 ] } } else { set ratio "-" CTputs $num [format " %5d\n" $total_scores] if { [info exists set_scores] } { CTputs $num [format " ------- = %s%%, scores absent in %d/%d\n" \ $ratio $abscent_cnt [llength [array names set_scores]]] } else { CTputs $num [format " ------- = %s%%, scores absent in %d/%d\n" \ $ratio $abscent_cnt 0 ] } } CTputs $num [format " %5d\n" $total_weights] } return [list $total_scores $total_weights $abscent_cnt \ [llength [array names set_scores] ] $summary_str] } ########################################################### # CTloginAnalysis ########################################################### ########################################################### ########################################################### proc CTloginAnalysis { num path id limit } { CTputs $num "Login analysis: telnet session web session\n\n" CTputs $num " set #: #Y #N #S #U #u #Y #N #S #U #u\n" set set_idx 0 set done 0 while { ! $done } { incr set_idx if { $set_idx > $limit } { set done 1; continue } CTputs $num [format " %2d: " $set_idx] set filename [file join $path records "log$set_idx.db"] updateStatusMessage "Analyzing [file tail $filename]" $num updateStatusBar 0.0 $num if { [file readable $filename] } { set result [CTstudentLoginData $num $filename $id] CTputs $num [eval format \"%4d %4d %4d %4d %4d\" $result] set no_log 0 } else { CTputs $num "========================" set no_log 1 } CTputs $num " " set filename [file join $path records "weblog$set_idx.db"] updateStatusMessage "Analyzing [file tail $filename]" $num updateStatusBar 0.0 $num if { [file readable $filename] } { set result [CTstudentLoginData $num $filename $id] CTputs $num [eval format \"%4d %4d %4d %4d %4d\" $result] set no_weblog 0 } else { CTputs $num "========================" set no_weblog 1 } CTputs $num "\n" if { $no_log && $no_weblog } { set done 1 } } } ########################################################### # CTstudentSetAnalysis ########################################################### ########################################################### ########################################################### proc CTstudentSetAnalysis { num path id limit } { set set_idx 0 set id [string toupper $id] CTputs $num " set \#:\n" set done 0 while { ! $done } { incr set_idx if { $set_idx > $limit } { set done 1; continue } set filename [file join $path records "set$set_idx.db"] updateStatusMessage "Analyzing [file tail $filename]" $num if { ![file readable $filename] } { continue } CTputs $num [format " %2d: " $set_idx] set fileId [open $filename "r"] set line_cnt 0 set found 0 set aline [gets $fileId] while { ! [eof $fileId] && !$found } { incr line_cnt if { $line_cnt > 3 } { set aline [string trim $aline] set s_id [string toupper [string range $aline 0 8]] if {$id == $s_id} { set found 1 set breakpt [string first "," $aline] set data [list [string range $aline 10 [expr $breakpt - 1] ] \ [string range $aline [expr $breakpt + 1] end ] ] CTputs $num "[lindex $data 0]\n [lindex $data 1]\n" } } set aline [gets $fileId] } close $fileId if { ! $found } { CTputs $num "\n\n" } } } ########################################################### # CTstudentLoginData ########################################################### ########################################################### ########################################################### proc CTstudentLoginData { num filename id } { set Y_total 0 set N_total 0 set U_total 0 set u_total 0 set S_total 0 set maxLine [expr double([lindex [exec wc $filename] 0])] set line_cnt 0 set fileId [open $filename "r"] set aline [gets $fileId] while { ![eof $fileId] } { incr line_cnt if { $line_cnt%300 == 0 } { updateStatusBar [expr $line_cnt/$maxLine] $num } set aline [string trim $aline] set s_id [string toupper [string range $aline 0 8]] set id [string toupper $id] if {$id == $s_id} { set ans_char [split [string range $aline 35 end] {} ] for {set i 0} {$i< [llength $ans_char]} {incr i} { if {[lindex $ans_char $i] == "Y"} { incr Y_total } elseif {[lindex $ans_char $i] == "N"} { incr N_total } elseif {[lindex $ans_char $i] == "U"} { incr U_total } elseif {[lindex $ans_char $i] == "u"} { incr u_total } elseif {[lindex $ans_char $i] == "S"} { incr S_total } } } set aline [gets $fileId] } close $fileId return [list $Y_total $N_total $S_total $U_total $u_total] } ########################################################### # CTrunCommand ########################################################### ########################################################### ########################################################### proc CTrunCommand { num cmdnum fileId {followup "" }} { global gCT set data [read $fileId] updateStatusSpinner $cmdnum if { $data != "" } { CTputs $cmdnum $data } if { [eof $fileId] } { fileevent $fileId readable "" catch {close $fileId} if { $followup == "" } { CToutput $num $cmdnum removeStatus $cmdnum unset gCT(cmd.$cmdnum) } else { eval $followup } } } ########################################################### # CTitemAnalysisRange ########################################################### ########################################################### ########################################################### proc CTitemAnalysisRange { num classpath setIdStart setIdEnd } { for { set i $setIdStart } { $i <= $setIdEnd } { incr i } { if { [ catch { CTitemAnalysis $num $classpath $i } errors ] } { displayError $errors } } } ########################################################### # CTitemAnalysis ########################################################### ########################################################### ########################################################### proc CTitemAnalysis { num classpath setId } { global gMaxSet set done 0 set total_scores 0 set total_weights 0 set upper_percent 0.0 set lower_percent 0.0 set Y_total 0 set N_total 0 for { set ii 0} { $ii<$gMaxSet } {incr ii} { set Y_cnt($ii) 0 set N_cnt($ii) 0 set Ycnt_upper($ii) 0.0 set Ycnt_lower($ii) 0.0 } set filename [file join $classpath records "set$setId.db"] if { ! [file readable $filename] } { CTputs $num "FILE: $filename does not exist!\n" return } displayStatus "Analyzing [file tail $filename]" both $num set maxLine [lindex [exec wc $filename] 0] set fileId [open "$filename" "r"] set valid_cnt 0 set line_cnt 0 set ans_char "" set aline [gets $fileId] while {![eof $fileId]} { incr line_cnt if { ($line_cnt%20) == 0 } { updateStatusBar [expr $line_cnt/double($maxLine)] $num } if { $line_cnt == 2 } { set aline [string trim $aline] set weights [split $aline {}] # set valid_weights 0 # for { set ii 0 } { $ii < [llength $weights] } { incr ii } { # incr valid_weights [lindex $weights $ii] # } } elseif { $line_cnt > 3} { set aline [string trim $aline] set prefix [lindex [split $aline ","] 0] set s_num [string toupper [lindex [split $aline " " ] 0 ] ] set ans_str [lindex [split $prefix " "] 1] set ans_char [split $ans_str {} ] set valid 0 for { set ii 0 } { $ii < [llength $ans_char] } { incr ii } { if { [lindex $ans_char $ii] != "-"} { set valid 1 } } if { $valid } { incr valid_cnt set score 0 for { set ii 0 } { $ii < [llength $ans_char] } { incr ii } { if { [lindex $ans_char $ii] == "Y" || \ [lindex $ans_char $ii] == "y" } { incr score [lindex $weights $ii] set Y_cnt($ii) [expr $Y_cnt($ii) + 1] set Y_total [expr $Y_total + 1] } if { [lindex $ans_char $ii] == "N" || \ [lindex $ans_char $ii] == "n" } { set N_cnt($ii) [expr $N_cnt($ii) + 1] set N_total [expr $N_total + 1] } if { [lindex $ans_char $ii] >= 0 && \ [lindex $ans_char $ii] <= 9 } { incr score [lindex $ans_char $ii] set yes_part [expr [lindex $ans_char $ii] / \ double([lindex $weights $ii]) ] set no_part [expr 1.0 - $yes_part] set Y_cnt($ii) [expr $Y_cnt($ii) + $yes_part] set Y_total [expr $Y_total + $yes_part] set N_cnt($ii) [expr $N_cnt($ii) + $no_part] set N_total [expr $N_total + $no_part] } # if { [lindex $ans_char $ii] == "E"} { # incr valid_weights -[lindex $weights $ii] # } } set s_db([format "%08d%s" $score $s_num]) $ans_str } } set aline [gets $fileId] } close $fileId removeStatus $num for { set ii 0 } { $ii < $gMaxSet } { incr ii } { set Ycnt_upper($ii) 0 set Ycnt_lower($ii) 0 } displayStatus "Pondering data . . ." spinner $num set upperpart_cnt [expr int(0.27 * double($valid_cnt))] set lowerpart_limit [expr $valid_cnt - $upperpart_cnt] set line_cnt 0 foreach sort_key [lsort -decreasing [array names s_db]] { incr line_cnt if { ($line_cnt%20) == 0 } { updateStatusSpinner $num } set ans_str $s_db($sort_key) set ans_char [split $ans_str {} ] for { set ii 0 } { $ii < [llength $ans_char] } { incr ii } { if { [lindex $ans_char $ii] == "Y" || \ [lindex $ans_char $ii] == "y" || \ [lindex $ans_char $ii] == [lindex $weights $ii] } { if { $line_cnt <= $upperpart_cnt } { incr Ycnt_upper($ii) } elseif { $line_cnt > $lowerpart_limit } { incr Ycnt_lower($ii) } } } } CTputs $num " There are $valid_cnt entries in file $filename\n" CTputs $num [format " The upper 27%% has %d records, the lower 27%% has %d records\n"\ $upperpart_cnt [expr $valid_cnt - $lowerpart_limit] ] CTputs $num " question \# DoDiff. Disc. Factor (%upper - %lower) \[\#records,\#records\]\n"; for { set ii 0 } { $ii < [llength $ans_char] } { incr ii } { updateStatusSpinner $num set tmp_total [expr $N_cnt($ii) + $Y_cnt($ii)] if { $tmp_total > 0 } { set diff [expr 100.0*($N_cnt($ii) / double($N_cnt($ii) + $Y_cnt($ii)))] } else { set diff "-" } set upper_percent [expr 100.0 * ($Ycnt_upper($ii) /double($upperpart_cnt))] set lower_percent [expr 100.0 * ($Ycnt_lower($ii) /double($upperpart_cnt))] set disc [expr $upper_percent - $lower_percent] CTputs $num [format " %2d: " [expr $ii + 1]] CTputs $num [format "%6.1f %5.1f (%6.1f - %6.1f) \[%8d,%8d\]\n" \ $diff $disc $upper_percent $lower_percent $Ycnt_upper($ii) \ $Ycnt_lower($ii) ] } removeStatus $num } ########################################################### # CTitemCorrelation ########################################################### # INPUTS: class name with full path, set number # # r = \frac{\sum{x_i y_i} - \frac{(\sum x_i)(\sum y_i)}{n}} # {\sqrt{(\sum x_i^2 - \frac{}{}}} # # corr = (sum of prod_xy - (sum_x*sum_y / n) ) / sqrt( (sum of sqr_x - (sum_x*sum_x/n))* # ########################################################### ########################################################### proc CTitemCorrelation { num classpath setId } { global gMaxSet set filename [file join $classpath records "set$setId.db"] if { ! [file readable $filename] } { CTputs $num "FILE: $filename does not exist!\n" return } displayStatus "Analyzing [file tail $filename]" both $num set maxLine [lindex [exec wc $filename] 0] set initialized 0 set question_cnt 0 set fileId [open "$filename" "r"] set line_cnt 0 set aline [gets $fileId] while {![eof $fileId]} { incr line_cnt if { ($line_cnt%20) == 0 } { updateStatusBar [expr {$line_cnt/double($maxLine)}] $num } if { $line_cnt == 2 } { set aline [string trimright $aline] set weights [split $aline {}] } if { $line_cnt > 3} { set aline [string trimright $aline] set data [string range $aline 10 end] set ans_str [lindex [split $data ","] 0] set ans_char_list [split $ans_str {} ] set try_str [string range $aline [expr {[string first "," $data] +1}] end ] set question_cnt [llength $ans_char_list] for { set ii 0 } { $ii < $question_cnt } { incr ii } { set ans_char($ii) [lindex $ans_char_list $ii] } if { $question_cnt > $initialized } { for {set ii 0} {$ii < [expr {$question_cnt - 1}]} {incr ii} { set start [expr {($initialized>($ii+1)) ? $initialized : ($ii+1)}] for { set jj $start } { $jj < $question_cnt } { incr jj } { set index_key "$ii.$jj" set prod_xy($index_key) 0.0 set sum_x($index_key) 0 set sum_y($index_key) 0 set sum_x2($index_key) 0 set sum_y2($index_key) 0 set valid_cnt($index_key) 0 } } set initialized $question_cnt } for { set ii 0 } { $ii < [expr {$question_cnt - 1}] } { incr ii } { for { set jj [expr {$ii+1}] } { $jj < $question_cnt } { incr jj } { set index_key "$ii.$jj" if { $ans_char($ii) != "-" && $ans_char($ii) != "E" && \ $ans_char($jj) != "-" && $ans_char($jj) != "E" } { ## $ans_char($ii) is one of 0 .. 9, Y, y, N, n ## $ans_char($jj) is one of 0 .. 9, Y, y, N, n if { $ans_char($ii) == "Y" || $ans_char($ii) == "y" } { set x_data [lindex $weights $ii] } elseif { $ans_char($ii) == "N" || $ans_char($ii) == "n" } { set x_data 0 } else { ## must be in 0 .. 9 set x_data $ans_char($ii) } if { $ans_char($jj) == "Y" || $ans_char($jj) == "y" } { set y_data [lindex $weights $jj] } elseif { $ans_char($jj) == "N" || $ans_char($jj) == "n" } { set y_data 0 } else { ## must be in 0 .. 9 set y_data $ans_char($jj) } set prod_xy($index_key) [expr {$x_data * $y_data + $prod_xy($index_key)} ] incr sum_x($index_key) $x_data incr sum_y($index_key) $y_data incr sum_x2($index_key) [expr {$x_data * $x_data}] incr sum_y2($index_key) [expr {$y_data * $y_data}] incr valid_cnt($index_key) 1 } } } } set aline [gets $fileId] } close $fileId removeStatus $num # print out the correlation matrix #parray sum_x #parray sum_y #parray prod_xy #puts $question_cnt CTputs $num " " for { set ii 1 } { $ii < $question_cnt } { incr ii } { CTputs $num [format " %2d" [expr {$ii+1}] ] } CTputs $num "\n" # -------------------------------------- for { set ii 0 } { $ii < [expr {$question_cnt -1}] } { incr ii } { CTputs $num [format " %2d:" [expr {$ii+1}] ] for { set jj 0 } { $jj < $ii } { incr jj } { CTputs $num " " } for { set jj [expr {$ii+1}] } { $jj < $question_cnt } { incr jj } { set index_key "$ii.$jj" if { $valid_cnt($index_key) != "0" } { set upper_part [ expr { $prod_xy($index_key) - ( ($sum_x($index_key) * $sum_y($index_key)) / double($valid_cnt($index_key)))}] set lower_part [expr {$sum_x2($index_key) - ($sum_x($index_key) * $sum_x($index_key) / double($valid_cnt($index_key)))} ] set lower_part [expr {$lower_part * ($sum_y2($index_key) - ($sum_y($index_key) * $sum_y($index_key) /double($valid_cnt($index_key))))}] set lower_part [expr {sqrt($lower_part)}] if { $lower_part != 0.0 } { set ratio [expr {$upper_part / double($lower_part)}] CTputs $num [format " % .2f" $ratio] } else { CTputs $num " INF " } } else { CTputs $num " ----" } } CTputs $num "\n" } } ########################################################### # CTsubmissionsLaunch ########################################################### ########################################################### ########################################################### proc CTsubmissionsLaunch { num cmdnum type s_id s_nm start end } { global gCT gFile gUniqueNumber gCapaConfig CTputs $cmdnum "$type submissions for $s_nm for set $start\n" if { $type == "telnet" } { set command "grep -i $s_id [file join $gFile($num) records submissions$start.db]" set followtype web } else { set command "grep -i $s_id [file join $gFile($num) \ records websubmissions$start.db]" set followtype telnet incr start } set done 0 set followcmd "" while { !$done && ($start <= ($end+1)) } { if { $start <= $end } { set followcmd "CTsubmissionsLaunch $num $cmdnum $followtype $s_id {$s_nm} \ $start $end" } if { ! [catch {set fileId [open "|$command" "r"]} ] } { set done 1 } } fconfigure $fileId -blocking 0 fileevent $fileId readable "CTrunCommand $num $cmdnum $fileId {$followcmd}" } ########################################################### # CTreportDist ########################################################### ########################################################### ########################################################### proc CTreportDist { num file percentage sectionlist } { set fileId [open $file "r"] set aline [gets $fileId] set which [expr [llength [split $aline "\t"]] - 2] set maximum [lindex [lrange [split $aline "\t"] $which end] 1] if { $percentage } { for {set i 0} {$i<=100} {incr i} { set totals($i.score) 0 set totals($i.stunum) "" } } else { for { set i 0 } { $i <= $maximum } { incr i } { set totals($i.score) 0 set totals($i.stunum) "" } } while { ![eof $fileId]} { set temp [lrange [split $aline "\t"] $which end] set score [lindex $temp 0] regsub -- "-" $score "0" score set max [lindex $temp 1] set temp [lindex [split $aline "\t"] 1] set section [lindex $temp 1] set stunum [lindex $temp 0] if { ([lsearch $sectionlist $section] != -1) && ($max!=0) } { if { $percentage } { set percent [expr int($score/double($max)*100)] incr totals($percent.score) lappend totals($percent.stunum) $stunum } else { if { $max > $maximum } { for {set i [expr $maximum+1]} {$i<=$max} {incr i} {set totals($i) 0} set maximum $max } set score [string trim $score] incr totals($score.score) lappend totals($score.stunum) $stunum } } set aline [gets $fileId] } CTputs $num "Scores #acheived\n" set scorelist "" set templist [array names totals *.score] foreach temp $templist {lappend possiblescores [lindex [split $temp .] 0]} foreach score [lsort -integer $possiblescores] { CTputs $num [format "%5d:%6d\n" $score $totals($score.score)] lappend scorelist [list $totals($score.score) $score $totals($score.stunum)] } return $scorelist } ########################################################### # CTgradeDistribution ########################################################### ########################################################### ########################################################### proc CTgradeDistribution { num classpath setId } { set filename [file join $classpath records "set$setId.db"] if { ! [file readable $filename] } { CTputs $num "FILE: $filename does not exist!\n" return } displayStatus "Analyzing [file tail $filename]" both $num set maxLine [lindex [exec wc $filename] 0] set fileId [open "$filename" "r"] set valid_cnt 0 set line_cnt 0 set aline [gets $fileId] while {![eof $fileId]} { incr line_cnt if { ($line_cnt%20) == 0 } { updateStatusBar [expr $line_cnt/double($maxLine)] $num } if { $line_cnt == 2 } { set aline [string trim $aline] set weights [split $aline {}] set valid_weights 0 foreach weight $weights { incr valid_weights $weight } for { set i 0 } { $i <= $valid_weights } { incr i } { set total_score($i) 0 } } elseif { $line_cnt > 3} { set aline [string trim $aline] set prefix [lindex [split $aline ","] 0] set s_num [string toupper [lindex [split $aline " " ] 0 ] ] set ans_str [lindex [split $prefix " "] 1] set ans_char [split $ans_str {} ] set valid 0 for { set ii 0 } { $ii < [llength $ans_char] } { incr ii } { if { [lindex $ans_char $ii] != "-"} { set valid 1 } } if { $valid } { incr valid_cnt set score 0 for { set ii 0 } { $ii < [llength $ans_char] } { incr ii } { if { [lindex $ans_char $ii] == "Y" || \ [lindex $ans_char $ii] == "y" } { incr score [lindex $weights $ii] } if { [lindex $ans_char $ii] >= 0 && \ [lindex $ans_char $ii] <= 9 } { incr score [lindex $ans_char $ii] } } if { [catch {incr total_score($score)} ] } { puts "$aline:$prefix:$s_num:$ans_str:$ans_char" } } } set aline [gets $fileId] } close $fileId removeStatus $num displayStatus "Pondering data . . ." spinner $num CTputs $num " There are $valid_cnt entries in file $filename\n" CTputs $num "Score #acheived\n" set scorelist "" foreach score [lsort -integer [array names total_score]] { CTputs $num [format "%5d:%6d\n" $score $total_score($score)] lappend scorelist [list $total_score($score) $score] } removeStatus $num return $scorelist } ########################################################### # CTgetStudentScores ########################################################### ########################################################### ########################################################### proc CTgetStudentScores { studentScoresVar classpath setId num } { upvar $studentScoresVar studentScores set filename [file join $classpath records "set$setId.db"] if { ! [file readable $filename] } { CTputs $num "FILE: $filename does not exist!\n" error } displayStatus "Analyzing [file tail $filename]" both $num set maxLine [lindex [exec wc $filename] 0] set fileId [open "$filename" "r"] set valid_cnt 0 set line_cnt 0 set aline [gets $fileId] set aline [gets $fileId] set weights [split [string trim $aline] {}] set valid_weights 0 foreach weight $weights { incr valid_weights $weight } set aline [gets $fileId] set aline [gets $fileId] while {![eof $fileId]} { incr line_cnt if { ($line_cnt%20) == 0 } { updateStatusBar [expr $line_cnt/double($maxLine)] $num } set aline [string trim $aline] set prefix [lindex [split $aline ","] 0] set s_num [string toupper [lindex [split $aline " " ] 0 ] ] set ans_str [lindex [split $prefix " "] 1] set ans_char [split $ans_str {} ] set valid 0 for { set ii 0 } { $ii < [llength $ans_char] } { incr ii } { if { [lindex $ans_char $ii] != "-"} { set valid 1 } } if { $valid } { incr valid_cnt if {[array names studentScores $s_num] == ""} {set studentScores($s_num) 0} for { set ii 0 } { $ii < [llength $ans_char] } { incr ii } { if { [lindex $ans_char $ii] == "Y" || [lindex $ans_char $ii] == "y" } { incr studentScores($s_num) [lindex $weights $ii] } if { [lindex $ans_char $ii] >= 0 && [lindex $ans_char $ii] <= 9 } { incr studentScores($s_num) [lindex $ans_char $ii] } } } set aline [gets $fileId] } close $fileId removeStatus $num return $valid_weights } ########################################################### # CTgradeDistributionRange ########################################################### ########################################################### ########################################################### proc CTgradeDistributionRange { num classpath setIdstart setIdend } { set totalpoints 0 for {set setId $setIdstart} {$setId <= $setIdend} {incr setId} { set points [CTgetStudentScores studentScores $classpath $setId $num] incr totalpoints $points # parray studentScores } displayStatus "Pondering data . . ." spinner $num for { set i 0 } { $i <= $totalpoints } { incr i } { set total_score($i) 0 } foreach sNum [array names studentScores] { incr total_score($studentScores($sNum)) } CTputs $num "Scores #acheived\n" set scorelist "" foreach score [lsort -integer [array names total_score]] { CTputs $num [format "%5d:%6d\n" $score $total_score($score)] lappend scorelist [list $total_score($score) $score] } removeStatus $num return $scorelist } #common Input dialogs #common output methods proc CTdatestamp { cmdnum } { CTputs $cmdnum [clock format [clock seconds]]\n } ########################################################### # CTputs ########################################################### ########################################################### ########################################################### proc CTputs { num message {tag normal} } { global gCT lappend gCT(output.$num) [list $message $tag] } ########################################################### # CToutputWrap ########################################################### ########################################################### ########################################################### proc CToutputWrap { num } { global gCT if { $gCT($num.wrap) } { $gCT($num.output) configure -wrap char } else { $gCT($num.output) configure -wrap none } } ########################################################### # CToutput ########################################################### ########################################################### ########################################################### proc CToutput { num cmdnum } { global gCT if { ![winfo exists $gCT($num).output] } { set outputWin [toplevel $gCT($num).output] set buttonFrame [frame $outputWin.button] set textFrame [frame $outputWin.text] set bottomFrame [frame $outputWin.bottom] pack $buttonFrame $textFrame $bottomFrame pack configure $buttonFrame -anchor e -expand 0 -fill x pack configure $textFrame -expand 1 -fill both pack configure $bottomFrame -expand 0 -fill x set gCT($num.output) [text $textFrame.text \ -yscrollcommand "$textFrame.scroll set" \ -xscrollcommand "$bottomFrame.scroll set"] scrollbar $textFrame.scroll -command "$textFrame.text yview" pack $gCT($num.output) $textFrame.scroll -side left pack configure $textFrame.text -expand 1 -fill both pack configure $textFrame.scroll -expand 0 -fill y scrollbar $bottomFrame.scroll -command "$textFrame.text xview" -orient h pack $bottomFrame.scroll -expand 0 -fill x set gCT($num.wrap) 1 checkbutton $buttonFrame.wrap -text "Wrap" -command "CToutputWrap $num" \ -variable gCT($num.wrap) button $buttonFrame.save -text "Save Text" -command "CTsaveText $num" button $buttonFrame.print -text "Print Text" -command "CTprintText $num" button $buttonFrame.dismiss -text "Dismiss" -command "destroy $outputWin" pack $buttonFrame.wrap $buttonFrame.save $buttonFrame.print \ $buttonFrame.dismiss -side left } set index [$gCT($num.output) index end] foreach line $gCT(output.$cmdnum) { eval $gCT($num.output) insert end $line } unset gCT(output.$cmdnum) raise $gCT($num).output $gCT($num.output) see $index update idletasks } ########################################################### # CTsaveText ########################################################### # saves the contents of a text window ########################################################### # Arguments: num (the unique number of the path, and window) # Returns : nothing # Globals : ########################################################### proc CTsaveText { num } { global gFile gCT set window $gCT($num.output) if {![winfo exists $window]} { return } set dir $gFile($num) set file "" if { $dir == "" || $dir == "."} { set dir [pwd] } set file [tk_getSaveFile -title "Enter the name to Save As" \ -initialdir "$dir" ] if { $file == "" } { displayError "File not saved" return } set fileId [open $file w] puts -nonewline $fileId [$window get 0.0 end-1c] close $fileId } ########################################################### # CTprintText ########################################################### # prints the contents of the text window, creates a temp file named # quiztemp.txt ########################################################### # Arguments: num (the unique number of the path, and window) # Returns : nothing # Globals : gFile gCT ########################################################### proc CTprintText { num } { global gFile gCT set window $gCT($num.output) if { ![winfo exists $window]} { return } catch {parseCapaConfig $num $gFile($num)} set lprCommand [getLprCommand [file join $gFile($num) managertemp.txt] $num] if {$lprCommand == "Cancel"} { return } set fileId [open [file join $gFile($num) managertemp.txt] w] puts -nonewline $fileId [$window get 0.0 end-1c] close $fileId set errorMsg "" if { [catch {set output [ eval "exec $lprCommand" ] } errorMsg ]} { displayError "An error occurred while printing: $errorMsg" } else { displayMessage "Print job sent to the printer.\n $output" } exec rm -f [file join $gFile($num) mangertemp.txt] } ########################################################### # CTprintCanvas ########################################################### ########################################################### ########################################################### proc CTprintCanvas { num window path } { if { ![winfo exists $window]} { return } catch {parseCapaConfig $num $gFile($num)} set lprCommand [getLprCommand [file join $path managertemp.txt] $num] if {$lprCommand == "Cancel"} { return } set rotate 0 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 } $window postscript -file [file join $path managertemp.txt] -rotate $rotate set errorMsg "" if { [catch {set output [ eval "exec $lprCommand" ] } errorMsg ]} { displayError "An error occurred while printing: $errorMsg" } else { displayMessage "Print job sent to the printer.\n $output" } exec rm -f [file join $path mangertemp.txt] } ########################################################### # CTsaveCanvas ########################################################### ########################################################### ########################################################### proc CTsaveCanvas { window path } { if { ![winfo exists $window] } { return } set dir $path set file "" if { $dir == "" } { set dir [pwd] } set file [tk_getSaveFile -title "Enter the name to Save As" \ -initialdir "$dir" ] if { $file == "" } { displayError "File not saved" return } $window postscript -file $file } ########################################################### # CTbargraph ########################################################### ########################################################### ########################################################### proc CTbargraph {window num barnum data {path ""} {title "" } {xlabel ""} {ylabel ""} {suffix ""} } { global gBarGraph set height 300 set width 500 global gWindowMenu set bargraph [toplevel $window.bargraph$barnum] if { $title != "" } { wm title $bargraph $title } $gWindowMenu add command -label "$title $barnum" -command "capaRaise $bargraph" set buttonFrame [frame $bargraph.buttons] set canvasFrame [frame $bargraph.canvas] pack $buttonFrame $canvasFrame -side top pack configure $canvasFrame -expand 1 -fill both set canvas [canvas $canvasFrame.canvas -height $height -width $width -background white] pack $canvas -expand 1 -fill both bind $canvas "CTdrawBargraph $barnum" button $buttonFrame.change -text "Change Graph" -command "CTchangeBargraph $window $barnum" button $buttonFrame.save -text "Save Graph" -command "CTsaveCanvas $canvas $path" button $buttonFrame.print -text "Print Graph" -command "CTprintCanvas $num $canvas $path" button $buttonFrame.dismiss -text "Dismiss" -command "CTdestroyBargraph $barnum" pack $buttonFrame.change $buttonFrame.save $buttonFrame.print \ $buttonFrame.dismiss -side left bind $bargraph "CTdestroyBargraph $barnum" set gBarGraph($barnum.num) $num set gBarGraph($barnum.suffix) $suffix set gBarGraph($barnum) $data set gBarGraph($barnum.canvas) $canvas set gBarGraph($barnum.title) $title set gBarGraph($barnum.xlabel) $xlabel set gBarGraph($barnum.ylabel) $ylabel set gBarGraph($barnum.color) green set gBarGraph($barnum.bucketscores) 0 CTautoscaleBargraph $barnum CTdrawBargraph $barnum } ########################################################### # CTautoscaleBargraph ########################################################### ########################################################### ########################################################### proc CTautoscaleBargraph { barnum } { global gBarGraph set data $gBarGraph($barnum) set max [lindex [lindex [lsort -decreasing -index 0 -real $data] 0] 0] if { $max > int($max) } { set max [expr int($max+1)] } set gBarGraph($barnum.yoften) [expr int([format "%1.e" [expr $max/10.0]])] if { $gBarGraph($barnum.yoften) == 0 } { set gBarGraph($barnum.yoften) 1 } set total [llength $data] set gBarGraph($barnum.xoften) [expr ($total/25) + 1] } ########################################################### # CTchangeBargraphData ########################################################### ########################################################### ########################################################### proc CTchangeBargraphData { barnum data } { global gBarGraph set gBarGraph($barnum) $data CTautoscaleBargraph $barnum CTdrawBargraph $barnum } ########################################################### # CTdestroyBargraph ########################################################### ########################################################### ########################################################### proc CTdestroyBargraph { num } { global gBarGraph if { [catch {set window [winfo toplevel $gBarGraph($num.canvas)]}]} { return } set window2 [file rootname $window].changeBarGraph$num foreach name [array names gBarGraph "$num.*" ] { unset gBarGraph($name) } unset gBarGraph($num) destroy $window catch {destroy $window2} } ########################################################### # CTdrawBargraph ########################################################### ########################################################### ########################################################### proc CTdrawBargraph { num } { global gBarGraph set data $gBarGraph($num) set canvas $gBarGraph($num.canvas) set suffix $gBarGraph($num.suffix) set height [winfo height $canvas] set width [winfo width $canvas] set titleoffset 0 set titleheight 15 set labelheight 15 set tickheight 15 set textheight [expr $labelheight+$tickheight] set textwidth 40 set graphheight [expr $height - $textheight - $titleheight] set graphwidth [expr $width - $textwidth] $canvas delete all #draw data set total [llength $data] set eachwidth [expr $graphwidth/$total] # set howoften [expr ($total/$gBarGraph($num.numlabels)) + 1] set howoften $gBarGraph($num.xoften) set when [expr ($total-1)%$howoften] set max 0 set i 0 set value 0 if { $gBarGraph($num.bucketscores) } { foreach datum $data { set value [expr {$value + [lindex $datum 0]}] if { $i % $howoften == $when } { if { $value > $max } { set max $value } set value 0 } incr i } } else { set max [lindex [lindex [lsort -decreasing -index 0 -real $data] 0] 0] } if { $max > int($max) } { set max [expr int($max+1)] } if { [catch {set pixelvalue [expr ($graphheight-1)/double($max)]} ] } { set pixelvalue 10 } set i 0 set value 0 foreach datum $data { set value [expr {$value + [lindex $datum 0]}] set which [lindex $datum 1] set y1 [expr {$graphheight + $titleheight}] set x2 [expr {$eachwidth * ($i+1) + $textwidth}] set y2 [expr {($graphheight-1) + $titleheight - $value * $pixelvalue}] set tag bar.$which.[expr $which-$howoften] if { [set color [lindex $datum 3]] == "" } {set color $gBarGraph($num.color)} if { $gBarGraph($num.bucketscores) && ($i % $howoften == $when) } { if { $i == $when } { # puts "$value-$which-$howoften" $canvas create rectangle $textwidth \ $y1 $x2 $y2 -fill $color -tag $tag } else { # puts "$value:$which:$howoften" $canvas create rectangle [expr {$eachwidth*($i-$howoften+1)+$textwidth}]\ $y1 $x2 $y2 -fill $color -tag $tag } } elseif { !$gBarGraph($num.bucketscores) } { $canvas create rectangle [expr {$eachwidth * $i + $textwidth}] \ $y1 $x2 $y2 -fill $color -tag bar.$which.[expr $which-1] set value 0 } if { $i % $howoften == $when } { $canvas create text [expr {$eachwidth * $i + $textwidth + $eachwidth/2}] \ [expr $graphheight+(($tickheight)/2)+$titleheight] -text $which set value 0 } incr i } #draw title $canvas create text [expr $textwidth+$titleoffset+($graphwidth/2)] 1 -anchor n\ -text $gBarGraph($num.title) #draw axis $canvas create line $textwidth [expr {$graphheight + $titleheight}] \ $textwidth [expr {$titleheight + 1}] #label xaxis $canvas create text [expr ($textwidth+($graphwidth/2))] \ [expr $titleheight+$graphheight+$tickheight+($labelheight/2)] \ -text $gBarGraph($num.xlabel) #label yaxis $canvas create text 1 1 -anchor nw -text $gBarGraph($num.ylabel) #draw tickmarks # set delta [format "%1.e" [expr ($max)/double($gBarGraph($num.numticks))]] set delta $gBarGraph($num.yoften) set start 0.0 while { $start < $max } { set center [expr {($graphheight-1)*(($start)/$max)+$titleheight+1}] $canvas create line $textwidth $center [expr $textwidth - 20] $center $canvas create text [expr $textwidth-3] $center -anchor ne -text [expr int($max-$start)] set start [expr $start + $delta] } if { [llength [lindex $data 0]] > 2} { $canvas bind current <1> "CTbargraphClick$suffix $num" bind $canvas "CTbargraphDisplayCreate $num" bind $canvas "CTbargraphDisplayRemove $num" bind $canvas "CTbargraphDisplayMove $num" $canvas bind all "CTbargraphDisplay$suffix $num" } } ########################################################### # CTbargraphDisplayCreate ########################################################### ########################################################### ########################################################### proc CTbargraphDisplayCreate { barnum } { global gBarGraph gCT gFile set canvas $gBarGraph($barnum.canvas) if {[winfo exists $canvas.bubble$barnum]} { return } set bubble [toplevel $canvas.bubble$barnum] wm overrideredirect $bubble 1 wm positionfrom $bubble program wm withdraw $bubble pack [label $bubble.l -highlightthickness 0 -relief raised -bd 1 -background yellow] } ########################################################### # CTbargraphDisplayRemove ########################################################### ########################################################### ########################################################### proc CTbargraphDisplayRemove { barnum } { global gBarGraph gCT gFile set canvas $gBarGraph($barnum.canvas) catch {destroy $canvas.bubble$barnum} } ########################################################### # CTbargraphDisplayBlank ########################################################### ########################################################### ########################################################### proc CTbargraphDisplayBlank { barnum } { global gBarGraph gCT gFile set canvas $gBarGraph($barnum.canvas) catch {$canvas.bubble$barnum.l configure -text ""} } ########################################################### # CTbargraphDisplayMove ########################################################### ########################################################### ########################################################### proc CTbargraphDisplayMove { barnum } { global gBarGraph gCT gFile set canvas $gBarGraph($barnum.canvas) catch {wm geometry $canvas.bubble$barnum +[expr 20+[winfo pointerx .]]+[expr 20+[winfo pointery .]]} if {[$canvas gettags current] == ""} {CTbargraphDisplayRemove $barnum} } ########################################################### # CTbargraphDisplayShowresponse ########################################################### ########################################################### ########################################################### proc CTbargraphDisplayShowresponse { barnum } { global gBarGraph gCT gFile set num $gBarGraph($barnum.num) set canvas $gBarGraph($barnum.canvas) set high [lindex [split [lindex [$canvas gettags current] 0] .] 1] foreach datum $gBarGraph($barnum) { set bar [lindex $datum 1] if { $bar != $high } { continue } if {![winfo exists $canvas.bubble$barnum.l]} {CTbargraphDisplayCreate $barnum} $canvas.bubble$barnum.l configure -text "[lindex $datum 0] - \"[splitline [lindex $datum 2] 35]\"" wm geometry $canvas.bubble$barnum +[expr 20+[winfo pointerx .]]+[expr 20+[winfo pointery .]] wm deiconify $canvas.bubble$barnum return } CTbargraphDisplayRemove $barnum } ########################################################### # CTbargraphDisplaySCP ########################################################### ########################################################### ########################################################### proc CTbargraphDisplaySCP { barnum } { global gBarGraph gCT gFile set num $gBarGraph($barnum.num) set canvas $gBarGraph($barnum.canvas) set high [lindex [split [lindex [$canvas gettags current] 0] .] 1] foreach datum $gBarGraph($barnum) { set bar [lindex $datum 1] if { $bar != $high } { continue } if {![winfo exists $canvas.bubble$barnum.l]} {CTbargraphDisplayCreate $barnum} $canvas.bubble$barnum.l configure -text "[lindex $datum 0]" wm geometry $canvas.bubble$barnum +[expr 20+[winfo pointerx .]]+[expr 20+[winfo pointery .]] wm deiconify $canvas.bubble$barnum return } CTbargraphDisplayRemove $barnum } ########################################################### # CTbargraphClickSCP ########################################################### ########################################################### ########################################################### proc CTbargraphClickSCP { barnum } { global gBarGraph gCT gFile set num $gBarGraph($barnum.num) set canvas $gBarGraph($barnum.canvas) set bucket $gBarGraph($barnum.bucketscores) set high [lindex [split [lindex [$canvas gettags current] 0] .] 1] set low [lindex [split [lindex [$canvas gettags current] 0] .] 2] set stunums "" if { $high == "" || $low == "" } { return } foreach datum $gBarGraph($barnum) { set bar [lindex $datum 1] if { $bar > $high || $bar <= $low } { continue } set stunums [concat $stunums [lindex $datum 2]] } if { $stunums == "" } { return } if {"" == [set stuSCP [multipleChoice $gCT($num) "Select a student" $stunums 0]]} { return } set loginAnalysis [expr {"Yes" == [makeSure "Do you wish to do a Login Analysis? It may take a while." ]}] foreach s_id $stuSCP { CTstudentCourseProfile $num $s_id \ [findByStudentNumber $s_id $gFile($num)] $loginAnalysis } } ########################################################### # CTbargraphClickShowresponse ########################################################### ########################################################### ########################################################### proc CTbargraphClickShowresponse { barnum } { global gBarGraph gCT gFile gUniqueNumber set num $gBarGraph($barnum.num) set canvas $gBarGraph($barnum.canvas) set bucket $gBarGraph($barnum.bucketscores) if { [catch {set datanum $gBarGraph($barnum.shownum1)}] } { set datanum [set gBarGraph($barnum.shownum1) [incr gUniqueNumber]] set winnum [set gBarGraph($barnum.shownum2) [incr gUniqueNumber]] } else { set winnum $gBarGraph($barnum.shownum2) } set gCT($winnum) "" set high [lindex [split [lindex [$canvas gettags current] 0] .] 1] foreach datum $gBarGraph($barnum) { set bar [lindex $datum 1] if { $bar != $high } { continue } CTputs $datanum "[lindex $datum 0] responses \"[lindex $datum 2]\"\n" } CToutput $winnum $datanum } ########################################################### # CTchangeBargraph ########################################################### ########################################################### ########################################################### proc CTchangeBargraph { window num } { global gBarGraph set change [toplevel $window.changeBarGraph$num] set infoFrame [frame $change.info] set buttonFrame [frame $change.button] set title [frame $change.title] set xlabel [frame $change.xlabel] set ylabel [frame $change.ylabel] set xoften [frame $change.xoften] set yoften [frame $change.yoften] set color [frame $change.color] set bucket [frame $change.bucket] set font [frame $change.font] pack $infoFrame $buttonFrame $title $xlabel $ylabel $xoften $yoften $color $bucket pack configure $title $xlabel $ylabel $xoften $yoften -anchor e -expand 1 -fill both button $buttonFrame.update -text Update -command "CTdrawBargraph $num" bind $change "CTdrawBargraph $num" button $buttonFrame.dismiss -text Dismiss -command "destroy $change" pack $buttonFrame.update $buttonFrame.dismiss -side left foreach {frame label var } "$title { Title} title $xlabel { X-Axis Label} xlabel $ylabel { Y-Axis Label} ylabel $xoften {Increment on X-Axis} xoften $yoften {Increment on Y-Axis} yoften" { label $frame.label -text $label set entryFrame [frame $frame.entry] pack $frame.label $entryFrame -side left pack configure $entryFrame -expand 1 -fill both entry $entryFrame.entry -textvariable gBarGraph($num.$var) \ -xscrollcommand "$entryFrame.scroll set" scrollbar $entryFrame.scroll -orient h -command \ "$entryFrame.entry xview" pack $entryFrame.entry $entryFrame.scroll -fill x } label $color.label -text "Color of Bars" label $color.color -relief ridge -background $gBarGraph($num.color) \ -text " " button $color.change -text "Change" -command "CTchangeBargraphColor $color $num" pack $color.label $color.color $color.change -side left checkbutton $bucket.bucket -text "Bucket Scores" -variable \ gBarGraph($num.bucketscores) -command "CTdrawBargraph $num" pack $bucket.bucket } ########################################################### # CTchangeBargraphColor ########################################################### ########################################################### ########################################################### proc CTchangeBargraphColor { color num } { global gBarGraph set temp [tk_chooseColor -initialcolor $gBarGraph($num.color)] if { $temp != "" } { $color.color configure -background [set gBarGraph($num.color) $temp] } CTdrawBargraph $num } ########################################################### # CTdisplayStudent ########################################################### ########################################################### ########################################################### proc CTdisplayStudent { num window path id } { if { ![file exists [file join $path photo gif $id.gif]] } { if { [file exists [file join $path photo jpg $id.jpg]] } { exec /usr/local/bin/djpeg -outfile [file join $path photo gif $id.gif] \ [file join $path photo jpg $id.jpg] } else { return } } set image [image create photo] $image read [file join $path photo gif $id.gif] set imageWin [toplevel $window.image$num] set buttonFrame [frame $imageWin.button] set infoFrame [frame $imageWin.info] set imageFrame [frame $imageWin.image] pack $buttonFrame $infoFrame $imageFrame button $buttonFrame.dismiss -command "destroy $imageWin" -text Dismiss pack $buttonFrame.dismiss label $infoFrame.label -text $id pack $infoFrame.label set canvas [canvas $imageFrame.canvas] pack $canvas $canvas create image 1 1 -image $image -anchor nw } ########################################################### # CTgetWhen ########################################################### ########################################################### ########################################################### proc CTgetWhen { num } { set day [getString . "Enter a date"] update return $day } ########################################################### # CTscanDB ########################################################### ########################################################### ########################################################### proc CTscanDB { num file outId startdate enddate } { global answerArray exist set fileId [open $file r] set Yes_cnt 0 set No_cnt 0 set line_cnt 0 set prob_cnt 0 set maxLine [lindex [exec wc $file] 0] puts $maxLine set aline [gets $fileId] while { ! [eof $fileId] } { incr line_cnt if { ($line_cnt%20) == 0 } { puts $curdate updateStatusBar [expr $line_cnt/double($maxLine)] $num } set length [llength $aline] set date [lrange $aline 1 [expr $length - 2]] set curdate [clock scan $date] if { $curdate < $startdate } { set aline [gets $fileId]; continue } if { $curdate > $enddate } { break } set s_num [string toupper [lindex $aline 0]] set ans_char [split [lindex $aline end] ""] set usr_ans "$s_num.ans" set usr_try "$s_num.try" if {$prob_cnt == 0} { set prob_cnt [llength $ans_char] } if { [array names answerArray "$usr_ans.*"] == "" } { for {set ii 0} { $ii <= $prob_cnt } { incr ii} { set answerArray($usr_ans.$ii) "-" } } if { [array names answerArray "$usr_try.*"] == "" } { for {set ii 0} { $ii <= $prob_cnt } { incr ii} { set answerArray($usr_try.$ii) 0 } } for {set ii 0} { $ii <= $prob_cnt } { incr ii} { if { [lindex $ans_char $ii] == "Y" } { set answerArray($usr_ans.$ii) "Y" incr answerArray($usr_try.$ii) } if { [lindex $ans_char $ii] == "N"} { if {$answerArray($usr_ans.$ii) != "Y"} { set answerArray($usr_ans.$ii) "Y" } incr answerArray($usr_try.$ii) } } if { [array names exist $s_num] == "" } { set exist($s_num) $s_num } set aline [gets $fileId] } close $fileId return $prob_cnt } ########################################################### # CTcreateSubset ########################################################### ########################################################### ########################################################### proc CTcreateSubset { num cmdnum day setId } { global gFile gCT answerArray exist set outId [open [file join $gFile($num) records "subset$setId.db"] w] set inId [open [file join $gFile($num) records "set$setId.db"] r] set startdate [clock scan "$day 12:00 AM"] set enddate [clock scan "$day 11:59 PM"] puts $startdate:$enddate set prob_cntt [CTscanDB $cmdnum [file join $gFile($num) records log$setId.db] $outId $startdate $enddate] puts $startdate:$enddate set prob_cntw [CTscanDB $cmdnum [file join $gFile($num) records weblog$setId.db] $outId $startdate $enddate] puts $startdate:$enddate puts "$day 12:00 AM : $day 11:59 PM" if { $prob_cntt > $prob_cntw } { set prob_cnt $prob_cntt } else { set prob_cnt $prob_cntw } puts $outId [gets $inId] puts $outId [gets $inId] puts $outId [gets $inId] foreach s_num [lsort [array names exist]] { set usr_ans $s_num.ans set usr_try $s_num.try puts -nonewline $outId "$s_num " for { set ii 0 } { $ii< $prob_cnt } { incr ii } { puts -nonewline $outId $answerArray($usr_ans.$ii) } for { set ii 0 } { $ii< $prob_cnt } { incr ii } { puts -nonewline $outId [format ",%2d" $answerArray($usr_try.$ii)] } puts $outId "" } close $outId close $inId catch {unset answerArray} catch {unset exist} } ########################################################### # CTdiscussForum ########################################################### ########################################################### ########################################################### proc CTdiscussForum { num file dir resultVar {specificSet 0}} { global gCT upvar $resultVar result if { $specificSet == 0 } { set start 1 } else { set start $specificSet } set fileId [open $file r] set maxLine [lindex [exec wc $file] 0] set aline [gets $fileId] set last 0 set line_cnt 0 while {![eof $fileId]} { incr line_cnt if { ($line_cnt%20) == 0 } { updateStatusBar [expr $line_cnt/double($maxLine)] $num } foreach {stunum capaid name email action set prob date time} [split $aline "|"] {} if {$specificSet && ($specificSet == $set)} {set aline [gets $fileId];continue} if { $action == "ViewProblem" } { if { [catch {incr count($set,$prob)}]} { set count($set,$prob) 1 if { $set > $last } { set last $set } if { [catch {set max($set)}]} { set max($set) 0 } if { $prob > $max($set)} { set max($set) $prob } if { [catch {set posts($set,$prob) [llength [glob $dir/discussion/$set/[format "%06d" $prob]-*-*-*.msg]]}]} { set posts($set,$prob) 0 } } set ever($name) 1 set names($set,$name) 1 set nameprob($set,$prob,$name) 1 } set aline [gets $fileId] } updateStatusMessage "Summarizing Data" $num updateStatusBar 0 $num for {set i 1} { $i <= $last } { incr i } { updateStatusBar [expr $i/$last] $num set total($i) 0 for {set j 1} { $j <= $max($i) } { incr j } { set message "" if {[catch { set result($num.$i.$j.posts) $posts($i,$j) }]} { set result($num.$i.$j.posts) 0 } if {[catch {set result($num.$i.$j.views) $count($i,$j)}]} { set result($num.$i.$j.views) 0 } catch {incr total($i) $count($i,$j)} if { [catch { set result($num.$i.$j.ratio) \ [expr $result($num.$i.$j.views)/double($result($num.$i.$j.posts))]} error]} { set result($num.$i.$j.ratio) 0.0 } set result($num.$i.$j.viewers) [llength [array names nameprob $i,$j,*]] } set result($num.$i.views) $total($i) set result($num.$i.max) $max($i) } for {set i 1} { $i<=$last } { incr i } { set result($num.$i.viewers) [llength [array names names $i,*]] } close $fileId set result($num.viewers) [llength [array names ever]] set result($num.last) $last #IDEAS: stick into capastats # : howmany viws are repeats # : Student Course Profile, add #ViewProblems #Posts # : add some portion of these stats to analyze log files? } ########################################################### # CTputsDiscussResults ########################################################### ########################################################### proc CTputsDiscussResults { num resultsVar } { upvar $resultsVar result for {set i 1} { $i <= $result($num.last) } { incr i } { CTputs $num "For Set $i #Visitors:$result($num.$i.viewers) did #views:$result($num.$i.views)\n" CTputs $num "Prob# #Posts #Views Ratio #UniqueStu\n" CTputs $num "------------------------------------\n" for {set j 1} { $j <= $result($num.$i.max)} { incr j } { CTputs $num [format "%5d %6d %6d %5s %6d\n" $j \ $result($num.$i.$j.posts) $result($num.$i.$j.views) \ [if {$result($num.$i.$j.ratio) == 0.0} {set temp " "} \ {format %.1f $result($num.$i.$j.ratio)}] \ $result($num.$i.$j.viewers)] } } CTputs $num "Overall Unique #viewers: $result($num.viewers)\n" } ########################################################### # CTcreateReportDialog ########################################################### ########################################################### ########################################################### proc CTcreateReportDialog { num cmdnum } { global gCT gFile set gCT(summary.section.$cmdnum) 1 set gCT(summary.set.$cmdnum) 1 set summary [toplevel $gCT($num).summary] set whoFrame [frame $summary.whoFrame -borderwidth 4 -relief groove] set whichFrame [frame $summary.whichFrame -borderwidth 4 -relief groove] set sortFrame [frame $summary.sortFrame] set file2Frame [frame $summary.file2Frame] set buttonFrame [frame $summary.buttonFrame] pack $whoFrame $whichFrame $sortFrame $file2Frame $buttonFrame -side top pack configure $whoFrame $whichFrame -padx 10 -pady 10 set sectionFrame [frame $whoFrame.section] set allFrame [frame $whoFrame.all] pack $sectionFrame $allFrame -side top set gCT(summary.who.$cmdnum) section radiobutton $sectionFrame.section -text \ "For students in default section:" -variable gCT(summary.who.$cmdnum) \ -value section entry $sectionFrame.entry -textvariable gCT(summary.section.$cmdnum) -width 3 pack $sectionFrame.section $sectionFrame.entry -side left radiobutton $allFrame.all -text "For all students in the class" \ -variable gCT(summary.who.$cmdnum) -value all pack $allFrame.all set sectionFrame [frame $whichFrame.section] set allFrame [frame $whichFrame.all] pack $sectionFrame $allFrame -side top set gCT(summary.which.$cmdnum) specific radiobutton $sectionFrame.section -text "For set:" \ -variable gCT(summary.which.$cmdnum) -value specific entry $sectionFrame.entry -textvariable gCT(summary.set.$cmdnum) -width 3 pack $sectionFrame.section $sectionFrame.entry -side left radiobutton $allFrame.all -text "For all sets up to:" -variable \ gCT(summary.which.$cmdnum) -value upto entry $allFrame.entry -textvariable gCT(summary.set.$cmdnum) -width 3 pack $allFrame.all $allFrame.entry -side left set firstFrame [frame $sortFrame.firstFrame -borderwidth 4 -relief groove] set secondFrame [frame $sortFrame.secondFrame -borderwidth 4 \ -relief groove] pack $firstFrame $secondFrame -side left set gCT(summary.first.$cmdnum) name label $firstFrame.label -text "Sorting Order - Primary" radiobutton $firstFrame.name -text "Student Name" -variable \ gCT(summary.first.$cmdnum) -value name radiobutton $firstFrame.number -text "Student Number" -variable \ gCT(summary.first.$cmdnum) -value number radiobutton $firstFrame.section -text "Section" -variable \ gCT(summary.first.$cmdnum) -value section radiobutton $firstFrame.grade -text "Grade" -variable gCT(summary.first.$cmdnum) \ -value grade pack $firstFrame.label $firstFrame.name $firstFrame.number \ $firstFrame.section $firstFrame.grade -side top -anchor w set gCT(summary.second.$cmdnum) number label $secondFrame.label -text "Sorting Order - Secondary" radiobutton $secondFrame.name -text "Student Name" -variable \ gCT(summary.second.$cmdnum) -value name radiobutton $secondFrame.number -text "Student Number" -variable \ gCT(summary.second.$cmdnum) -value number radiobutton $secondFrame.section -text "Section" -variable \ gCT(summary.second.$cmdnum) -value section radiobutton $secondFrame.grade -text "Grade" -variable gCT(summary.second.$cmdnum) \ -value grade pack $secondFrame.label $secondFrame.name $secondFrame.number \ $secondFrame.section $secondFrame.grade -side top -anchor w set defaultFrame [frame $file2Frame.defaultFrame] set fileFrame [frame $file2Frame.fileFrame] pack $defaultFrame $fileFrame -side top set gCT(summary.filename.$cmdnum) default radiobutton $defaultFrame.default -text "Grader Chooses File Name" \ -variable gCT(summary.filename.$cmdnum) -value default pack $defaultFrame.default radiobutton $fileFrame.label -text "Specified Output File:" \ -variable gCT(summary.filename.$cmdnum) -value specified set entryFrame [frame $fileFrame.entryFrame] button $fileFrame.select -text "Select File" \ -command "selectOutputFile" pack $fileFrame.label $entryFrame $fileFrame.select -side left entry $entryFrame.entry -textvariable gCT(summary.file.$cmdnum) \ -xscrollcommand "$entryFrame.scroll set" scrollbar $entryFrame.scroll -orient h -command \ "$entryFrame.entry xview" pack $entryFrame.entry $entryFrame.scroll pack configure $entryFrame.scroll -fill x button $buttonFrame.create -text "Create" -command \ "removeWindowEntry Summary destroy $summary CTcreateSummaryReport $num $cmdnum" button $buttonFrame.cancel -text "Cancel" -command \ "removeWindowEntry Summary destroy $summary" pack $buttonFrame.create $buttonFrame.cancel -side left Centre_Dialog $summary default } ########################################################### # CTcreateSummaryReport ########################################################### ########################################################### ########################################################### proc CTcreateSummaryReport { num cmdnum } { global gCT gFile displayStatus "Opening File" both $cmdnum switch $gCT(summary.who.$cmdnum) { all { set file ClassSet$gCT(summary.set.$cmdnum).rpt } section { set file Sec$gCT(summary.section.$cmdnum)Set$gCT(summary.set.$cmdnum).rpt } default { displayError "An error has occured while creating a summary \ report $gCT(summary.section.$cmdnum)" return } } if { $gCT(summary.filename.$cmdnum) == "specified" } { set file $gCT(summary.file.$cmdnum) } if { $file == "" } { removeStatus displayError "Must specify a valid filename" return } updateStatusMessage "Creating Summary" $cmdnum set cwd [pwd] cd $gFile($num) set error [ catch {CTcreateSummary $file $cmdnum} ] cd $cwd removeStatus $cmdnum if {!$error && "Yes" == [makeSure "Created summary file $file, would you like to see it?"]} { set fileId [open [file join $gFile($num) $file] r] CTputs $cmdnum [read $fileId] CToutput $num $cmdnum } }