#! /usr/bin/perl # Copyright 2001-2019 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. use DBI; use CGI; use Cwd; use Number::Format qw(:all); my %lex = ('Attendance Profiles' => 'Attendance Profiles', 'Attendance' => 'Attendance', 'Cannot open tex file' => 'Cannot open tex file', 'Enrollment' => 'Enrollment', 'Not Found' => 'Not Found', 'Periods Per Day' => 'Periods Per Day', 'Perfect Attendance' => 'Perfect Attendance', 'View/Download' => 'View/Download', 'View Log File' => 'View Log File', 'Total' => 'Total', 'Absent' => 'Absent', 'Late' => 'Late', 'Excused' => 'Excused', 'Unexcused' => 'Unexcused', 'times' => 'times', 'day(s)' => 'day(s)', 'Main' => 'Main', 'Name' => 'Name', 'Select' => 'Select', 'Withdrawn Students' => 'Withdrawn Students', 'Subject' => 'Subject', 'Sort by' => 'Sort by', 'Select' => 'Select', 'Grade' => 'Grade', 'Homeroom' => 'Homeroom', 'Start Date' => 'Start Date', 'End Date' => 'End Date', 'Show' => 'Show', 'Continue' => 'Continue', 'No Student(s) Found' => 'No Student(s) Found', 'Days' => 'Days', 'Period' => 'Period', 'Error' => 'Error', 'Blank=All' => 'Blank=All', 'Band' => 'Band', 'Summary Records' => 'Summary Records', 'Count' => 'Count', 'Reason' => 'Reason', 'Teacher' => 'Teacher', 'Homeroom' => 'Homeroom', 'Font Size' => 'Font Size', 'Paper Size' => 'Paper Size', 'Letter' => 'Letter', 'Legal' => 'Legal', 'A4' => 'A4', 'Date' => 'Date', 'Not Found' => 'Not Found', 'Description' => 'Description', ); my $grayshade = '0.80'; my $self = "rptattprof.pl"; # Get current dir so know what path for config files. my $configpath; my $teachermode; if ( getcwd() =~ /tcgi/ ){ # we are in tcgi $teachermode = 1; $configpath = '..'; # go back one to get to etc. } else { $configpath = '../..'; # go back two to get to etc. } # main config file eval require "$configpath/etc/admin.conf"; if ( $@ ) { print $lex{Error}. " $@
\n"; die $lex{Error}. " $@\n"; } # load attendance library eval require "$configpath/lib/libattend.pl"; if ( $@ ) { print $lex{Error}. " $@
\n"; die $lex{Error}. " $@\n"; } # load latex filtering (for subject description field, band) eval require "$configpath/lib/liblatex.pl"; if ( $@ ) { print $lex{Error}. " $@
\n"; die $lex{Error}. " $@\n"; } # Do a check for attendance strings if ( not $absentUnexcused or not $lateUnexcused or not $lateString or not $absentString ) { print "

$lex{Error}: $lex{Attendance} $lex{Description} $lex{'Not Found'}

\n"; print "\n"; exit; } # Get current dir so know what CSS to display and shift to teacher settings. if ( getcwd() =~ /tcgi/ ) { # we are in tcgi $css = $tchcss; $homepage = $tchpage; $downloaddir = $tchdownloaddir; $webdownloaddir = $tchwebdownloaddir; } my $maxlines = 28; my $shortname = "attprofile$$"; my $filename = "$shortname.tex"; # Set AM/PM Hash for use converting 2 period day to AM/PM %ampm = ( 1 => 'AM', 2 => 'PM'); my $dsn = "DBI:$dbtype:dbname=$dbase"; my $dbh = DBI->connect($dsn,$user,$password); $dbh->{mysql_enable_utf8} = 1; my $q = new CGI; print $q->header( -charset, $charset ); my %arr = $q->Vars; # Testing throughput #foreach my $key ( sort keys %arr ) { print "K:$key V:$arr{$key}
\n"; } # rounding format my $fmt = new Number::Format(-decimal_fill => '1', -decimal_digits => '2'); my $wdselectflag; if ( $arr{wdselectflag} ) { # We have selected withdrawn students to print. $wdselectflag = 1; delete $arr{wdselectflag}; } my $sortorder = "homeroom, lastname, firstname"; if ( $arr{sortorder} eq 'name' ) { $sortorder = "lastname, firstname"; } elsif ( $arr{sortorder} eq 'grade' ) { $sortorder = "grade, lastname, firstname"; } elsif ( $arr{sortorder} eq 'band' ) { $sortorder = "band, lastname, firstname"; } elsif ( $arr{sortorder} eq 'room' ) { $sortorder = "homeroom, lastname, firstname"; } if ( $arr{sortorder} ) { delete $arr{sortorder}; } my $select; if ( $arr{group} ) { if ( $arr{select} eq $lex{Grade} ) { # Find this grade; my $grp = $dbh->quote( $arr{group} ); $select = "where grade = $grp"; } elsif ( $arr{select} eq $lex{Homeroom} ) { my $grp = $dbh->quote( $arr{group} ); $select = "where homeroom = $grp"; } elsif ( $arr{select} eq $lex{Band} ) { my $grp = $dbh->quote( $arr{group} ); $select = "where band = $grp"; } } # print page header my $title = $lex{'Attendance Profiles'}; print qq{$doctype\n$lex{'Attendance Profiles'}\n}; print qq{\n}; print qq{\n}; print qq{\n}; print qq{\n}; print qq{\n}; print qq{$chartype\n\n}; print qq{[ $lex{Main}\n}; if ( not $teachermode ) { print qq{ | $lex{Attendance}\n}; } print qq{ ]\n}; print qq{

$title

\n}; #foreach my $key (sort keys %arr ) { print "K:$key V:$arr{$key}
\n"; } if ( not $arr{page} ) { showStartPage(); } else { delete $arr{page}; } # Passed variables: start and end dates for reporting period. if ( not $arr{startdate} or not $arr{enddate} ) { print qq{

$lex{'Start Date'} $lex{Or} $lex{'End Date'} $lex{'Not Found'}

\n}; print qq{\n}; exit; } my $startdate = $arr{startdate}; my $enddate = $arr{enddate}; # If checkbox for withdrawn, allow selection of students to print. if ( $arr{withdrawn} ) { selectWithdrawn( $startdate, $enddate ); } # Perfect Attendance Option my $perfectattendance; if ( $arr{perfectattendance} ) { $perfectattendance = 1; delete $arr{perfectattendance}; } # Now create a hash to store student numbers of students to print (if # not selected from withdrawn). if ( not $wdselectflag ) { # we are doing a normal print run of active students my $sth = $dbh->prepare("select studnum from student $select order by $sortorder"); $sth->execute; if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } while ( my $studnum = $sth->fetchrow) { push @students, $studnum; } } else { # we have a selected withdrawn student group to print foreach my $sn (keys %arr) { if ( $sn eq 'papersize' or $sn eq 'fontsize' or $sn eq 'startdate' or $sn eq 'enddate' ) { next; } push @students, $sn; } } if ( @students ) { # We have students to print; setup LaTeX file. open(TEX,">$filename") || die $lex{'Cannot open tex file'}; my ( $papersize, $textwidth, $textheight ); if ( $arr{papersize} eq $lex{Letter} ) { $papersize = 'letterpaper'; $textwidth = $g_letterpaper_textwidth; $textheight = $g_letterpaper_textheight; } elsif ( $arr{papersize} eq $lex{Legal} ) { $papersize = 'legalpaper'; $textwidth = $g_legalpaper_textwidth; $textheight = $g_legalpaper_textheight; } elsif ( $arr{papersize} eq $lex{A4} ) { $papersize = 'a4paper'; $textwidth = $g_a4paper_textwidth; $textheight = $g_a4paper_textheight; } my $fontsize = $arr{fontsize}. 'pt'; print TEX "\\documentclass[ $fontsize,$papersize]{article} \\usepackage{array,colortbl,multicol,inputenc} $a_latex_header \\pagestyle{empty} \\setlength{\\textwidth}{ $textwidth } \\setlength{\\textheight}{ $textheight } \\setlength{\\hoffset}{-25mm} \\setlength{\\voffset}{-36mm} \\setlength{\\extrarowheight}{2pt} \\setlength{\\parindent}{0pt}\n"; print TEX "\\begin{document}\n"; } else { print "

$lex{'No Student(s) Found'}

\n"; print "\n"; exit; } my $sth = $dbh->prepare("select lastname, firstname, grade, homeroom, band from studentall where studnum = ?"); foreach my $studnum ( @students ) { # get rest of student data. $sth->execute($studnum); if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } my ( $lastname, $firstname, $grade, $homeroom, $band ) = $sth->fetchrow; ($band) = latex_filter($band); my $tardytot = 0; my $absenttot = 0; my $tardyu = 0; my $tardye = 0; my $absentu = 0; my $absente = 0; my @enrollblocks = findEnrollmentBlocks( $studnum, $startdate, $enddate, $dbh ); # Setup to fetch Attendance Records my $sth1 = $dbh->prepare("select absdate, reason, period, subjsec from attend where studentid = ? and to_days(absdate) >= to_days('$startdate') and to_days(absdate) <= to_days('$enddate') order by absdate, period "); $sth1->execute( $studnum ); if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } my $absrows = $sth1->rows; # Skip student if not showing perfect attendance # if ( not $perfectattendance and $absrows < 1 ) { next; } # Get teacher and homeroom data (if any), print Enrollment changes. $sth2 = $dbh->prepare("select sal, firstname, lastname from staff as s, staff_multi as sm where sm.userid = s.userid and sm.field_name = 'homeroom' and sm.field_value = ?"); $sth2->execute( $homeroom ); if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } my ($tsal, $tfirstname, $tlastname) = $sth2->fetchrow; my $teacher; if ($tlastname){ $teacher = $lex{Teacher}. ":& $tsal $tfirstname $tlastname\\\\ \n"; } my $hroom; if ( $homeroom ) { $hroom = $lex{Homeroom}. ":& $homeroom\\\\ \n"; } # Start of Printing for this student print TEX "\\center {\\sf\\huge $schoolname $lex{'Attendance Profiles'} } \\\\ \n\\bigskip"; print TEX "{\\Large $firstname $lastname} $withdrawn \\\\ \n \\bigskip\n"; print TEX "\\begin{tabular}{r|l} \n \\hline\n$teacher $hroom\n \\hline\n"; if ( $band ) { print TEX $lex{Band}. "& {\\bf $band} \\\\ \\hline\n"; } print TEX "\\end{tabular}\n\n"; # Enrollment Section if ( @enrollblocks ) { print TEX "\\hrulefill\\\\\n{\\large\\sf $lex{Enrollment} }\\\\ \n\\medskip\n"; print TEX "\\begin{tabular}{|l|l|r|}\\hline\n"; print TEX "\\rowcolor[gray]{0.85}$lex{'Start Date'} & $lex{'End Date'} & $lex{Days}\\\\ \\hline\n"; foreach my $ref ( @enrollblocks ) { my $days = calcDaysOpen( $ref->{start}, $ref->{end}, $dbh); print TEX "$ref->{start} & $ref->{end} & $days \\\\ \\hline\n"; } print TEX "\\end{tabular}\\\\ \n\\medskip\n"; } # Now print the periods absent. # Calculate periods into days my $periods = $g_ppd{$grade}; if ( not $grade ) { print "

$lex{Error}: $lex{Grade} $lex{'Not Found'}"; print " $firstname $lastname

\n"; next; } elsif ( not $periods ) { # We don't have this grade's periods defined. print "$lex{Error}: $lex{'Periods Per Day'} $lex{'Not Found'} - $lex{Grade} $grade"; print "\n
$firstname $lastname\n"; next; } my (%subjectslate, %subjectsabs); # hold subject information, if any... if ( $absrows > 0 ) { # then we have absences; loop through doing calcs. if ( $arr{summary} ) { # print Summary Values only printSummaryRecords( $studnum ); } else { # print it all... print TEX "\\hrulefill\\\\ \n\\setlength{\\premulticols}{5pt}\n"; print TEX "\\setlength{\\postmulticols}{5pt}\n"; print TEX "\\begin{multicols}{2}\n\\raggedright\n"; for ($i=1; $i<=$absrows; $i++) { my ($absdate, $reason, $period, $subjsec) = $sth1->fetchrow; # Convert to AM/PM format if 2 periods per day if ($periods == 2){ # $periods defined on line 226 above $period = $ampm{$period}; # ampm hash defined at top. } # Fixes for crud in reasons for attendance. $reason =~ s/[^A-Za-z\s]//g; # Do the calcs for reasons if ($reason eq $lateUnexcused){ $tardyu++; if ($subjsec) { $subjectslate{$subjsec}++; } # only for unexcused. } elsif ($reason =~ m/$lateString/) { $tardye++; } elsif ($reason eq $absentUnexcused){ $absentu++; if ($subjsec) { $subjectsabs{$subjsec}++; } # only for unexcused. } elsif ($reason =~ m/$absentString/){ $absente++; } else { # unknown reason... print "

$lex{Error}:"; print " $reason - $absdate - ". $lex{Period}. " $period
\n"; print "$firstname $lastname ($studnum)
\n"; } print TEX "$absdate-$period $reason\\\\ \n"; } my $daysabsentu = $fmt->format_number( $absentu/$periods, 2); my $daysabsente = $fmt->format_number( $absente/$periods, 2); my $daysabsenttot = $fmt->format_number( $daysabsente + $daysabsentu, 2); $tardytot = $tardye + $tardyu; print TEX "\\end{multicols}\n\n\\hrulefill\\\\ \n\\bigskip\n"; print TEX "\\begin{tabular}{r|l}\\hline\n"; print TEX $lex{Late}. ' '. $lex{Unexcused}," & $tardyu ",$lex{times},"\\\\\n"; print TEX $lex{Late}. ' '. $lex{Excused}, "& $tardye ", $lex{times}, " \\\\\n"; print TEX $lex{Total}. ' '. $lex{Late}, "& $tardytot ", $lex{times}, "\\\\\n"; print TEX "\\hline\n", $lex{Absent}. ' '. $lex{Unexcused}, "& $daysabsentu "; print TEX $lex{'day(s)'}, "\\\\\n"; print TEX $lex{Absent}. ' '. $lex{Excused}, "& $daysabsente ", $lex{'day(s)'}, "\\\\\n"; print TEX $lex{Total}. ' ', $lex{Absent}, "& $daysabsenttot ", $lex{'day(s)'}, "\\\\\n"; print TEX "\\hline\n\\end{tabular}\n"; } # end of Complete or Summary Records # Subject Attendance printSubjectAttendance($studnum, $arr{startdate}, $arr{enddate} ); print TEX "\\newpage\n\n"; } else { # Perfect Attendance print TEX "\\bigskip {\\huge $lex{'Perfect Attendance'}! } \\newpage \n\n"; } } # End of Student Loop print TEX "\\end{document}"; close TEX; system("$pdflatex $filename >pdflog$$.txt"); system("mv $shortname.pdf $downloaddir"); system("mv pdflog$$.txt $downloaddir"); system("rm $shortname.*"); print qq{

\n}; print qq{$lex{'View/Download'} $lex{'Attendance Profiles'}

\n}; print qq{[ }; if ( not $teachermode ) { print qq{$lex{Attendance} |\n}; } print qq{$lex{'View Log File'} ]\n}; print qq{\n}; #---------------------- sub printSummaryRecords { #---------------------- my $studnum = shift; # must be passed student records. my $sth = $dbh->prepare("select distinct reason, period, count(period) from attend where studentid = ? and to_days(absdate) >= to_days('$startdate') and to_days(absdate) <= to_days('$enddate') group by reason, period order by period, reason"); if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; } $sth->execute( $studnum ); if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; } print TEX "\\begin{tabular}{r|l|l}\\hline\n"; print TEX "\\rowcolor[gray]{$grayshade} $lex{Reason} & $lex{Period} & $lex{Count}"; print TEX "\\\\ \\hline\n"; while ( my ( $reason, $period, $count ) = $sth->fetchrow ) { print TEX "$reason & $period & $count \\\\ \\hline\n"; } print TEX "\\end{tabular}\n"; } #----------------------- sub printCompleteRecords { #----------------------- my $studnum = shift; # Setup to fetch Attendance Records my $sth1 = $dbh->prepare("select absdate, reason, period, subjsec from attend where studentid = ? and to_days(absdate) >= to_days('$startdate') and to_days(absdate) <= to_days('$enddate') order by absdate, period "); $sth1->execute( $studnum ); if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } my $absrows = $sth1->rows; my (%subjectslate, %subjectsabs); # hold subject information, if any... if ( $absrows > 0 ) { # then we have absences; loop through doing calcs. print TEX "\\hrulefill\\\\ \n\\setlength{\\premulticols}{5pt}\n"; print TEX "\\setlength{\\postmulticols}{5pt}\n"; print TEX "\\begin{multicols}{2}\n\\raggedright\n"; for ($i=1; $i<=$absrows; $i++) { my ($absdate, $reason, $period, $subjsec) = $sth1->fetchrow; # Convert to AM/PM format if 2 periods per day if ($periods == 2){ # $periods defined on line 226 above $period = $ampm{$period}; # ampm hash defined at top. } # Fixes for crud in reasons for attendance. $reason =~ s/[^A-Za-z\s]//g; # Do the calcs for reasons if ($reason eq $lateUnexcused){ $tardyu++; if ($subjsec) { $subjectslate{$subjsec}++; } # only for unexcused. } elsif ($reason =~ m/$lateString/) { $tardye++; } elsif ($reason eq $absentUnexcused){ $absentu++; if ($subjsec) { $subjectsabs{$subjsec}++; } # only for unexcused. } elsif ($reason =~ m/$absentString/){ $absente++; } else { # unknown reason... print "". $lex{'Unknown reason'}; print ": $reason - $absdate - ". $lex{Period}. " $period
\n"; print "$firstname $lastname ($studnum)
\n"; } print TEX "$absdate-$period $reason\\\\ \n"; } my $daysabsentu = $fmt->format_number( $absentu/$periods, 2); my $daysabsente = $fmt->format_number( $absente/$periods, 2); my $daysabsenttot = $fmt->format_number( $daysabsente + $daysabsentu, 2); $tardytot = $tardye + $tardyu; print TEX "\\end{multicols}\n\n\\hrulefill\\\\ \n\\bigskip\n"; print TEX "\\begin{tabular}{r|l}\\hline\n"; print TEX $lex{Late}. ' '. $lex{Unexcused}," & $tardyu ",$lex{times},"\\\\\n"; print TEX $lex{Late}. ' '. $lex{Excused}, "& $tardye ", $lex{times}, " \\\\\n"; print TEX $lex{Total}. ' '. $lex{Late}, "& $tardytot ", $lex{times}, "\\\\\n"; print TEX "\\hline\n", $lex{Absent}. ' '. $lex{Unexcused}, "& $daysabsentu "; print TEX $lex{'day(s)'}, "\\\\\n"; print TEX $lex{Absent}. ' '. $lex{Excused}, "& $daysabsente ", $lex{'day(s)'}, "\\\\\n"; print TEX $lex{Total}. ' ', $lex{Absent}, "& $daysabsenttot ", $lex{'day(s)'}, "\\\\\n"; print TEX "\\hline\n\\end{tabular}\n"; print TEX "\\newpage\n\n"; } else { # Perfect Attendance print TEX "\\bigskip {\\huge ", $lex{'Perfect Attendance'}, "! } \\newpage \n\n"; } } # end of printCompleteRecords #------------------------- sub printSubjectAttendance { #------------------------- my ( $studnum, $startdate, $enddate ) = @_; # Find subjects where student is absent... my $sth = $dbh->prepare("select distinct subjsec from attend where studentid = ? and to_days(absdate) >= to_days('$startdate') and to_days(absdate) <= to_days('$enddate') and subjsec != '' and subjsec is not null and subjsec != 'NULL'"); $sth->execute( $studnum ); if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } my $subjrows = $sth->rows; if ( $subjrows < 1 ) { return; } # Setup for printing subject lates/absences print TEX "\n\\bigskip\n\n"; print TEX "\\begin{tabular}{|l|c|c|}\\hline\n"; print TEX "\\rowcolor[gray]{$grayshade}",$lex{Subject}; print TEX '&',$lex{Absent},'&',$lex{Late}," \\\\ \\hline\n"; my $sth1 = $dbh->prepare("select description from subject where subjsec = ?"); if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; } my $sth2 = $dbh->prepare("select count(*)from attend where studentid = ? and subjsec = ? and reason = ? and to_days(absdate) >= to_days('$startdate') and to_days(absdate) <= to_days('$enddate')"); if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; } while ( my $subjsec = $sth->fetchrow ) { # loop through all subjects $sth1->execute( $subjsec ); if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; } my $desc = $sth1->fetchrow; ( $desc ) = latex_filter( $desc ); # watch for &, etc # Lates $sth2->execute($studnum, $subjsec, $lateUnexcused ); if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; } my $lates = $sth2->fetchrow; # Absences $sth2->execute($studnum, $subjsec, $absentUnexcused ); if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; } my $absents = $sth2->fetchrow; print TEX "$desc ($subjsec) & $absents "; print TEX "& $lates \\\\ \\hline\n"; } print TEX "\\end{tabular}\n"; } # end of printSubjectAttendance #------------------ sub selectWithdrawn { # select withdrawn students to print. #------------------ #foreach my $key ( sort keys %arr ) { print "K:$key V:$arr{$key}
\n"; } my ($startdate, $enddate) = @_; # Get count of withdrawn students in studentwd table my $sth = $dbh->prepare("select count(*) from studentwd"); $sth->execute; if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } my $studcount = $sth->fetchrow; print qq{

$studcount $lex{'Withdrawn Students'}

\n}; print qq{
}; print qq{\n}; print qq{\n}; print qq{\n}; print qq{\n}; print qq{\n}; print qq{\n}; print qq{\n}; print qq{\n}; print qq{\n}; my $sth = $dbh->prepare("select studid,lastname, firstname, studnum from studentwd order by lastname, firstname"); $sth->execute; if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } for (1..$studcount) { my ($studid, $lastname, $firstname, $studnum) = $sth->fetchrow; print qq{\n}; } print qq{\n}; print qq{
$lex{Name}$lex{Select}
}; print qq{
$lastname, $firstname ($studnum)}; print qq{
}; print qq{
\n}; exit; } #----------------- sub showStartPage { #----------------- # Get default papersize my $papersize = $defaultpapersize; $papersize =~ s/paper//; # strip off the 'paper' ending; $papersize = ucfirst( $papersize ); # print sortorder and selection input form. print qq{
\n}; print qq{\n}; print qq{\n}; print qq{\n}; print qq{\n}; # Blank Row print qq{\n}; # Dates print qq{\n}; print qq{\n}; print qq{}; print qq{\n}; # print qq{\n}; =head # Terms print qq{\n}; print qq{\n}; print qq{}; print qq{\n}; =cut # Blank Row print qq{\n}; # Paper Size print qq{\n}; print qq{\n}; # Font Size print qq{\n}; print qq{\n}; # Summary Only print qq{\n}; # Withdrawn print qq{\n}; # Perfect Attendance print qq{\n}; print qq{\n}; print qq{
$lex{'Sort by'}\n}; print qq{
$lex{Select}\n}; print qq{\n}; print qq{ $lex{'Blank=All'}

$lex{'Start Date'}\n}; print qq{\n}; print qq{
$lex{'End Date'}\n}; print qq{
$lex{Or}
$lex{'Start Term'}
$lex{'End Term'}

$lex{'Paper Size'}
$lex{'Font Size'}
$lex{Show} $lex{'Summary Records'}\n}; print qq{
$lex{Show} $lex{'Withdrawn Students'}\n}; print qq{
$lex{Show} $lex{'Perfect Attendance'}\n}; print qq{
}; print qq{
\n}; print qq{\n}; print qq{\n}; exit; }