...
 
Commits (6)
......@@ -15,10 +15,10 @@ The input files should be placed in the `script_input` folder which is in the sa
| name | lastname | email | matrikel|
|---|---|---|---|
|Theodore |Von Kárman |example1@ovgu.de |123456|
|Theodore |Von Kármán |example1@ovgu.de |123456|
|Osborne |Reynolds |example2@st.ovgu.de |123457|
1. `assignment_info.csv` :file with the range for the marked values.
1. `assignment_info.csv`: file with the range for the marked values.
|find_marker |range_min |range_max |round_off_decimals
|---|---|---|---|
......@@ -28,5 +28,5 @@ The input files should be placed in the `script_input` folder which is in the sa
## Script output
1. `output_assignments.csv`:file with a summary of all the output data.
1. `output_assignments.csv`: file with a summary of all the output data.
1. `parameters_ID_xxxxxxxx`: one `tex` file, with custom parameters, for each student.
......@@ -5,8 +5,8 @@ Script: Assignment Customizer
Description:
This script takes a tex file with marked parameters and a list of students
matriculation numbers to produce a new tex file with custom parameters for
each student and a csv file with all the output assignments data.
matriculation numbers to produce 1) a new tex file with custom parameters for
each student and 2) a summary csv file with all the output assignments data.
"""
"""-------------------------Hard coded input--------------------------------"""
......@@ -20,18 +20,18 @@ output_parameters_path = 'script_output/parameters_ID_'
"""-------------------------------------------------------------------------"""
# Import modules
import csv # For reading cvs files
import csv # For reading csv files
from hash_function import hash_function # Import hash_function
# Initialize arrays to store data
names = [] # Student name
names = [] # Student first name
last_name = [] # Student last name
emails = [] # Student email address
matrikel_num = [] # Student matrikel number
markers = [] # Marker for the number to customize
range_min = [] # Maximum value that the custom number can take
range_max = [] # Minimum value that the custom number can take
decimals = [] # Number of decimals to round off the custom numbers
decimals = [] # Number of decimals by which to round off the custom numbers
custom_ID = [] # Custom ID for the student
rand_matrix = [] # These are the random numbers to customize the assignments
custom_values = [] # Matrix with all custom values for each student assingment
......@@ -62,7 +62,7 @@ with open(assignment_info_path, newline='') as f:
range_max.append(float(row[2]))
decimals.append(int(row[3]))
# Generate anonimus ID and six semi-randoms numbers for each student
# Generate anonymous ID and six specific numbers for each student
for number in matrikel_num:
[ID, rand_numbers]=hash_function(number)
custom_ID.append(ID)
......@@ -71,7 +71,7 @@ for number in matrikel_num:
# Generate custom values for each student from the semi-random numbers
for i in range (0,len(names)):
counter = 0 # Initialize counter for random numbers indexes
temp_array = [] # Initialize temporal array
temp_array = [] # Initialize temporary array
for j in range (0,len(markers)):
if counter>5: # This is for the case when len(markers)>random numbers
counter=0
......@@ -88,7 +88,7 @@ with open (output_csv_path,'w',newline='') as f:
writer.writerow([names[i],last_name[i],emails[i],matrikel_num[i],
custom_ID[i]]+custom_values[i])
# Generate modified tex files with custom parameters for each student
# Generate a tex file with custom parameters for each student
for i in range (0,len(names)): # For each student
temp_param=parameters
for j in range (0, len(markers)): # Replace each marker by a custom value
......
resultone = dummyone * dummytwo
resulttwo = dummytwo**2 + dummyone**(0.5)
find_marker,range_min,range_max,round_off_decimals
XXpipediameterXX,0.5,3,1
XXpipelengthXX,100,350,0
XXmassflowXX,1.5,4,1
XXdensityXX,980,1300,0
find_marker,range_min,range_max,round_off_decimals
XXpipediameterXX,0.5,3,1
XXpipelengthXX,100,350,0
XXdensityXX,980,1300,0
XXviscosityXX,1E-05,0.2,7
XXreynoldsXX,4500,20000000,0
XXdummyoneXX,1,10000,0
XXdummytwoXX,0.001,0.1,4
\newcommand{\pipediameter}{XXpipediameterXX}
\newcommand{\pipelength}{XXpipelengthXX}
\newcommand{\massflow}{XXmassflowXX}
\newcommand{\density}{XXdensityXX}
\newcommand{\viscosity}{XXviscosityXX}
\newcommand{\reynolds}{XXreynoldsXX}
\newcommand{\dummytwo}{XXdummytwoXX}
\newcommand{\dummyone}{XXdummyoneXX}
name,lastname,email,matrikel,custom_ID,XXpipediameterXX,XXpipelengthXX,XXmassflowXX,XXdensityXX
Osborne,Von Kármán,example1@ovgu.de,123456,28107819,1.2,102.0,2.0,1097.0
Theodore,Reynolds,example2@ovgu.de,123457,17688816,1.9,349.0,3.6,990.0
student1,one,one@st.ovgu.de,100001,32203334,1.7,270.0,2.4,1044.0
student2,two,two@st.ovgu.de,100002,90886833,1.1,308.0,3.0,1010.0
student3,three,three@st.ovgu.de,100003,89131963,2.6,133.0,2.8,1267.0
student4,four,four@st.ovgu.de,100004,25214889,1.9,172.0,2.9,1272.0
student5,five,five@st.ovgu.de,100005,31675588,1.2,180.0,1.7,1060.0
student6,six,six@st.ovgu.de,100006,26783579,2.8,346.0,1.9,1219.0
student7,seven,seven@st.ovgu.de,100007,91213660,2.9,141.0,3.6,1144.0
student8,eight,eight@st.ovgu.de,100008,33105406,1.3,105.0,2.5,1218.0
name,lastname,email,matrikel,custom_ID,XXpipediameterXX,XXpipelengthXX,XXdensityXX,XXviscosityXX,XXreynoldsXX,XXdummyoneXX,XXdummytwoXX
Osborne,Von Kármán,example1@ovgu.de,123456,28107819,1.2,102.0,1042.0,0.0734063,5423280.0,1971.0,0.0299
Theodore,Reynolds,example2@ovgu.de,123457,17688816,1.9,349.0,1251.0,0.0062097,6223100.0,8120.0,0.0566
student1,one,one@st.ovgu.de,100001,32203334,1.7,270.0,1095.0,0.040208,10522133.0,4051.0,0.0468
student2,two,two@st.ovgu.de,100002,90886833,1.1,308.0,1176.0,0.0186091,17820490.0,2511.0,0.0265
student3,three,three@st.ovgu.de,100003,89131963,2.6,133.0,1140.0,0.179401,384414.0,4971.0,0.0824
student4,four,four@st.ovgu.de,100004,25214889,1.9,172.0,1157.0,0.1824009,18620310.0,7930.0,0.0554
student5,five,five@st.ovgu.de,100005,31675588,1.2,180.0,1001.0,0.0502075,12641656.0,3401.0,0.0275
student6,six,six@st.ovgu.de,100006,26783579,2.8,346.0,1030.0,0.1494025,12641656.0,5540.0,0.0929
student7,seven,seven@st.ovgu.de,100007,91213660,2.9,141.0,1250.0,0.1024049,2563924.0,9650.0,0.0964
student8,eight,eight@st.ovgu.de,100008,33105406,1.3,105.0,1108.0,0.1486026,8222651.0,9170.0,0.0328
\newcommand{\pipediameter}{1.9}
\newcommand{\pipelength}{349.0}
\newcommand{\massflow}{3.6}
\newcommand{\density}{990.0}
\newcommand{\density}{1251.0}
\newcommand{\viscosity}{0.0062097}
\newcommand{\reynolds}{6223100.0}
\newcommand{\dummytwo}{0.0566}
\newcommand{\dummyone}{8120.0}
\newcommand{\pipediameter}{1.9}
\newcommand{\pipelength}{172.0}
\newcommand{\massflow}{2.9}
\newcommand{\density}{1272.0}
\newcommand{\density}{1157.0}
\newcommand{\viscosity}{0.1824009}
\newcommand{\reynolds}{18620310.0}
\newcommand{\dummytwo}{0.0554}
\newcommand{\dummyone}{7930.0}
\newcommand{\pipediameter}{2.8}
\newcommand{\pipelength}{346.0}
\newcommand{\massflow}{1.9}
\newcommand{\density}{1219.0}
\newcommand{\density}{1030.0}
\newcommand{\viscosity}{0.1494025}
\newcommand{\reynolds}{12641656.0}
\newcommand{\dummytwo}{0.0929}
\newcommand{\dummyone}{5540.0}
\newcommand{\pipediameter}{1.2}
\newcommand{\pipelength}{102.0}
\newcommand{\massflow}{2.0}
\newcommand{\density}{1097.0}
\newcommand{\density}{1042.0}
\newcommand{\viscosity}{0.0734063}
\newcommand{\reynolds}{5423280.0}
\newcommand{\dummytwo}{0.0299}
\newcommand{\dummyone}{1971.0}
\newcommand{\pipediameter}{1.2}
\newcommand{\pipelength}{180.0}
\newcommand{\massflow}{1.7}
\newcommand{\density}{1060.0}
\newcommand{\density}{1001.0}
\newcommand{\viscosity}{0.0502075}
\newcommand{\reynolds}{12641656.0}
\newcommand{\dummytwo}{0.0275}
\newcommand{\dummyone}{3401.0}
\newcommand{\pipediameter}{1.7}
\newcommand{\pipelength}{270.0}
\newcommand{\massflow}{2.4}
\newcommand{\density}{1044.0}
\newcommand{\density}{1095.0}
\newcommand{\viscosity}{0.040208}
\newcommand{\reynolds}{10522133.0}
\newcommand{\dummytwo}{0.0468}
\newcommand{\dummyone}{4051.0}
\newcommand{\pipediameter}{1.3}
\newcommand{\pipelength}{105.0}
\newcommand{\massflow}{2.5}
\newcommand{\density}{1218.0}
\newcommand{\density}{1108.0}
\newcommand{\viscosity}{0.1486026}
\newcommand{\reynolds}{8222651.0}
\newcommand{\dummytwo}{0.0328}
\newcommand{\dummyone}{9170.0}
\newcommand{\pipediameter}{2.6}
\newcommand{\pipelength}{133.0}
\newcommand{\massflow}{2.8}
\newcommand{\density}{1267.0}
\newcommand{\density}{1140.0}
\newcommand{\viscosity}{0.179401}
\newcommand{\reynolds}{384414.0}
\newcommand{\dummytwo}{0.0824}
\newcommand{\dummyone}{4971.0}
\newcommand{\pipediameter}{1.1}
\newcommand{\pipelength}{308.0}
\newcommand{\massflow}{3.0}
\newcommand{\density}{1010.0}
\newcommand{\density}{1176.0}
\newcommand{\viscosity}{0.0186091}
\newcommand{\reynolds}{17820490.0}
\newcommand{\dummytwo}{0.0265}
\newcommand{\dummyone}{2511.0}
\newcommand{\pipediameter}{2.9}
\newcommand{\pipelength}{141.0}
\newcommand{\massflow}{3.6}
\newcommand{\density}{1144.0}
\newcommand{\density}{1250.0}
\newcommand{\viscosity}{0.1024049}
\newcommand{\reynolds}{2563924.0}
\newcommand{\dummytwo}{0.0964}
\newcommand{\dummyone}{9650.0}
Script: create_pdfs.sh
======================
## Description
This script takes a series of `tex` files containing each a series of LaTeX variables with custom values, and produces, for each of those, a pair of `pdf` files: one contaning the assignment, and the other containing the corresponding solution.
The input files should be placed in the `script_input` folder which is in the same path as the script. The output files will be saved in the `script_output` folder.
## Dependencies
The script is run in a bash shell on a Ubuntu system. It makes use of the `pdflatex` compiler. The example `tex` file uses stylesheets from the [sensible styles](https://git.framasoft.org/u/olivier/sensible-styles) library.
## Script input
1. One `sample_problem_assignment.tex` and one `sample_problem_solution.tex` file, containing the basic LaTeX templates for the assignment and solution of the problem.
1. Any number of `parameters_ID_xxxxxxxx.tex` files, with xxxxxxxx the custom ID for each student, containing declarations for LaTeX variables and their numerical values, for example:
\newcommand{\codenumber}{17688816}
\newcommand{\pipediameter}{1.9}
\newcommand{\pipelength}{349.0}
\newcommand{\viscosity}{1.2e-2}
## Script output
For each input file, a pair of files named `assignment_ID_xxxxxxxx.pdf` and `solution_ID_xxxxxxxx.pdf`.
#!/bin/bash
# Input parameters
inputfolder='script_input'
outputfolder='script_output'
assignmentsourcefile="$inputfolder/assignment.tex"
solutionsourcefile="$inputfolder/solution.tex"
# Cleanup output folder
mkdir -v $outputfolder/old
rm -rvf $outputfolder/old/*
mv -vf $outputfolder/* $outputfolder/old/
# Create links to the source tex files in the current folder
# syntax: ln -s destination linkname
ln -svf "$assignmentsourcefile" assignment.tex
ln -svf "$solutionsourcefile" solution.tex
# Pick up all the files in input folder one by one
for parameterfile in "$inputfolder"/parameters_ID_*.tex; do
# What is the code number?
# Pick up parameter file name, strip all but number, call it $codenumber
codenumber=$(echo $parameterfile | sed "s/$inputfolder\/parameters_ID_//" | sed 's/\.tex//')
echo "#"
echo "#"
echo "building PDFs with code number of $codenumber..."
# Define input and output file names for this problem ID
parameterfilepath=$(echo $inputfolder/parameters_ID_$codenumber.tex)
assignmentfilepath=$(echo $outputfolder/assignment_ID_$codenumber.pdf)
solutionfilepath=$(echo $outputfolder/solution_ID_$codenumber.pdf)
# Make a link called "parameters.tex" that points to the specific
# parameters file for this ID
ln -svf "$parameterfilepath" parameters.tex
# Add LaTeX variable at the end of parameters.tex, which is just
# the custom ID:
echo "\newcommand{\codenumber}{$codenumber}" >> parameters.tex
# Empty up the tmp subfolder
rm -rf tmp/*
# Compile the actual PDF files:
# compile them with pdflatex
# then move the result to the output folder
pdflatex assignment.tex
mv -vf assignment.pdf $assignmentfilepath
pdflatex solution.tex
mv -vf solution.pdf $solutionfilepath
# Cleanup after pdflatex: move temporary files to tmp subfolder
mv -vf *.aux *.bbl *.bcf *.blg *.ilg *.log *.nav *.nlo *.nls *.run.xml *.snm *.toc *.out *.fls *.fdb_latexmk *.spl *-blx.bib *-eps-converted-to.pdf *bib.bak tmp/
done
# Remove remaining symlinks in main folder
rm -v parameters.tex assignment.tex solution.tex
echo "end of script."
\documentclass[12pt,a4paper]{article}
\usepackage{magdeburg1} % from https://git.framasoft.org/u/olivier/sensible-styles
\renewcommand{\authorofthisdocument}{Olivier Cleynen}
\renewcommand{\titleofthisdocument}{Example problem: assignment}
\usepackage{magdeburg2}
\input{parameters.tex}
\begin{document}
\begin{center}
~\vspace{2cm}\par
{\LARGE \titleofthisdocument\par}
\vspace{1em}
{\footnotesize Last modified \today\\
Olivier Cleynen -- olivier.cleynen@ovgu.de\\}
\vspace{2em}
\end{center}
\vspace{3cm}
\section{Introduction}
This example document is generated automatically for the student with the code number \num{\codenumber}.
\section{Problem}
An object has property $A = \SI{\dummyone}{\metre\per\second}$.
What is the value of $B$?
\end{document}
\newcommand{\pipediameter}{1.9}
\newcommand{\pipelength}{349.0}
\newcommand{\density}{1251.0}
\newcommand{\viscosity}{0.0062097}
\newcommand{\reynolds}{6223100.0}
\newcommand{\dummytwo}{0.0566}
\newcommand{\dummyone}{8120.0}
\newcommand{\meanvelocity}{1.234}
\newcommand{\massflow}{12.34}
\newcommand{\pipediameter}{1.9}
\newcommand{\pipelength}{172.0}
\newcommand{\density}{1157.0}
\newcommand{\viscosity}{0.1824009}
\newcommand{\reynolds}{18620310.0}
\newcommand{\dummytwo}{0.0554}
\newcommand{\dummyone}{7930.0}
\newcommand{\meanvelocity}{1.234}
\newcommand{\massflow}{12.34}
\newcommand{\pipediameter}{2.8}
\newcommand{\pipelength}{346.0}
\newcommand{\density}{1030.0}
\newcommand{\viscosity}{0.1494025}
\newcommand{\reynolds}{12641656.0}
\newcommand{\dummytwo}{0.0929}
\newcommand{\dummyone}{5540.0}
\newcommand{\meanvelocity}{1.234}
\newcommand{\massflow}{12.34}
\documentclass[12pt,a4paper]{article}
\usepackage{magdeburg1} % from https://git.framasoft.org/u/olivier/sensible-styles
\renewcommand{\authorofthisdocument}{Olivier Cleynen}
\renewcommand{\titleofthisdocument}{Example problem: solution}
\usepackage{magdeburg2}
\input{parameters.tex}
\begin{document}
\begin{center}
~\vspace{2cm}\par
{\LARGE \titleofthisdocument\par}
\vspace{1em}
{\footnotesize Last modified \today\\
Olivier Cleynen -- olivier.cleynen@ovgu.de\\}
\vspace{2em}
\end{center}
\vspace{3cm}
\section{Introduction}
This example document is the solution for the problem with code number \num{\codenumber}.\\
Please grade this fairly and rigorously. Thank you!
\section{Problem solution}
Since $A$ has the value $A = \SI{\dummyone}{\metre\per\second}$, we calculate that $B = \SI{\dummytwo}{\kelvin}$.
\end{document}
......@@ -7,18 +7,18 @@ Script: Match Peers
"""-------------------------Hard coded input--------------------------------"""
# Input files paths
students_info_path = 'script_input/output_assignments.csv'
submission_pdfs_path = 'script_input/submission_'#pdf name : submission_ID.pdf'
submission_pdfs_path = 'script_input/submission_' # pdf name : submission_ID.pdf'
# Output files paths
peers_csv_path = 'script_output/peers.csv'
"""-------------------------------------------------------------------------"""
# Import modules
import csv # For reading cvs files
import csv # For reading csv files
import pathlib # For working with local paths
import random # For shuffling elements in arrays
# Initialize arrays to store data
names = [] # Student name
names = [] # Student first name
last_name = [] # Student last name
emails = [] # Student email address
matrikel_num = [] # Student matrikel number
......@@ -26,8 +26,8 @@ custom_ID = [] # Custom ID for the student
did_their_homework = [] # List of students that actually submitted a solution
ID_peer1 = [] # List of peers (first peer)
ID_peer2 = [] # List of peers (second peer)
random_peers1 = [] # Temporal list of possible peers to assign
random_peers2 = [] # Temporal list of possible peers to assign
random_peers1 = [] # Temporary list of possible peers to assign
random_peers2 = [] # Temporary list of possible peers to assign
# Store students data from csv file into variables
with open(students_info_path, newline='') as f:
......@@ -41,8 +41,8 @@ with open(students_info_path, newline='') as f:
matrikel_num.append(row[3])
custom_ID.append(row[4])
# Check which students actually sent a solution to their assignment by looking
# for a file in the "script_input" folder with the name "soluttion_ID.pdf"
# Check which students actually submitted their solution to their assignment by looking
# for a file in the "script_input" folder with the name "submission_ID.pdf"
for i in range(0, len(custom_ID)):
file_to_search = pathlib.Path(submission_pdfs_path+custom_ID[i]+'.pdf')
did_their_homework.append(file_to_search.exists())
......@@ -54,7 +54,7 @@ for i in range(0, len(custom_ID)):
ID_peer1 = ['']*len(names)
ID_peer2 = ['']*len(names)
# Create two temporal arrays with the peers to be assigned
# Create two temporary arrays with the peers to be assigned
for i in range(0,len(custom_ID)):
# Only students who submitted solution can recieve a peer role
if did_their_homework[i]==True:
......@@ -79,8 +79,8 @@ while counter<len(names) and iterations<10000:
iterations = iterations + 1 # Update iterations counter
continue # This jumps to the begining of the while loop
# Make sure that te last student in the list does not end up without a peer
# given the case that the last peer to be assigned is himself (or herself)
# Make sure that the last student in the list does not end up wihout a peer,
# in the case that the last peer to be assigned is themselves.
if len(random_peers1) == 1 and (custom_ID[counter] == random_peers1[0] or
custom_ID[counter] == random_peers2[0] or
random_peers1[0] == random_peers2[0]):
......
......@@ -13,7 +13,7 @@ This tool is being developed in order to experiment with peer-graded coursework
## Authors
Germán Santa-Maria, [Olivier Cleynen](https://ariadacapo.net/), with the kind financial support of the [LSS laboratory](http://www.lss.ovgu.de) of the university. Inspiration and guidance were gratefully received from [Mathias Magdowski](http://www.imt.ovgu.de/Das+Institut/Mitarbeiterinnen+und+Mitarbeiter/visitenkarten/magdowski__mathias-kat-lehrveranstaltungen-p-71.html) (see [[1]](https://www.slideshare.net/MathiasMagdowski/personalisierbare-aufgaben-und-anonymer-peerreview/), [[2]](https://www.youtube.com/watch?v=hnMEFYMfa0M)).
Germán Santa-Maria, [Olivier Cleynen](https://ariadacapo.net/), with the kind financial support of the [LSS laboratory](http://www.lss.ovgu.de) of the university. Inspiration and guidance were gratefully received from [Mathias Magdowski](http://www.imt.ovgu.de/Das+Institut/Mitarbeiterinnen+und+Mitarbeiter/visitenkarten/magdowski__mathias-kat-lehrveranstaltungen-p-71.html) (see [[1]](https://www.slideshare.net/MathiasMagdowski/personalisierbare-aufgaben-und-anonymer-peerreview/), [[2]](https://www.researchgate.net/publication/330243310_Personalisierbare_Aufgaben_und_anonymer_Peer-Review)).
## License
......@@ -29,7 +29,7 @@ A total of nine modules (six of which being locally-run scripts) are needed to r
[x] [Module 2](M2_customize_assignments): Generate custom variables for assignments
(in Python)
[ ] Module 3: Generate assignments and solutions
[x] [Module 3](M3_generate_assignments): Generate assignments and solutions
(in bash + LaTeX)
[ ] Module 4: Send assignments to students
......