File:
[LON-CAPA] /
loncom /
interface /
statistics /
loncorrectproblemplot.pm
Revision
1.1:
download - view:
text,
annotated -
select for diffs
Mon Feb 2 21:45:12 2004 UTC (20 years, 6 months ago) by
matthew
Branches:
MAIN
CVS tags:
HEAD
Added: loncorrectproblems plot: produce a histogram of the number of students
having N problems correct.
loncoursedata: Modified &get_student_scores to accept enrollment status and
section as inputs. No longer works at a student level. At worst the
SQL queries generated are cleaner, at best the queries run faster.
lonstatistics: Modified to export the selected enrollment status.
Added the correct problems plot to the statistics menu.
1: # The LearningOnline Network with CAPA
2: #
3: # $Id: loncorrectproblemplot.pm,v 1.1 2004/02/02 21:45:12 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: use HTML::Entities();
39: use Time::Local();
40: use Spreadsheet::WriteExcel();
41:
42: my $plotcolors = ['#33ff00',
43: '#ff33cc', '#990000', '#aaaa66', '#663399', '#ff9933',
44: '#66ccff', '#ff9999', '#cccc33', '#660000', '#33cc66',
45: ];
46:
47: my @SubmitButtons = (
48: { name => 'CreatePlot',
49: text => 'Create Plot' },
50: { name => 'ClearCache',
51: text => 'Clear Caches' },
52: { name => 'updatecaches',
53: text => 'Update Student Data' },
54: );
55:
56: sub BuildCorrectProblemsPage {
57: my ($r,$c)=@_;
58: #
59: my %Saveable_Parameters = ('Status' => 'scalar',
60: 'Section' => 'array');
61: &Apache::loncommon::store_course_settings('correct_problems_plot',
62: \%Saveable_Parameters);
63: &Apache::loncommon::restore_course_settings('correct_problems_plot',
64: \%Saveable_Parameters);
65: #
66: &Apache::lonstatistics::PrepareClasslist();
67: #
68: $r->print('<h2>'.&mt('Number of Correct Problems Plot').'</h2>');
69: $r->print(&CreateInterface());
70: #
71: my @Students = @Apache::lonstatistics::Students;
72: #
73: if (@Students < 1) {
74: $r->print('<h2>'.
75: &mt('There are no students in the sections selected').
76: '</h2>');
77: }
78: #
79: &Apache::loncoursedata::clear_internal_caches();
80: if (exists($ENV{'form.ClearCache'}) ||
81: exists($ENV{'form.updatecaches'}) ||
82: (exists($ENV{'form.firstanalysis'}) &&
83: $ENV{'form.firstanalysis'} ne 'no')) {
84: &Apache::lonstatistics::Gather_Full_Student_Data($r);
85: }
86: if (! exists($ENV{'form.firstanalysis'})) {
87: $r->print('<input type="hidden" name="firstanalysis" value="yes" />');
88: } else {
89: $r->print('<input type="hidden" name="firstanalysis" value="no" />');
90: }
91: foreach my $button (@SubmitButtons) {
92: $r->print('<input type="submit" name="'.$button->{'name'}.'" '.
93: 'value="'.&mt($button->{'text'}).'" />');
94: $r->print(' 'x5);
95: }
96: $r->rflush();
97: #
98: # Determine which problem symbs we are to sum over
99: if (exists($ENV{'form.CreatePlot'})) {
100: my @ProblemSymbs;
101: if ($Apache::lonstatistics::SelectedMaps[0] ne 'all') {
102: foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess()){
103: foreach my $res (@{$seq->{'contents'}}) {
104: next if ($res->{'type'} ne 'assessment');
105: foreach my $part (@{$res->{'parts'}}) {
106: push(@ProblemSymbs,{symb=>$res->{'symb'},
107: part=>$part});
108: }
109: }
110: }
111: }
112: my $score_data = &Apache::loncoursedata::get_student_scores
113: (\@Apache::lonstatistics::SelectedSections,
114: \@ProblemSymbs,
115: $Apache::lonstatistics::enrollment_status);
116: $r->print(&AnalyzeScoreData($score_data));
117: }
118: return;
119: }
120:
121: #########################################################
122: #########################################################
123:
124: =pod
125:
126: =item
127:
128: =cut
129:
130: #########################################################
131: #########################################################
132: sub AnalyzeScoreData {
133: my ($score_data) = @_;
134: #
135: # Basic check first
136: if (@$score_data < 1) {
137: return '<h2>There is no data to plot</h2>';
138: }
139: #
140: # Determine which bins to use
141: my $lowest = $score_data->[0]->[0];
142: $lowest = 0;
143: my $highest = $score_data->[-1]->[0];
144: my $binsize = 1;
145: if ($highest > 50) { $binsize = 2; }
146: if ($highest > 100) { $binsize = 5; }
147: if ($highest > 200) { $binsize = 10; }
148: if ($highest > 500) { $binsize = 20; }
149: if ($highest > 1000) { $binsize = 50; }
150: if ($highest > 2000) { $binsize = 100; }
151: #
152: # Get the data into the bins (destroying $score_data in the process)
153: my @Bins = &bin_data($score_data,$binsize,$lowest,$highest);
154: my @Xdata; my @Ydata; my $max;
155: my $Str = '<table border="1">'."\n".'<tr><th>Range</th><th>Count</th></tr>'."\n";
156: while (my $bin = shift(@Bins)) {
157: push (@Xdata,$bin->{'start'});
158: push (@Ydata,$bin->{'count'});
159: if ($bin->{'count'} > $max) {
160: $max = $bin->{'count'};
161: }
162: $Str.= '<tr><td>'.$bin->{'start'}.' - '.$bin->{'end'}.'</td>'.
163: '<td>'.$bin->{'count'}.'</td></tr>'."\n";
164: }
165: my $title = '';
166: $Str .= "</table><br />\n";
167: $Str = "<br />\n".&Apache::loncommon::DrawBarGraph($title,
168: 'Num Correct Problems',
169: 'Number of students',
170: $max,
171: undef, # colors
172: \@Xdata,
173: \@Ydata).
174: "\n<br />\n".$Str;
175: return $Str;
176: }
177:
178:
179: #########################################################
180: #########################################################
181:
182: =pod
183:
184: =item &bin_data($data,$binsize,$startbin,$endbin)
185:
186: Note: This routine destroys the array of data passed to it.
187:
188: Inputs: $data: array reference - the contents of @$data must
189: be arrays with x and y data. $data = [ [x1,y1],[x2,y2],...];
190: $binsize: Width of bins to put data in
191: $startbin: the starting bin.
192: $endbin: the ending bin.
193: Returns: Array of Bins. Each bin is a hash reference with the following
194: keys: 'start', 'count', and 'end'.
195:
196: =cut
197:
198: #########################################################
199: #########################################################
200: sub bin_data {
201: my ($data,$binsize,$startbin,$endbin)=@_;
202: return () if (! defined($data) || ref($data) ne 'ARRAY');
203: #
204: # Determine bin geometry
205: my $binstart = $startbin;
206: my $binend = $startbin+$binsize;
207: # put the data into bins
208: my @Bins;
209: my $count=0;
210: my $idx=0;
211: while ($idx < scalar(@$data) && ($binend-$endbin)<$binsize) {
212: my $dataset = $data->[$idx++];
213: my ($x,$y) = @{$dataset};
214: while ($x > $binend) {
215: # store the old data
216: push (@Bins,{ start => $binstart,
217: count => $count,
218: end => $binend });
219: # start counting again
220: $binstart += $binsize;
221: $binend += $binsize;
222: $count = 0;
223: }
224: $count+=$y;
225: }
226: return @Bins;
227: }
228:
229: #########################################################
230: #########################################################
231:
232: =pod
233:
234: =item
235:
236: =cut
237:
238: #########################################################
239: #########################################################
240: sub CreateInterface {
241: ##
242: ## Environment variable initialization
243: my $Str;
244: $Str .= '<table cellspacing="5">'."\n";
245: $Str .= '<tr>';
246: $Str .= '<td align="center"><b>'.&mt('Sections').'</b></td>';
247: $Str .= '<td align="center"><b>'.&mt('Enrollment Status').'</b></td>';
248: $Str .= '<td align="center"><b>'.&mt('Sequences and Folders').'</b></td>';
249: $Str .= '</tr>'."\n";
250: ##
251: ##
252: $Str .= '<tr><td align="center">'."\n";
253: $Str .= &Apache::lonstatistics::SectionSelect('Section','multiple',5);
254: $Str .= '</td>';
255: #
256: $Str .= '<td align="center">';
257: $Str .= &Apache::lonhtmlcommon::StatusOptions(undef,undef,5);
258: $Str .= '</td><td>'."\n";
259: #
260: my $only_seq_with_assessments = sub {
261: my $s=shift;
262: if ($s->{'num_assess'} < 1) {
263: return 0;
264: } else {
265: return 1;
266: }
267: };
268: $Str .= &Apache::lonstatistics::MapSelect('Maps','multiple,all',5,
269: $only_seq_with_assessments);
270: $Str .= '</td><td>'."\n";
271: ##
272: $Str .= '</tr>'."\n";
273: $Str .= '</table>'."\n";
274: return $Str;
275: }
276:
277: 1;
278:
279: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>