File:
[LON-CAPA] /
loncom /
interface /
statistics /
loncorrectproblemplot.pm
Revision
1.9:
download - view:
text,
annotated -
select for diffs
Sun Mar 7 20:53:41 2004 UTC (20 years, 5 months ago) by
matthew
Branches:
MAIN
CVS tags:
HEAD
loncoursedata.pm: &get_student_scores modified to limit by time.
loncorrectproblemplot.pm: Added time limits, corrected "bin"ing bug which
caused the last data set to be missed, plot title is now the sequence
being analyzed or "Multiple Sequences", added "N", the number of students,
to the title. Added the maximum possible number of correct problems to
the x-axis label.
1: # The LearningOnline Network with CAPA
2: #
3: # $Id: loncorrectproblemplot.pm,v 1.9 2004/03/07 20:53:41 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: #########################################################
49: #########################################################
50:
51: =pod
52:
53: =item &BuildCorrectProblemsPage
54:
55: Entry point from lonstatistics to the correct problems plot page.
56:
57: =cut
58:
59: #########################################################
60: #########################################################
61:
62: sub BuildCorrectProblemsPage {
63: my ($r,$c)=@_;
64: #
65: my %Saveable_Parameters = ('Status' => 'scalar',
66: 'Section' => 'array');
67: &Apache::loncommon::store_course_settings('correct_problems_plot',
68: \%Saveable_Parameters);
69: &Apache::loncommon::restore_course_settings('correct_problems_plot',
70: \%Saveable_Parameters);
71: #
72: &Apache::lonstatistics::PrepareClasslist();
73: #
74: $r->print(&CreateInterface());
75: #
76: my @Students = @Apache::lonstatistics::Students;
77: #
78: if (@Students < 1) {
79: $r->print('<h2>'.
80: &mt('There are no students in the sections selected').
81: '</h2>');
82: }
83: #
84: &Apache::loncoursedata::clear_internal_caches();
85: if (exists($ENV{'form.ClearCache'}) ||
86: exists($ENV{'form.updatecaches'}) ||
87: (exists($ENV{'form.firstanalysis'}) &&
88: $ENV{'form.firstanalysis'} ne 'no')) {
89: &Apache::lonstatistics::Gather_Full_Student_Data($r);
90: }
91: if (! exists($ENV{'form.firstanalysis'})) {
92: $r->print('<input type="hidden" name="firstanalysis" value="yes" />');
93: } else {
94: $r->print('<input type="hidden" name="firstanalysis" value="no" />');
95: }
96: foreach my $button (@SubmitButtons) {
97: $r->print('<input type="submit" name="'.$button->{'name'}.'" '.
98: 'value="'.&mt($button->{'text'}).'" />');
99: $r->print(' 'x5);
100: }
101: $r->rflush();
102: #
103: # Determine which problem symbs we are to sum over
104: if (exists($ENV{'form.CreatePlot'})) {
105: my @ProblemSymbs;
106: my $total_parts = 0;
107: my $title = '';
108: if ($Apache::lonstatistics::SelectedMaps[0] ne 'all') {
109: foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()){
110: if ($title eq '') {
111: $title = $seq->{'title'};
112: } else {
113: $title = 'Multiple Sequences';
114: }
115: foreach my $res (@{$seq->{'contents'}}) {
116: next if ($res->{'type'} ne 'assessment');
117: foreach my $part (@{$res->{'parts'}}) {
118: $total_parts++;
119: push(@ProblemSymbs,{symb=>$res->{'symb'},
120: part=>$part});
121: }
122: }
123: }
124: }
125: my ($starttime,$endtime) = &Apache::lonstathelpers::get_time_limits();
126: my $score_data = &Apache::loncoursedata::get_student_scores
127: (\@Apache::lonstatistics::SelectedSections,
128: \@ProblemSymbs,
129: $Apache::lonstatistics::enrollment_status,undef,
130: $starttime,$endtime);
131: $r->print(&AnalyzeScoreData($score_data,$title,$total_parts));
132: }
133: return;
134: }
135:
136: #########################################################
137: #########################################################
138:
139: =pod
140:
141: =item & AnalyzeScoreData($score_data)
142:
143: Analyze the result of &Apache::loncoursedata::get_student_scores() and
144: return html with a plot of the data and a table of the values and bins.
145:
146: =cut
147:
148: #########################################################
149: #########################################################
150: sub AnalyzeScoreData {
151: my ($score_data,$title,$total_parts) = @_;
152: #
153: # Basic check first
154: if (@$score_data < 1) {
155: return '<h2>There is no data to plot</h2>';
156: }
157: #
158: # Determine which bins to use
159: my $lowest = $score_data->[0]->[0];
160: $lowest = 0;
161: my $highest = $score_data->[-1]->[0];
162: &Apache::lonnet::logthis('highest = '.$highest);
163: my $binsize = 1;
164: if ($highest > 50) { $binsize = 2; }
165: if ($highest > 100) { $binsize = 5; }
166: if ($highest > 200) { $binsize = 10; }
167: if ($highest > 500) { $binsize = 20; }
168: if ($highest > 1000) { $binsize = 50; }
169: if ($highest > 2000) { $binsize = 100; }
170: #
171: # Get the data into the bins (destroying $score_data in the process)
172: my @Bins = &bin_data($score_data,$binsize,$lowest,$highest);
173: my @Xdata; my @Ydata; my $max;
174: my $Str = '<table border="1">'."\n".'<tr><th>Range</th><th>Count</th></tr>'."\n";
175: my $sum = 0;
176: while (my $bin = shift(@Bins)) {
177: push (@Xdata,$bin->{'start'});
178: push (@Ydata,$bin->{'count'});
179: $sum += $bin->{'count'};
180: if ($bin->{'count'} > $max) {
181: $max = $bin->{'count'};
182: }
183: $Str.= '<tr><td>'.$bin->{'start'}.' - '.$bin->{'end'}.'</td>'.
184: '<td>'.$bin->{'count'}.'</td></tr>'."\n";
185: }
186: # scale max to an integer.
187: $max = 5*(int($max/5)+1);
188: $Str .= "</table><br />\n";
189: $title = &HTML::Entities::decode($title);
190: $Str = "<br />\n".&Apache::loncommon::DrawBarGraph($title.' N = '.$sum,
191: 'Num Correct Problems (max:'.$total_parts.')',
192: 'Number of students',
193: $max,
194: undef, # colors
195: \@Xdata,
196: \@Ydata).
197: "\n<br />\n".$Str;
198: return $Str;
199: }
200:
201:
202: #########################################################
203: #########################################################
204:
205: =pod
206:
207: =item &bin_data($data,$binsize,$startbin,$endbin)
208:
209: Note: This routine destroys the array of data passed to it.
210:
211: Inputs: $data: array reference - the contents of @$data must
212: be arrays with x and y data. $data = [ [x1,y1],[x2,y2],...];
213: $binsize: Width of bins to put data in
214: $startbin: the starting bin.
215: $endbin: the ending bin.
216: Returns: Array of Bins. Each bin is a hash reference with the following
217: keys: 'start', 'count', and 'end'.
218:
219: =cut
220:
221: #########################################################
222: #########################################################
223: sub bin_data {
224: my ($data,$binsize,$startbin,$endbin)=@_;
225: return () if (! defined($data) || ref($data) ne 'ARRAY');
226: #
227: # Determine bin geometry
228: my $binstart = $startbin;
229: my $binend = $startbin+$binsize;
230: # put the data into bins
231: my @Bins;
232: my $count=0;
233: my $idx=0;
234: while ($idx < scalar(@$data) && ($endbin-$binend + $binsize)>0) {
235: my $dataset = $data->[$idx++];
236: my ($x,$y) = @{$dataset};
237: while ($x > ($binend-.001)) {
238: # store the old data
239: push (@Bins,{ start => $binstart,
240: count => $count,
241: end => $binend });
242: # start counting again
243: $binstart += $binsize;
244: $binend += $binsize;
245: $count = 0;
246: }
247: $count+=$y;
248: }
249: if ($count > 0) {
250: push (@Bins,{ start => $binstart,
251: count => $count,
252: end => $binend });
253: }
254: return @Bins;
255: }
256:
257: #########################################################
258: #########################################################
259:
260: =pod
261:
262: =item &CreateInterface
263:
264: Inputs: none.
265:
266: Returns: HTML for the correct problems plot interface.
267:
268: =cut
269:
270: #########################################################
271: #########################################################
272: sub CreateInterface {
273: ##
274: ## Environment variable initialization
275: my $Str;
276: $Str .= &Apache::lonhtmlcommon::breadcrumbs
277: (undef,'Correct Problems Plot');
278: $Str .= '<table cellspacing="5">'."\n";
279: $Str .= '<tr>';
280: $Str .= '<td align="center"><b>'.&mt('Sections').'</b></td>';
281: $Str .= '<td align="center"><b>'.&mt('Enrollment Status').'</b></td>';
282: $Str .= '<td align="center"><b>'.&mt('Sequences and Folders').'</b></td>';
283: $Str .= '<td rowspan="2">'.
284: &Apache::lonstathelpers::limit_by_time_form().'</td>';
285: $Str .= '</tr>'."\n";
286: ##
287: ##
288: $Str .= '<tr><td align="center">'."\n";
289: $Str .= &Apache::lonstatistics::SectionSelect('Section','multiple',5);
290: $Str .= '</td>';
291: #
292: $Str .= '<td align="center">';
293: $Str .= &Apache::lonhtmlcommon::StatusOptions(undef,undef,5);
294: $Str .= '</td><td>'."\n";
295: #
296: my $only_seq_with_assessments = sub {
297: my $s=shift;
298: if ($s->{'num_assess'} < 1) {
299: return 0;
300: } else {
301: return 1;
302: }
303: };
304: $Str .= &Apache::lonstatistics::MapSelect('Maps','multiple,all',5,
305: $only_seq_with_assessments);
306: $Str .= '</td>';
307: #
308: ##
309: $Str .= '</tr>'."\n";
310: $Str .= '</table>'."\n";
311: return $Str;
312: }
313:
314: 1;
315:
316: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>