Learning stuff

I’ve learned a great deal about the inner workings of WordPress over the past week and I’ve decided to write my own theme. Naturally, the best way to do that is to modify one that’s intended for just this purpose. I’ve switched to this barebones theme in an attempt to learn how all this stuff works.

Should be an adventure.

Back to the Future

This is just too cool. Listening to this makes me want to put together a community horn ensemble. Thing is, there are just enough top rate horn players in this area that I think it could actually work. Something to ponder, for sure.

My Christmas Menu

Now that Christmas has come and gone, I feel I have time to post my Christmas menu. So, here it goes

Roast Turkey (did my own brine from what I had on hand, some champagne that had long since gone flat, spiced apple cider, orange juice, a bit of red wine, bay leaves, peppercorns, thyme, 3/4 cup sugar, 1 1/2 cup salt, water and ice.)
Dressing (Pepperidge Farms mix that I made with cream of celery soup)
Smoked Chile Scalloped Sweet Potatoes
Cranberry Chutney
Tofurkey Roast with stuffing & mushroom gravy
Mashed Potatoes & Turkey Gravy
Sugar Snap Peas & Asparagus
Lemon Merangue Pie
Pecan Pie
Eggnog

For the record, I did my own pie crust, and you can find the recipe here. An interesting comparison came up because I only had enough lard for one of the pie crusts (yes, I keep lard on hand). The pie crust made with butter and shortening still tasted good, but was not as tender as the one made with butter and lard. By the way, one important modification on AB’s pie crust recipe – skip the whole deal with the water spritzer. Just add the entire 1/4 cup of that the recipe calls for into the food processor. Every time I’ve used the water spritzer I apparently ended up not using enough water, resulting in a crust that sticks to the parchment paper during blind baking. Every time I’ve simply added the 1/4 cup water the pie comes out perfectly.

The brine did a great job on keeping the turkey moist. You can even get a hint of some of those extra flavors when tasting the dark meat. I think the biggest hits for the meal portion were the smoked chile sweet potatoes and the cranberry chutney. I did reduce the recipe for the chutney by 1/3 just to have more reasonable proportions. i think next time I would have reduced it to use just a single bag of cranberries (the recipe called for 2.5 pounds and I reduced it to use two 12 oz bags). Even making the reduction, I have tons left over, though it is very good stuff. I think the larger recipe would be appropriate for canning and/or gift giving. The sweet potatoes were great, though I cooked them much longer than what was called for – probably because it was sharing the oven with other items at the time. Still, make sure you go by looks and be sure to taste it when you bring it out to make sure it’s done the way you want it.

I may add some pictures to this post later on.

A new adventure

Last night, I successfully bid on and won an original West Bend Poppery hot air popcorn popper and 4 pounds of green coffee beans. Two things are certain about this:

1. A culinary adventure is about to begin.
2. It’s somewhat ironic that I’m excited about buying green beans.

Autograde Script 2.0

As with the earlier versions, this script is designed to check my students’ typing assignments against a key. I had to download all submitted assignments in moodle, placing them in a folder on my linux box, placing the key in .txt format, and running the script. This would output a fairly long filename that had the grade in it. I would then have to go ahead and manually enter in students’ grades in moodle and manually upload each response file. It was a big improvement, but still a tedious process. This new script automates the entire process.

The usage for the script is simply

./autograde lesson#

After that, it downloads all assignments, grades them, posts the grades to moodle, and uploads a response file.

There were some challenges for me in this one, most of which involved learning the intricacies of moodle. If you’re interested in adapting this for your own purposes, you should know that each assignment has a different number. One is related to the submissions.php file which displays the assignments in the browser, the other is related to the moodledata folder where the submissions for each student are actually stored.

In order to make this work, I had to be able to query the mysql database to find the userid number for each student. Each submission file begins with the student’s username, so I had to find a way to truncate the file so that it would return the username only and then use that to query the mysql database to return the userid. I found a great php script here and ended up using it twice in my setup – once to obtain the username in order to find the userid, and again later to obtain a consistent, and simpler filename. The second instance probably could have been done in bash instead of php, but I was already taking up too much time to write this script as it was. At some point, I may tinker with it and see if I can make it more efficient, but since it works, I’m not really inclined to fix it.

If you have any comments or suggestions on how to improve it in any way, I welcome your comments.

Dependencies:
docx2txt
dwdiff
curl
Chirp Internet’s php text truncation script
ftp access to your moodledata directory

First, here’s the main script. If you’re going to use it, be sure to change the URL’s and replace the username and password with your correct information. Also, you’ll need to do a search and replace to replace the &lt and &gt with the proper angle brackets.

#!/bin/bash

# first check if there is one argument1:
if [ "$#" -ne 1 ]; then
    echo "usage: $0 &ltlesson#&gt"
    exit
fi

WORKDIR=$HOME/autograde/$1
KEYFILE=$HOME/autograde/keys/$1key.txt


if [ "$1" == lesson1 ]; then
ASSIGNMENT=125
UPLOADDIR=93
else if [ "$1" == lesson2 ]; then
ASSIGNMENT=126
UPLOADDIR=94
else if [ "$1" == lesson3 ]; then
ASSIGNMENT=127
UPLOADDIR=95
else if [ "$1" == lesson4 ]; then
ASSIGNMENT=17
UPLOADDIR=11
else if [ "$1" == lesson5 ]; then
ASSIGNMENT=15
UPLOADDIR=10
else if [ "$1" == lesson6 ]; then
ASSIGNMENT=33
UPLOADDIR=22
else if [ "$1" == lesson7 ]; then
ASSIGNMENT=54
UPLOADDIR=35
else if [ "$1" == lesson8 ]; then
ASSIGNMENT=74
UPLOADDIR=50
else if [ "$1" == lesson9 ]; then
ASSIGNMENT=94
UPLOADDIR=67
else if [ "$1" == lesson10 ]; then
ASSIGNMENT=128
UPLOADDIR=96
else if [ "$1" == lesson11 ]; then
ASSIGNMENT=129
UPLOADDIR=97
else if [ "$1" == lesson12 ]; then
ASSIGNMENT=98
UPLOADDIR=71
else if [ "$1" == lesson13 ]; then
ASSIGNMENT=130
UPLOADDIR=98
else if [ "$1" == lesson14 ] ; then
ASSIGNMENT=131
UPLOADDIR=99
else if [ "$1" == lesson15 ] ; then
ASSIGNMENT=132
UPLOADDIR=100
else if [ "$1" == lesson16 ] ; then
ASSIGNMENT=133
UPLOADDIR=101
else echo "Please input the lesson you which to grade as \"lesson#\", using only lower case, no spaces, and of course, no quotes."
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi

echo "Moodle assignment number is" $ASSIGNMENT
echo "Working directory is" $WORKDIR
echo "The key for this exercise is" $KEYFILE

#visit the home page to get current session cookie
echo "Visiting the home page to get current session cookie"
wget --spider --save-cookies cookies.txt --keep-session-cookies https://yourwebsite.com/moodle/login/index.php

#log in to moodle
echo "logging into moodle"
wget --load-cookies cookies.txt --save-cookies cookies.txt --keep-session-cookies --post-data "username=username&password=password&testcookie=1" -O- https://yourwebsite.com/moodle/login/index.php

#download all files for assignment
echo "downloading zip file containing assignments for" $1
wget --load-cookies cookies.txt --save-cookies cookies.txt --keep-session-cookies --post-data "download=zip" -O "$WORKDIR/assignments.zip" https://yourwebsite.com/moodle/mod/assignment/submissions.php?id=$ASSIGNMENT


#unzip assignments to appropriate location
unzip $WORKDIR/assignments.zip -d $WORKDIR

#delete previously uploaded feedback files
rm $WORKDIR/*response*

GRADEDDIR=$WORKDIR/graded

#checks to see if $GRADEDDIR exists and creates it if it does not
if [ ! -d "$GRADEDDIR" ]; then
mkdir -p "$GRADEDDIR"
fi

#converts MS Word format to plain text
for UNGRADED in $WORKDIR/*.docx; do
docx2txt.sh $UNGRADED;
done

#compares text files against key and outputs to .GRADED.txt file
for GRADED in $WORKDIR/*.txt; do
/usr/bin/dwdiff -s $KEYFILE $GRADED &gt "$WORKDIR/$(basename $GRADED .txt).GRADED"
done

#renames .GRADED file with information dwdiff writes to end of file
for RENAMED in $WORKDIR/*.GRADED; do
mv $RENAMED "$WORKDIR/$(basename $RENAMED .GRADED).$(grep "old:" $RENAMED).RENAMED"
done

#moves graded files to graded directory
for MOVED in $WORKDIR/*.RENAMED; do
mv "$MOVED" $GRADEDDIR/
done

#begin converting .RENAMED to .html
for COLORIZED in $GRADEDDIR/*.RENAMED; do
cat "$COLORIZED" | sed -e 's/\[-/&ltspan style=\"background-color:red\"&gt/g' -e 's/-\]/&lt\/span&gt/g' -e 's/{+/&ltspan style=\"background-color:yellow\"&gt/g' -e 's/+}/&lt\/span&gt/g' -e '1i&lthtml&gt\n&ltbody&gt\n&ltpre&gt' -e 's/old:/Answer Key:/' -e 's/new:/Your Document:/' &gt "$COLORIZED.html"
done

#finish converting .txt to .html
for HTMLEND in $GRADEDDIR/*.html; do
echo "&lt/pre&gt
&lt/body&gt
&lt/html&gt" &gt&gt '$HTMLEND'
done

#clean up the filenames a bit
rename 's/.old: /\-/' $GRADEDDIR/*.html
rename 's/.RENAMED././' $GRADEDDIR/*.html

#removes .txt files from $WORKDIR
rm $WORKDIR/*.txt
#remove last line of .RENAMED file and rename to .TRUNCATED
for TRUNCATED in $GRADEDDIR/*.RENAMED; do
sed -e '$d' "$TRUNCATED" &gt "$TRUNCATED".TRUNCATED
done

#remove spaces from .TRUNCATED filenames
rename 's/ /_/g' $GRADEDDIR/*.TRUNCATED

#remove spaces from .html filenames
rename 's/ /_/g' $GRADEDDIR/*.html

#remove % sign and replace with word 'percent' in html filenames
rename 's/%/percent/g' $GRADEDDIR/*.html

#remove all .RENAMED files from $GRADEDDIR to clean up a bit
rm $GRADEDDIR/*.RENAMED

#define userid and grade variables and post the grades and a generic comment to moodle
for POSTED in $GRADEDDIR/*.TRUNCATED; do
USERID=$(curl -s -d "filename=$(basename $POSTED)" http://yourwebsite.com/getuserid.php)
POSTEDGRADE=$(grep -o '[[:digit:]]*% common' $POSTED | grep -o '[[:digit:]]*')
wget --load-cookies cookies.txt --save-cookies cookies.txt --keep-session-cookies --post-data "offset=1&userid=$USERID&id=$ASSIGNMENT&mode=grade&menuindex=10&saveuserid=-1&grade=$POSTEDGRADE&submissioncomment=Please+ask+me+if+you+have+any+questions.+&format=1&mailinfo=0&submit=Save+changes" -O- https://yourwebsite.com/moodle/mod/assignment/submissions.php
done

echo "Now renaming files into an easier to read format. This may take a while."

for RESPONSEFILES in $GRADEDDIR/*.html; do
GETUSERID=$(curl -s -d "filename=$(basename $RESPONSEFILES)" http://yourwebsite.com/getuserid.php | sed 's/ //g')
GETSHORTNAME=$(curl -s -d "filename=$(basename $RESPONSEFILES)" "http://yourwebsite.com/getusername.php" | sed 's/ //g')
mv $RESPONSEFILES $GRADEDDIR/$GETSHORTNAME
done

rename 's/Chapter/_Chapter/' $GRADEDDIR/*.html

for SHORTNAMERESPONSE in $GRADEDDIR/*.html ; do
GETUSERID=$(curl -s -d "filename=$(basename $SHORTNAMERESPONSE)" http://yourwebsite.com/getuserid.php | sed 's/ //g')
curl -T $SHORTNAMERESPONSE ftp://yourwebsite.com/moodledata/2/moddata/assignment/$UPLOADDIR/$GETUSERID/responses/ --user username:password --ftp-create-dirs
done

#clean up a bit more
rm $WORKDIR/assignments.zip
rm $GRADEDDIR/*.TRUNCATED
rm $WORKDIR/*.docx
rm $GRADEDDIR/*.html

Next is the getuserid.php script:

&lt?php
// Original PHP code by Chirp Internet: www.chirp.com.au 
// Please acknowledge use of this code by including this header. 
function myTruncate($string, $limit, $break=".", $pad="...") 
{  
  // return with no change if string is shorter than $limit  
  if(strlen($string) &lt= $limit) return $string;  
  // is $break present between $limit and the end of the string?  
   if(false !== ($breakpoint = strpos($string, $break, $limit))) {  
     if($breakpoint &lt strlen($string) - 1) {  
  $string = substr($string, 0, $breakpoint);  
  }
  } 
  
  return $string; 
  }

$con = mysql_connect("localhost",databasename","password");
if (!$con)
  {
  die('Could not connect: ' . mysql_error());
  }

mysql_select_db("databasename", $con);

$testpost = $_POST['filename'];
$testtruncate = myTruncate($testpost, 1, "_");
$result = mysql_query("SELECT id FROM mdl_user WHERE username LIKE '$testtruncate'") or die(mysql_error());
while($row = mysql_fetch_array($result))
  {
  echo $row["id"];
  }

mysql_close($con);
?&gt 

Last is the getusername.php script, which really probably could be done entirely in bash, I just haven’t put my head to it yet:

&lt?php
$filename = $_POST['filename'];
$pieces = explode("_", $filename);
echo $pieces[0] . $pieces[1] . $pieces[2] . "feedback.html";
?&gt 

And that’s it. Again, any comments or suggestions you have are most welcome.

Updated Auto Grade Script

Not long after I posted the original autograding script, I figured out a way to colorize the output. My solution was html. Here’s the script in it’s final (for now) form.

EDIT – For some reason, WordPress really doesn’t like this script, even within the pre tags. If you want to use it, you’ll just have to do a search and replace to get rid of the &lt and &gt to replace them with the appropriate characters.

#!/bin/bash
WORKDIR=$1
KEYFILE=$2
GRADEDDIR=$WORKDIR/graded

# first check if there are two arguments:
if [ "$#" -ne 2 ]; then
    echo "usage: $0 &lt/path/to/files&gt &lt/path/to/answerkey.txt&gt"
    exit
fi

#checks to see if $GRADEDDIR exists and creates it if it does not
if [ ! -d "$GRADEDDIR" ]; then
        mkdir -p "$GRADEDDIR"
fi

#converts MS Word format to plain text
for UNGRADED in $WORKDIR/*.docx; do
docx2txt.sh $UNGRADED;
done

#compares text files against key and outputs to .GRADED.txt file
for GRADED in $WORKDIR/*.txt; do
dwdiff -s $KEYFILE $GRADED &gt "$WORKDIR/$(basename $GRADED .txt).GRADED"
done

#renames .GRADED file with information dwdiff writes to end of file
for RENAMED in $WORKDIR/*.GRADED; do
mv $RENAMED "$WORKDIR/$(basename $RENAMED .GRADED).$(grep "old:" $RENAMED).RENAMED"
done

#moves graded files to graded directory
for MOVED in $WORKDIR/*.RENAMED; do
mv "$MOVED" $GRADEDDIR/
done

#begin converting .RENAMED to .html
for COLORIZED in $GRADEDDIR/*.RENAMED; do
cat "$COLORIZED" | sed -e 's/\[-/&ltspan style=\"background-color:red\"&gt/g' -e 's/-\]/&lt\/span&gt/g' -e 's/{+/&ltspan style=\"background-color:yellow\"&gt/g' -e 's/+}/&lt\/span&gt/g' -e '1i&lthtml&gt\n&ltbody&gt\n&ltpre&gt' -e 's/old:/Answer Key:/' -e 's/new:/Your Document:/' &gt "$COLORIZED.html"
done

#finish converting .txt to .html
for HTMLEND in $GRADEDDIR/*.html; do
echo "&lt/pre&gt
&lt/body&gt
&lt/html&gt" &gt&gt '$HTMLEND'
done

#clean up the filenames a bit
rename 's/.old: /\-/' $GRADEDDIR/*.html
rename 's/.RENAMED././' $GRADEDDIR/*.html

#removes .txt files from $WORKDIR and .RENAMED files from $GRADEDDIR
rm $WORKDIR/*.txt
rm $GRADEDDIR/*.RENAMED