Cl2ww
Jump to navigation
Jump to search
#!/usr/bin/perl -w use strict; # # cl2ww [-c|-s] [crs-sxn [crs-sxn.. ]] # # process classlist files for class-sections indicated, creating # corresponding webwork userlist files, classnum.lst # -s : assume the webwork roster has section & recitation # = section num # (e.g., 115-103 has sxn=103, rct=103) # -c : assume the webwork roster has the section # = course # and # recitation # = section # (e.g., 115-103 has sxn=115, rct=103) # otherwise, assume that section # = section # rounded down, recitation # # = section number (e.g., 215-021 has sxn=020, rct=021) # # by Gavin LaRose # version 1.34 # changes: 1.34: add -s flag # 1.33: add -c flag # 1.32: correct handling of csv files generated by python # 1.31: bugfix; chomp newlines from file names, avoid double # counting students in 215, 216 if -all is used, make # instructors show up with section number and 000 for # recitation # 1.3 : update to get rid of passwords, add instructor # 1.2 : revised recitation number support # 1.1 : added support for recitation number # 5 jan 2010 # # (c)2013 Gavin LaRose/Regents of the University of Michigan # # This program 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 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # #------------------------------------------------------------------------------ # variables # my $dataDir = '/home/glarose/IFS-Home/LSA-Files/Private/classlists/data'; my @instrFiles = ('instr_pw.csv', 'instr.csv'); select STDERR; $|=1; select STDOUT; $|=1; #------------------------------------------------------------------------------ # main # my $cflag = 0; if ( @ARGV && $ARGV[0] eq '-c' ) { $cflag = 1; shift( @ARGV ); } if ( @ARGV && $ARGV[0] eq '-s' ) { $cflag = 2; shift( @ARGV ); } if ( ! @ARGV ) { my $fname = "none"; print "course-section to process (e.g., 115-all, 216-102)? "; chomp( $fname = <STDIN> ); push( @ARGV, $fname ); } # we make $classes{crs-num} = [ list of webwork roster lines ] my %classes = (); # webwork lines are # studentID, lName, fmName, status, comment, section, recitation, \ # email, loginName foreach my $course ( @ARGV ) { my @fileList = (); my ( $crs, $sxn ) = ( $course =~ /(\d+)-((\d+)|(all))/ ); die("* error: course identifier $course is not in the form CRS-SXN\n") if ( ! defined($crs) || ! defined($sxn) || ! $crs || ! $sxn ); if ( $sxn eq 'all' ) { if ( $crs =~ /^21[56]/ ) { @fileList = `/bin/ls ${crs}_??[1-4].csv 2> /dev/null`; @fileList = `/bin/ls $dataDir/${crs}_??[1-4].csv 2> /dev/null` if ( ! @fileList ); } else { @fileList = `/bin/ls ${crs}_*.csv 2> /dev/null`; @fileList = `/bin/ls $dataDir/${crs}_*.csv 2> /dev/null` if ( ! @fileList ); } } else { push(@fileList, "${crs}_${sxn}.csv"); } for ( my $i=0; $i<@fileList; $i++ ) { chomp($fileList[$i]); if ( ! -f $fileList[$i] && ! -f "$dataDir/$fileList[$i]" ) { @fileList = (); last; } elsif ( ! -f $fileList[$i] ) { $fileList[$i] = "$dataDir/$fileList[$i]"; } } die("* error: missing class roster file(s)\n") if ( ! @fileList ); print "reading course file: "; foreach my $f ( @fileList ) { my ( $c, $s ) = ($f =~ /(\d{3})_(\d{3})/); print "$c-$s.. "; open( IF, $f ) or die("* error: cannot open $f for reading\n"); while ( <IF> ) { # first line is a header; skip it if ( /^[0-9]/ ) { s/\s*$//; s/\"//g; my @entry = csvSplit( $_ ); my $cnum = $entry[0] . "_" . $entry[1]; # update section and recitation if needed my ( $snum, $rcn ); if ( $cflag == 1 ) { $snum = $entry[0]; $rcn = $entry[1]; } elsif ( $cflag == 2 ) { $rcn = $entry[1]; $snum = $rcn; } else { $rcn = $entry[1]; $snum = substr($entry[1],0,2) . '0'; } $classes{"$crs-$sxn"} = [ ] if ( ! defined( $classes{"$crs-$sxn"} ) ); # generate webwork user data line push( @{$classes{"$crs-$sxn"}}, "$entry[-1], $entry[3], $entry[4], C, , $snum, " . "$rcn, $entry[2]\@umich.edu, $entry[2]" ); } } } print "done\n"; } # where can we find instructor data? my $instrFile = ; foreach my $iFile ( @instrFiles ) { if ( -f "$dataDir/$iFile" ) { $instrFile = $iFile; last; } } my @instrList = (); @instrList = `/bin/cat $dataDir/$instrFile 2> /dev/null` if ( $instrFile ); foreach ( keys %classes ) { my $fn = $_ . ".lst"; while ( -f "$fn" ) { print "file $fn exists: [cr] to overwrite or newname: "; chomp( $fn = <STDIN> ); } $fn = ( $fn eq "" ) ? $_ . ".lst" : $fn; open ( FN, ">$fn") or die ("* error: cannot open file $fn for writing\n"); # get instructor data, if possible my @instrLines = (); if ( @instrList ) { my ( $crs, $sxn ) = ( $_ =~ /(\d+)-((\d+)|(all))/ ); if ( $sxn eq 'all' ) { @instrLines = grep {/^$crs,/} @instrList; } else { @instrLines = grep {/^$crs,$sxn,/} @instrList; } } foreach my $iLine ( @instrLines ) { $iLine =~ s/\s*$//; my @vals = csvSplit(/,/, $iLine); my ( $sxn, $rcn ); if ( $cflag ) { $sxn = $vals[0]; $rcn = $vals[1]; } else { $rcn = $vals[1]; $rcn =~ s/\d$/0/; $sxn = '000'; } print FN "$vals[5], $vals[3], $vals[4], C, , $sxn, " . "$rcn, $vals[2]\@umich.edu, $vals[2]\n"; } foreach my $ent ( @{$classes{$_}} ) { print FN "$ent\n"; } close FN; if ( @instrLines ) { print "wrote userdata to file $fn, including instructor(s)\n"; } else { print "wrote userdata to file $fn; could not add instructor(s)\n"; } } # #------------------------------------------------------------------------------ # subroutines # # sub getpass { # # generate a random password of the form wordNword2, with word being # four letters long, N being a random digit, and word2 being three # letters long. this uses the arrays @threes and @fours loaded by # loadDict # # my $rand1 = int(rand()*(@fours)); # my $rand2 = int(rand()*(@threes)); # my $randd = int(rand()*10); # return $fours[$rand1] . $randd . $threes[$rand2]; # } # sub loadDict { # my ( $df3, $df4 ) = @_; # # returns arrays of 'nice' three and four letter words from the dictionary # files $df3 and $df4 # # @threes = (); # @fours = (); # open(DF, $df3) or die("** can't open dictionary file $df3 **\n"); # while ( <DF> ) { # chomp; # push @threes, $_; # } # close(DF); # open(DF, $df4) or die("** can't open dictionary file $df4 **\n"); # while ( <DF> ) { # chomp; # push @fours, $_; # } # close(DF); # } sub csvSplit { my $line = shift(); my @fields = (); while ( $line ) { my $term = ; if ( $line =~ /^"/ ) { #" $line = substr( $line, 1 ); # bite off quote my $ind = index( $line, '"' ); # " $term = substr( $line, 0, $ind ); $line = ( $term =~ /$line,?$/ ) ? : substr( $line, $ind+1 ); # get rid of any trailing comma $line =~ s/^,//; } else { my $ind = index( $line, ',' ); $term = ($ind == -1) ? $line : substr( $line, 0, $ind ); $line = ( $term =~ /$line,?$/ ) ? : substr( $line, $ind ); # get rid of any trailing comma $line =~ s/^,//; } push( @fields, $term ); } return @fields; } # # end script #------------------------------------------------------------------------------