1: # The LearningOnline Network with CAPA
2: #
3: # $Id: loncorrectproblemplot.pm,v 1.3 2004/02/02 21:52:28 matthew Exp $
4: #
5: # Copyright Michigan State University Board of Trustees
6: #
7: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
8: #
9: # LON-CAPA is free software; you can redistribute it and/or modify
10: # it under the terms of the GNU General Public License as published by
11: # the Free Software Foundation; either version 2 of the License, or
12: # (at your option) any later version.
13: #
14: # LON-CAPA is distributed in the hope that it will be useful,
15: # but WITHOUT ANY WARRANTY; without even the implied warranty of
16: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17: # GNU General Public License for more details.
18: #
19: # You should have received a copy of the GNU General Public License
20: # along with LON-CAPA; if not, write to the Free Software
21: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22: #
23: # /home/httpd/html/adm/gpl.txt
24: #
25: # http://www.lon-capa.org/
26: #
27:
28: package Apache::loncorrectproblemplot;
29:
30: use strict;
31: use Apache::lonnet();
32: use Apache::loncommon();
33: use Apache::lonhtmlcommon();
34: use Apache::loncoursedata();
35: use Apache::lonstatistics;
36: use Apache::lonstathelpers;
37: use Apache::lonlocal;
38:
39: my @SubmitButtons = (
40: { name => 'CreatePlot',
41: text => 'Create Plot' },
42: { name => 'ClearCache',
43: text => 'Clear Caches' },
44: { name => 'updatecaches',
45: text => 'Update Student Data' },
46: );
47:
48: sub BuildCorrectProblemsPage {
49: my ($r,$c)=@_;
50: #
51: my %Saveable_Parameters = ('Status' => 'scalar',
52: 'Section' => 'array');
53: &Apache::loncommon::store_course_settings('correct_problems_plot',
54: \%Saveable_Parameters);
55: &Apache::loncommon::restore_course_settings('correct_problems_plot',
56: \%Saveable_Parameters);
57: #
58: &Apache::lonstatistics::PrepareClasslist();
59: #
60: $r->print('<h2>'.&mt('Number of Correct Problems Plot').'</h2>');
61: $r->print(&CreateInterface());
62: #
63: my @Students = @Apache::lonstatistics::Students;
64: #
65: if (@Students < 1) {
66: $r->print('<h2>'.
67: &mt('There are no students in the sections selected').
68: '</h2>');
69: }
70: #
71: &Apache::loncoursedata::clear_internal_caches();
72: if (exists($ENV{'form.ClearCache'}) ||
73: exists($ENV{'form.updatecaches'}) ||
74: (exists($ENV{'form.firstanalysis'}) &&
75: $ENV{'form.firstanalysis'} ne 'no')) {
76: &Apache::lonstatistics::Gather_Full_Student_Data($r);
77: }
78: if (! exists($ENV{'form.firstanalysis'})) {
79: $r->print('<input type="hidden" name="firstanalysis" value="yes" />');
80: } else {
81: $r->print('<input type="hidden" name="firstanalysis" value="no" />');
82: }
83: foreach my $button (@SubmitButtons) {
84: $r->print('<input type="submit" name="'.$button->{'name'}.'" '.
85: 'value="'.&mt($button->{'text'}).'" />');
86: $r->print(' 'x5);
87: }
88: $r->rflush();
89: #
90: # Determine which problem symbs we are to sum over
91: if (exists($ENV{'form.CreatePlot'})) {
92: my @ProblemSymbs;
93: if ($Apache::lonstatistics::SelectedMaps[0] ne 'all') {
94: foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()){
95: foreach my $res (@{$seq->{'contents'}}) {
96: next if ($res->{'type'} ne 'assessment');
97: foreach my $part (@{$res->{'parts'}}) {
98: push(@ProblemSymbs,{symb=>$res->{'symb'},
99: part=>$part});
100: }
101: }
102: }
103: }
104: my $score_data = &Apache::loncoursedata::get_student_scores
105: (\@Apache::lonstatistics::SelectedSections,
106: \@ProblemSymbs,
107: $Apache::lonstatistics::enrollment_status);
108: $r->print(&AnalyzeScoreData($score_data));
109: }
110: return;
111: }
112:
113: #########################################################
114: #########################################################
115:
116: =pod
117:
118: =item & AnalyzeScoreData($score_data)
119:
120: Analyze the result of &Apache::loncoursedata::get_student_scores() and
121: return html with a plot of the data and a table of the values and bins.
122:
123: =cut
124:
125: #########################################################
126: #########################################################
127: sub AnalyzeScoreData {
128: my ($score_data) = @_;
129: #
130: # Basic check first
131: if (@$score_data < 1) {
132: return '<h2>There is no data to plot</h2>';
133: }
134: #
135: # Determine which bins to use
136: my $lowest = $score_data->[0]->[0];
137: $lowest = 0;
138: my $highest = $score_data->[-1]->[0];
139: my $binsize = 1;
140: if ($highest > 50) { $binsize = 2; }
141: if ($highest > 100) { $binsize = 5; }
142: if ($highest > 200) { $binsize = 10; }
143: if ($highest > 500) { $binsize = 20; }
144: if ($highest > 1000) { $binsize = 50; }
145: if ($highest > 2000) { $binsize = 100; }
146: #
147: # Get the data into the bins (destroying $score_data in the process)
148: my @Bins = &bin_data($score_data,$binsize,$lowest,$highest);
149: my @Xdata; my @Ydata; my $max;
150: my $Str = '<table border="1">'."\n".'<tr><th>Range</th><th>Count</th></tr>'."\n";
151: while (my $bin = shift(@Bins)) {
152: push (@Xdata,$bin->{'start'});
153: push (@Ydata,$bin->{'count'});
154: if ($bin->{'count'} > $max) {
155: $max = $bin->{'count'};
156: }
157: $Str.= '<tr><td>'.$bin->{'start'}.' - '.$bin->{'end'}.'</td>'.
158: '<td>'.$bin->{'count'}.'</td></tr>'."\n";
159: }
160: my $title = '';
161: $Str .= "</table><br />\n";
162: $Str = "<br />\n".&Apache::loncommon::DrawBarGraph($title,
163: 'Num Correct Problems',
164: 'Number of students',
165: $max,
166: undef, # colors
167: \@Xdata,
168: \@Ydata).
169: "\n<br />\n".$Str;
170: return $Str;
171: }
172:
173:
174: #########################################################
175: #########################################################
176:
177: =pod
178:
179: =item &bin_data($data,$binsize,$startbin,$endbin)
180:
181: Note: This routine destroys the array of data passed to it.
182:
183: Inputs: $data: array reference - the contents of @$data must
184: be arrays with x and y data. $data = [ [x1,y1],[x2,y2],...];
185: $binsize: Width of bins to put data in
186: $startbin: the starting bin.
187: $endbin: the ending bin.
188: Returns: Array of Bins. Each bin is a hash reference with the following
189: keys: 'start', 'count', and 'end'.
190:
191: =cut
192:
193: #########################################################
194: #########################################################
195: sub bin_data {
196: my ($data,$binsize,$startbin,$endbin)=@_;
197: return () if (! defined($data) || ref($data) ne 'ARRAY');
198: #
199: # Determine bin geometry
200: my $binstart = $startbin;
201: my $binend = $startbin+$binsize;
202: # put the data into bins
203: my @Bins;
204: my $count=0;
205: my $idx=0;
206: while ($idx < scalar(@$data) && ($binend-$endbin)<$binsize) {
207: my $dataset = $data->[$idx++];
208: my ($x,$y) = @{$dataset};
209: while ($x > $binend) {
210: # store the old data
211: push (@Bins,{ start => $binstart,
212: count => $count,
213: end => $binend });
214: # start counting again
215: $binstart += $binsize;
216: $binend += $binsize;
217: $count = 0;
218: }
219: $count+=$y;
220: }
221: return @Bins;
222: }
223:
224: #########################################################
225: #########################################################
226:
227: =pod
228:
229: =item &CreateInterface
230:
231: Inputs: none.
232:
233: Returns: HTML for the correct problems plot interface.
234:
235: =cut
236:
237: #########################################################
238: #########################################################
239: sub CreateInterface {
240: ##
241: ## Environment variable initialization
242: my $Str;
243: $Str .= '<table cellspacing="5">'."\n";
244: $Str .= '<tr>';
245: $Str .= '<td align="center"><b>'.&mt('Sections').'</b></td>';
246: $Str .= '<td align="center"><b>'.&mt('Enrollment Status').'</b></td>';
247: $Str .= '<td align="center"><b>'.&mt('Sequences and Folders').'</b></td>';
248: $Str .= '</tr>'."\n";
249: ##
250: ##
251: $Str .= '<tr><td align="center">'."\n";
252: $Str .= &Apache::lonstatistics::SectionSelect('Section','multiple',5);
253: $Str .= '</td>';
254: #
255: $Str .= '<td align="center">';
256: $Str .= &Apache::lonhtmlcommon::StatusOptions(undef,undef,5);
257: $Str .= '</td><td>'."\n";
258: #
259: my $only_seq_with_assessments = sub {
260: my $s=shift;
261: if ($s->{'num_assess'} < 1) {
262: return 0;
263: } else {
264: return 1;
265: }
266: };
267: $Str .= &Apache::lonstatistics::MapSelect('Maps','multiple,all',5,
268: $only_seq_with_assessments);
269: $Str .= '</td><td>'."\n";
270: ##
271: $Str .= '</tr>'."\n";
272: $Str .= '</table>'."\n";
273: return $Str;
274: }
275:
276: 1;
277:
278: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>