Skip to content

Commit

Permalink
Update documentation to reflect the previous commit
Browse files Browse the repository at this point in the history
  • Loading branch information
kagalenko-m-b authored and kagalenko-m-b committed Jan 7, 2025
1 parent 0c50110 commit 523acd6
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 72 deletions.
86 changes: 17 additions & 69 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,73 +2,21 @@

[![Build Status](https://github.com/kagalenko-m-b/ProblemSet.jl/workflows/CI/badge.svg)](https://github.com/kagalenko-m-b/ProblemSet.jl/actions)

The goal of this project is to facilitate the creation of problem assignments
for a group of students. A problem set consists of several problem templates with
text and placeholder variables. Percentage signs before and after mark the
placeholder variables within the template text. Function `problemset_latex()`
then generates the latex source of the assignment and solutions for a vector of students'
names. In the latex source assigned values replace the placeholder variables.
Every placeholder variable must appear at least once as the left-hand of
an assignment where the tilde replaces the equality sign.
The goal of this package is to facilitate the creation of problem assignments
for a group of students. It allows to randomize the assignments in two ways:

This is an example set:
```julia
@problemset my_set begin
@problem pool begin
pool_size_liters ~ rand(1000:10:2000)
inflow_liters_sec ~ rand(10:20)
outflow_max = inflow_liters_sec ÷ 2
outflow_liters_sec ~ rand(1:outflow_max)
@solution begin
fill_rate = inflow_liters_sec - outflow_liters_sec
time_to_fill = pool_size_liters / fill_rate
time_to_fill_min ~ round(time_to_fill / 60, digits=3)
leaked_liters ~ round(time_to_fill*outflow_liters_sec, digits=3)
end
@text """
An empty pool can hold %pool_size_liters% liters of water. Pipe
fills it at the rate %inflow_liters_sec%~liters/sec while another
drains it at the rate %outflow_liters_sec%~liters/sec. How many minutes
will it take to fill the pool and how many liters of water will
drain out by the time the pool is full?
"""
@text_solution """
It will take %time_to_fill_min% minutes to fill the pool and
%leaked_liters%~liters of water will drain out.
"""
end
@problem addition begin
x ~ rand(1:3)
y ~ rand(2:5)
@solution xy ~ x + y
@text raw""" Find the sum \(c = a + b\) of two values: \(a = %x%\) and
\(b = %y%\)
"""
@text_solution raw"""
Sum is equal to \(c = %xy%\)
"""
end
@problem subtraction begin
z ~ rand(7:9)
w ~ rand(1:5)
@solution zw ~ z - w
@text raw""" Find the difference \(c = a - b\) of two values: \(a = %z%\) and
\(b = %w%\)
"""
@text_solution raw"""
Difference is equal to \(c = %zw%\)
"""
end
end
```
After execution of this macro, there's a vector in workspace named `my_set`
that contains three functions `my_set_pool()`, `my_set_addition()` and
`my_set_subtraction()`. Text-generating function makes use of their
[methods](Generated_methods.md). This is how an assignment may be produced:
```julia
student_names = ["A", "B", "C"];
rng_seed = 123;
txt,txt_sol = problemset_latex(student_names, my_set, 2=>1:3, rng_seed);
write("problems.tex", latex_preamble*txt);
write("solutions.tex", latex_preamble*txt);
```
* [random selection](Random_selection.md) of problems from a set, and

* [random variations](Random_variations.md) of the specified parts of an individual
problem's statement.

Those two kinds of randomization may be combined.

A problem set consists of several problem templates. Each template may hold the textual
statement of the problem, its solution and fragments of Julia code to vary
the values of placeholder variables within the statement and the solution.

The package exports macros `@problem` and `@problemset` that create a template and a set,
respectively. Function `problemset_latex()` generates the latex sources of
assignments and their solutions. To ensure reproducibility, it calls `Random.seed!()`
with an incremental value before generating each succesive problem.
24 changes: 24 additions & 0 deletions Random_selection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
## Random selection of problems from a set

A simplest set may be created by giving to the `@problemset` macro a list of questions
as a multiline string:
```julia
@problemset question_set """The first question.
The second question.
...
The tenth question."
```
This creates a workspace vector named `question_set` that contains ten functions
`question_set_1()`, `question_set_2()`, … `question_set_10()`. Suppose you wish
an individual assignment to contain one question from the first half of the vector
and two questions from the second half. That may be accomplished as follows:
```julia
student_names = ["A", "B", "C", "D"];
rng_seed = 123;
subsets = [1=>1:5, 2=>6:10]
txt, = problemset_latex(student_names, question_set, subsets, rng_seed);
write("questions.tex", latex_preamble()*txt);
```
72 changes: 72 additions & 0 deletions Random_variations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
## Random variation of a problem's statement

Problem template will typically include the statement's text with a few placeholder
variables. Percentage signs before and after mark the
placeholder variables within the template text. Function `problemset_latex()`
then generates the latex source of the assignment and solutions for a vector of students'
names. In the latex source assigned values replace the placeholder variables.
Every placeholder variable must appear at least once as the left-hand of
an assignment where the tilde replaces the equality sign.

This is an example set:
```julia
@problemset my_set begin
@problem pool begin
pool_size_liters ~ rand(1000:10:2000)
inflow_liters_sec ~ rand(10:20)
outflow_max = inflow_liters_sec ÷ 2
outflow_liters_sec ~ rand(1:outflow_max)
@solution begin
fill_rate = inflow_liters_sec - outflow_liters_sec
time_to_fill = pool_size_liters / fill_rate
time_to_fill_min ~ round(time_to_fill / 60, digits=3)
leaked_liters ~ round(time_to_fill*outflow_liters_sec, digits=3)
end
@text """
An empty pool can hold %pool_size_liters% liters of water. Pipe
fills it at the rate %inflow_liters_sec%~liters/sec while another
drains it at the rate %outflow_liters_sec%~liters/sec. How many minutes
will it take to fill the pool and how many liters of water will
drain out by the time the pool is full?
"""
@text_solution """
It will take %time_to_fill_min% minutes to fill the pool and
%leaked_liters%~liters of water will drain out.
"""
end
@problem addition begin
x ~ rand(1:3)
y ~ rand(2:5)
@solution xy ~ x + y
@text raw""" Find the sum \(c = a + b\) of two values: \(a = %x%\) and
\(b = %y%\)
"""
@text_solution raw"""
Sum is equal to \(c = %xy%\)
"""
end
@problem subtraction begin
z ~ rand(7:9)
w ~ rand(1:5)
@solution zw ~ z - w
@text raw""" Find the difference \(c = a - b\) of two values: \(a = %z%\) and
\(b = %w%\)
"""
@text_solution raw"""
Difference is equal to \(c = %zw%\)
"""
end
end
```

Executing this macro creates a workspace vector named `my_set`
that contains three functions `my_set_pool()`, `my_set_addition()` and
`my_set_subtraction()`. Text-generating function makes use of their
[methods](Generated_methods.md). This is how an assignment may be produced:
```julia
student_names = ["A", "B", "C", "D"];
rng_seed = 123;
txt,txt_sol = problemset_latex(student_names, my_set, 2=>1:3, rng_seed);
write("problems.tex", latex_preamble()*txt);
write("solutions.tex", latex_preamble()*txt);
```
10 changes: 7 additions & 3 deletions src/ProblemSet.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module ProblemSet
using MacroTools
using Random

export @problem, @problemset, TokenText, problemset_latex, latex_preamble
export TokenText, @problem, @problemset, problemset_latex, latex_preamble

struct TokenText
strings::Vector{<:AbstractString}
Expand All @@ -15,8 +15,8 @@ struct TokenText
end
include("problem_compiler.jl")

latex_preamble = """
\\documentclass[a4paper,12pt,notitlepage]{article}
latex_preamble(;font_size_pt::Integer=12, default_language=:english) = """
\\documentclass[a4paper,$(font_size_pt)pt,notitlepage]{article}
\\usepackage{amsmath}
\\usepackage[left=1.cm,right=1cm,top=1cm,bottom=1cm]{geometry}
\\pagenumbering{gobble}
Expand All @@ -26,7 +26,11 @@ latex_preamble = """
\\usepackage{float}
\\usepackage{graphicx}
\\usepackage{bookmark}
\\usepackage{tabularx}
\\usepackage[table]{xcolor}
\\setdefaultlanguage{$default_language}
\\setmainfont{Liberation Serif}
\\setmonofont{Liberation Mono}
\\setsansfont{Liberation Sans}\n\n"""

function select_problems(
Expand Down

0 comments on commit 523acd6

Please sign in to comment.