#! /usr/bin/perl # Copyright 2001-2022 Leslie Richardson # This file is part of Open Admin for Schools. # Open Admin for Schools is free software; you can redistribute it # and/or modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. my %lex = ('Main' => 'Main', 'Continue' => 'Continue', 'Grade' => 'Grade', 'Error' => 'Error', 'Common Math Assessment' => 'Common Math Assessment', 'Report' => 'Report', 'Name' => 'Name', 'Tests' => 'Tests', 'No Students Found' => 'No Students Found', 'Last,First/Last/Initials/Studnum' => 'Last,First/Last/Initials/Studnum', 'Search' => 'Search', 'Show Withdrawn' => 'Show Withdrawn', 'Attendance' => 'Attendance', 'View' => 'View', ); my $self = 'cmaRpt9.pl'; # individual student report. use DBI; use CGI; use Cwd; use Number::Format qw(:all); use Time::JulianDay; my @strands = qw(P N SS SP); my %strandnames = ('P' => 'Patterns and Relations', 'N' => 'Numbers and Operations', 'SS' => 'Shape and Space', 'SP' => 'Stats and Prob' ); =head my %colormap = ( 1 => '#822', 2 => '#BB1', 3 => '#228', 4 => '#282' ); =cut my %colormap = ( 1 => 'r', 2 => 'y', 3 => 'b', 4 => 'g' ); my $configpath = '../../..'; my $linkpath = '../../attendance'; # for links to rptattstud1.pl if ( getcwd() =~ /tcgi/ ){ # we are in tcgi $configpath = '../..'; $linkpath = '..'; } eval require "$configpath/etc/admin.conf"; if ( $@ ) { print $lex{Error}. " $@
\n"; die $lex{Error}. " $@\n"; } my $q = new CGI; print $q->header( -charset, $charset ); my %arr = $q->Vars; my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $iddst) = localtime(time); $year = $year + 1900; $wday++; $mon++; my $currsdate = "$year-$mon-$mday"; my $currdate = "$dow[$wday], $month[$mon] $mday, $year"; my $currjd = julian_day( split('-', $currsdate) ); # setup values for links to student attendance report (studattrpt1.pl) my ($sy,$ey) = split('-', $schoolyear); # global config my $endmonth = "$year-$mon"; # based on current month. my $startmonth = "$sy-08"; my $dsn = "DBI:$dbtype:dbname=$dbase"; my $dbh = DBI->connect($dsn,$user,$password); $dbh->{mysql_enable_utf8} = 1; # Get current dir so know what CSS to display; if ( getcwd() =~ /tcgi/ ){ # we are in tcgi $css = $tchcss; $homepage = $tchpage; } my $title = "$lex{Report} 9 - Student Report - $schoolname"; print qq{$doctype\n$lex{'Common Math Assessment'} $title\n}; print qq{\n}; print qq{$chartype\n\n}; print qq{\n}; print qq{
[ $lex{Main} ] $lex{'Common Math Assessment'}
\n}; print qq{

$title

\n}; if ( not $arr{page} ) { showStartPage(); } elsif ( $arr{page} == 1 ) { delete $arr{page}; selectStudent(); } elsif ( $arr{page} == 2 ) { delete $arr{page}; showReport(); } #---------------- sub showStartPage { #---------------- print qq{
\n}; print qq{\n}; print qq{\n}; print qq{\n}; print qq{\n}; # Withdrawn print qq{\n}; print qq{
}; print qq{
$lex{'Last,First/Last/Initials/Studnum'}
$lex{'Show Withdrawn'}}; print qq{
\n}; print qq{\n}; exit; } # end of showStartPage #---------------- sub selectStudent { #---------------- my $studenttable = 'student'; if ( $arr{showwithdrawn} ) { $studenttable = 'studentall'; } my $student = $arr{student}; # Setup the Search if ($student =~ /\d+/) { # we have a student number $studnum = $student; $sth = $dbh->prepare("select lastname, firstname, studnum, grade from $studenttable where studnum = ?"); $sth->execute( $studnum ); } else { # we have words hopefully with a comma ($lastname,$firstname) = split /\,/, $student; $firstname =~ s/^\s*//; $lastname =~ s/^\s*//; if ($lastname and $firstname){ # both entered. $sth = $dbh->prepare("select lastname, firstname, studnum, grade from $studenttable where lastname = ? and firstname = ? order by lastname, firstname"); $sth->execute( $lastname, $firstname ); } elsif ( $lastname and not $firstname ){ # only lastname (no comma) if (length($lastname) == 2){ # search by initials: fi, li. $fi = substr($lastname,0,1); $li = substr($lastname,1,1); $fi .= '%'; $li .= '%'; $sth = $dbh->prepare("select lastname,firstname, studnum, grade from $studenttable where lastname $sql{like} ? and firstname $sql{like} ? order by lastname, firstname"); $sth->execute( $li, $fi ); } else { $sth = $dbh->prepare("select lastname, firstname, studnum, grade from $studenttable where lastname = ? order by lastname, firstname"); $sth->execute( $lastname ); } } else { $sth = $dbh->prepare("select lastname, firstname, studnum, grade from $studenttable order by lastname, firstname"); } } # Last Else if ( $DBI::errstr ) { print $lex{Error}. ": $DBI::errstr"; die $DBI::errstr; } my $first = 1; print qq{\n}; if ( $arr{showwithdrawn} ) { print qq{\n}; } print qq{}; print qq{\n}; my $sth1 = $dbh->prepare("select count(*) from mathca_scores where studnum = ?"); my $sth2 = $dbh->prepare("select count(*) from studentwd where studnum = ?"); # Loop through each found student. while ( my ( $lastname, $firstname,$studnum, $grade ) = $sth->fetchrow ) { # Math Scores? $sth1->execute( $studnum ); if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; } my $testcount = $sth1->fetchrow; # Withdrawn? $sth2->execute( $studnum ); if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; } my $wdcount = $sth2->fetchrow; my $wd; if ( $wdcount ) { $wd = qq{WD\n}; } print qq{}; # Attendance/Enrollment Link print qq{\n}; # Tests print qq{\n}; $first = 0; } if ( $first ) { # no students print qq{\n}; print qq{
WD = Withdrawn Student
$lex{Name}$lex{Grade}$lex{Tests}$lex{Attendance}
$wd $lastname, $firstname}; print qq{ ($studnum)$grade
\n}; print qq{\n}; print qq{\n}; print qq{\n}; print qq{\n}; print qq{
$testcount\n}; if ( $testcount ) { print qq{
\n}; print qq{\n}; print qq{\n}; print qq{\n}; print qq{
\n}; } print qq{
$lex{'No Students Found'}

\n}; showStartPage(); } else { print qq{\n}; } exit; } # end of selectStudent #------------- sub showReport { #------------- # foreach my $key ( sort keys %arr ) { print "K:$key V:$arr{$key}
\n"; } my $studenttable = 'studentall'; # if ( $arr{showwithdrawn} ) { # $studenttable = 'studentwd'; # } =head # Figure out the number of days in the school year and also where # the current date fits into that. my %closed; # $closed{julian date} = fraction of day closed. my $sth = $dbh->prepare("select date, dayfraction from dates"); $sth->execute; if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } while ( my ($d, $frac) = $sth->fetchrow ) { if ( not $frac ) { next; } # just in case my $jd = julian_day( split('-', $d) ); $closed{$jd} = $frac; } my $startjd = julian_day( split('-', $schoolstart) ); my $endjd = julian_day( split('-', $schoolend) ); # print "School Start: $schoolstart School End:$schoolend
\n"; # loop through the school year; count # number of days until end and also until the current date. my ($totaldays, $partdays ); for my $jd ( $startjd..$endjd ) { # run through the school year my $dow = day_of_week( $jd ); if ( $dow == 6 or $dow == 1 ) { next; } if ( $closed{$jd} ) { my $open = 1 - $closed{$jd}; $totaldays += $open; if ( $jd <= $currjd ) { $partdays += $open; } } else { $totaldays++; if ( $jd <= $currjd ) { $partdays++; } } } # print "

Total:$totaldays Part:$partdays
\n"; my $percentdone = format_number( $partdays * 100 / $totaldays, 1,1 ); print qq{

Percent of School Year Complete: $percentdone%

\n}; print qq{

$classname – $currdate

\n}; =cut # Get Student Name my $sth = $dbh->prepare("select lastname, firstname from studentall where studnum = ?"); $sth->execute( $arr{studnum} ); if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } my ($lastname, $firstname) = $sth->fetchrow; # Build Outcomes selection my %outcomes; # lists outcomes. my %odesc; # outcomes description. my $sth = $dbh->prepare("select * from mathca_outcomes"); $sth->execute; if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } while ( my $ref = $sth->fetchrow_hashref ) { my %r = %$ref; my $oid = $r{oid}; my $grade = $r{grade}; my ($cat, $seq) = split(/\./, $oid); $cat =~ s/$grade$//; # remove grade $outcomes{$grade}{$cat}{$seq} = $oid; $odesc{$oid} = $r{odesc}; } # Done building data structure. my $sth1 = $dbh->prepare("select tgrade from mathca_scores where studnum = ? and schoolyear = ?"); # Get the student's school years my $sth = $dbh->prepare("select distinct schoolyear from mathca_scores where studnum = ? order by schoolyear"); $sth->execute( $arr{studnum} ); if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } while ( my $year = $sth->fetchrow ) { # Get the grade for this school year (assume only 1) $sth1->execute( $arr{studnum}, $year ); if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } my $grade = $sth1->fetchrow; # Now build a structure for this grade my %strandcount; # $catcount{category} = number in this category. foreach my $cat ( sort keys %{ $outcomes{$grade} } ) { foreach my $seq ( sort keys %{ $outcomes{$grade}{$cat} } ) { if ( $seq > $strandcount{$cat} ) { $strandcount{$cat} = $seq; } } } my $totaloutcomes; foreach my $key ( keys %strandcount ) { $totaloutcomes += $strandcount{$key}; } my %data; # holds all data $data{studnum}{outcome}{prepost} = score; my %pass; # $pass{studnum} = count of passes ( >= 3) my %strandpass; my %tdates; # store test dates for outcomes and pre/post $tdates{outcome}{pretest/posttest}; # Get Student Data my $sth1 = $dbh->prepare("select prepost, outcome, score, tdate from mathca_scores where schoolyear = ? and studnum = ? order by tdate"); # Get this student's data $sth1->execute( $year, $arr{studnum} ); if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } while ( my ($prepost, $outcome, $score, $tdate) = $sth1->fetchrow ) { if ( $prepost eq 'posttest' ) { # only do posttests for data. push @{ $data{$studnum}{$outcome} }, $score; if ( $score >= 3 ) { $pass{$studnum}{'pass'}++; } $pass{$studnum}{'count'}++; } } # Start Printing Data print qq{
Grade $grade
\n}; print qq{\n}; print qq{\n}; # header section. print qq{}; print qq{}; foreach my $strand ( @strands ) { if ( $strandcount{$strand} ) { # print IF we have that strand print qq{\n}; } } print qq{\n}; # Second Line: Desc; print qq{}; foreach my $strand ( @strands ) { if ( $strandcount{$strand} ) { # print IF we have that strand foreach my $seq ( sort keys %{ $outcomes{$grade}{$strand} } ) { my $outcome = $outcomes{$grade}{$strand}{$seq}; print qq{}; } } } print qq{\n}; print qq{\n}; # %pass my ($pass, $mst, $outcomecount); if ( $pass{$studnum}{count} ) { $pass = format_number( $pass{$studnum}{pass} * 100 / $pass{$studnum}{count}, 0, 0); #if ( $pass ) { $pass .= '%'; } } # now figure out how many outcomes have scores foreach my $outcome ( keys %{ $data{$studnum} } ) { if ( ${ $data{$studnum}{$outcome} }[0] ) { $outcomecount++; } } if ( $pass{$studnum}{count} and $totaloutcomes ) { $mst = format_number( $pass{$studnum}{pass} / $pass{$studnum}{count} * $outcomecount / $totaloutcomes, 2, 2); } print qq{}; foreach my $strand ( @strands ) { if ( not $strandcount{$strand} ) { next; } # skip any strands not covered in this grade. foreach my $seq ( sort keys %{ $outcomes{$grade}{$strand} } ) { my $outcome = $outcomes{$grade}{$strand}{$seq}; my @scores = @{ $data{$studnum}{$outcome} }; my $displayval; my $first = 1; my $max; foreach my $score ( @scores ) { if ( not $first ) { $displayval .= qq{/}; } else { $first = 0; } $displayval .= $score; if ( $score > $max ) { $max = $score; } } my $class = $colormap{$max}; print qq{}; } } # end of this strand print qq{
Hover on Column Titles to see text descriptions
StudentPass
Per
MST}; print qq{$strandnames{$strand} ($strandcount{$strand})
$outcome
$lastname, $firstname$pass$mst$displayval
\n}; } # end of this year =head # now totals for this student my ($pretotalavg, $posttotalavg); if ( $pretotalcount ) { $pretotalavg = format_number( $pretotalsum / $pretotalcount, 2); } if ( $posttotalcount ) { $posttotalavg = format_number( $posttotalsum / $posttotalcount, 2); } my $diff = format_number( $posttotalavg - $pretotalavg, 2); print qq{$posttotalcount$pretotalavg}; print qq{$posttotalavg$diff\n}; # Passes; my $passpercent; if ( $pass{$studnum}{'count'} and $pass{$studnum}{'pass'} ) { $passpercent = format_number( $pass{$studnum}{'pass'} * 100 / $pass{$studnum}{'count'}, 2); } if ( $passpercent ) { print qq{$passpercent% ($pass{$studnum}{'pass'}/$pass{$studnum}{'count'})\n}; } elsif ( $pass{$studnum}{'count'} ) { # have count, but no passes print qq{0% (0/$pass{$studnum}{'count'})\n}; } else { # print blank. print qq{\n}; } =cut # print qq{\n}; # next grade. print qq{
}; print qq{All scores are posttest scores. Pretest scores are }; print qq{not shown on this report
\n}; print qq{
}; print qq{If more than one test is given to a student on the }; print qq{same outcome, these scores are separated by slashes
\n}; print qq{\n}; exit; } # end of showReport