Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Example report exercise steps #448

Merged
merged 83 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
4440091
template file with step marker
LuckyJosh Sep 25, 2024
c37c095
add step generation script
LuckyJosh Sep 25, 2024
2ff5ce6
removed trailing spaces
LuckyJosh Sep 25, 2024
348d7f2
removed extension, to stop formatters
LuckyJosh Sep 25, 2024
c4449ff
add Makefile to create the step dirs and fill them
LuckyJosh Sep 26, 2024
7a36775
fix missplaced * in regex
LuckyJosh Sep 27, 2024
5be5591
changes to script
LuckyJosh Sep 27, 2024
e1301dc
add and change cli args
LuckyJosh Sep 27, 2024
9dc3557
add makefile using the pyscript
LuckyJosh Sep 27, 2024
fdac792
add dataclass for codeline
LuckyJosh Oct 1, 2024
b594ef4
update makefile
LuckyJosh Oct 1, 2024
1ab7a12
output of all steps for snapshot testing
LuckyJosh Oct 1, 2024
9ebfcba
add data with uncertainty columns
LuckyJosh Oct 1, 2024
fb498ae
add data without uncertainty columns
LuckyJosh Oct 1, 2024
8d0ea12
add template for the latex files
LuckyJosh Oct 1, 2024
14c0b78
add template for the python script
LuckyJosh Oct 1, 2024
521f8c6
add task description files
LuckyJosh Oct 1, 2024
123e036
change for hardcoded results at first
LuckyJosh Oct 1, 2024
efe5e03
fix step range for tikz
LuckyJosh Oct 1, 2024
691df66
fix command
LuckyJosh Oct 1, 2024
b04f16e
fix empty line
LuckyJosh Oct 1, 2024
2edb65b
fix double plot of fitfunction
LuckyJosh Oct 1, 2024
fa789ba
add templates for the bib files
LuckyJosh Oct 1, 2024
1af7d7a
add bibfiles rule
LuckyJosh Oct 1, 2024
81743ee
add prefix to destinguish template and target files
LuckyJosh Oct 1, 2024
d8ede60
change from string substitution to function call
LuckyJosh Oct 1, 2024
66df90a
changed naming and order of variables
LuckyJosh Oct 1, 2024
85527c3
reduce snapshot test to python output
LuckyJosh Oct 1, 2024
8a09837
removed test rule and obsolete content
LuckyJosh Oct 1, 2024
2d279f4
update output snapshot
LuckyJosh Oct 1, 2024
5efbdb0
renamed templates to include filetype
LuckyJosh Oct 1, 2024
6629bab
delete obsolet Makefile
LuckyJosh Oct 1, 2024
f62a718
remove stderr from snapshot test and updated snapshot
LuckyJosh Oct 1, 2024
f331381
change name since texfiles are not really 'scripts'
LuckyJosh Oct 1, 2024
95b7f29
add comments and clean up generation script
LuckyJosh Oct 2, 2024
d55f60a
Merge branch 'main' into example-report-exercise-steps
LuckyJosh Oct 2, 2024
6580ed1
removed the hardcoded last step since the script can infer it
LuckyJosh Oct 2, 2024
ebb3dca
changed required space to optional spaces
LuckyJosh Oct 2, 2024
fa43d8b
fixed regression introduced by the cleanup process
LuckyJosh Oct 2, 2024
c1ac356
fixed copy-paste mistake in the pythonscript template
LuckyJosh Oct 2, 2024
8c88df0
add pattern data to template line for debug/dry-run output
LuckyJosh Oct 2, 2024
0b1d589
fixed naming and parsing of the upperlimit in a pattern
LuckyJosh Oct 2, 2024
98b160c
remove obsolete comment
LuckyJosh Oct 2, 2024
d481918
remove obsolete argument
LuckyJosh Oct 2, 2024
7b9360e
removed incorrect exception fixed upper index
LuckyJosh Oct 2, 2024
ea0480e
change range to list for debug/dry-run output
LuckyJosh Oct 2, 2024
7e3d2b2
fix python outputfiles
LuckyJosh Oct 2, 2024
a32af7d
fix output of test rule
LuckyJosh Oct 2, 2024
4b67c63
remove debug print
LuckyJosh Oct 2, 2024
8306fb6
changes to taskfiles
LuckyJosh Oct 2, 2024
bfb3c9f
add image of the experimental setup
LuckyJosh Oct 2, 2024
9b53569
add templates
LuckyJosh Oct 2, 2024
d10d8cf
add image file to theory section
LuckyJosh Oct 2, 2024
abc92dc
add template Makefile
LuckyJosh Oct 2, 2024
e136fcb
add image file handling
LuckyJosh Oct 2, 2024
3636eb5
renamed image to have some consistancy (files for the report are name…
LuckyJosh Oct 3, 2024
c16a03f
imporved debug/dry-run output
LuckyJosh Oct 3, 2024
9084872
removed empty lines from steps they dont need to be in
LuckyJosh Oct 3, 2024
e4f2e31
added number padding
LuckyJosh Oct 3, 2024
6602df0
fix stepranges
LuckyJosh Oct 3, 2024
57f70e6
add build/ folder
LuckyJosh Oct 3, 2024
2b2e1fd
add build folder in 'makefile'-step (10)
LuckyJosh Oct 3, 2024
0bdb72f
update Makefile
LuckyJosh Oct 3, 2024
46f8245
add taskfiles to makefile fix all and tex_files dependencies
LuckyJosh Oct 3, 2024
32b0fc3
moved reference to later step
LuckyJosh Oct 3, 2024
893f3f8
moved line with ref to step 9
LuckyJosh Oct 3, 2024
ce99086
add Makfile-loesung template for the steps in which no Makefile is pr…
LuckyJosh Oct 3, 2024
2153b51
add function to shorten the copy for loops
LuckyJosh Oct 3, 2024
f30d1dc
add run rule to first build all steps and then run the Makfile therin
LuckyJosh Oct 3, 2024
aa694b6
added command to create empty file, to stop the Makefile from recreat…
LuckyJosh Oct 3, 2024
894868c
fixed stepranges
LuckyJosh Oct 3, 2024
b1e8cb2
add python script content for step 11
LuckyJosh Oct 3, 2024
b1657f1
add python 'libraies' as an example
LuckyJosh Oct 3, 2024
90a882a
update makefile for last step
LuckyJosh Oct 3, 2024
af64bf3
Rename Makefile to Makefile-loesung
chrbeckm Oct 4, 2024
dfbf4d2
example report grammar check part 1
chrbeckm Oct 4, 2024
a3a1e70
grammar check part 2
chrbeckm Oct 4, 2024
ea88c76
grammar check part 3
chrbeckm Oct 4, 2024
afff16a
rephrased the task files + languagetool spellchecking
LuckyJosh Oct 4, 2024
b6df193
added files like the image to the stepfolder in which they are introd…
LuckyJosh Oct 4, 2024
ca166a3
fixed latex lines in wrong step
LuckyJosh Oct 4, 2024
050acad
merge
LuckyJosh Oct 4, 2024
e094b42
Merge branch 'main' into example-report-exercise-steps
LuckyJosh Oct 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
213 changes: 213 additions & 0 deletions exercises-toolbox/8-all/example-report/Makefile-loesung
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
datafilenames = Messwerte_Bahn.txt \
Messwerte_Frames_Kugel.txt \
Messwerte_Frames_Zylinder.txt \
Messwerte_Kamera.txt \
Messwerte_Kugel.txt \
Messwerte_Zylinder.txt

advanced_mpl_filenames = matplotlibrc header-matplotlib.tex

steps = 01 02 03 04 05 06 07 08 09 10 11

### Directories

# build/example-report-step-{01,...,11}/
step_dirs = $(foreach step, $(steps),build/example-report-step-$(step)/)

# build/example-report-step-{01,...,11}/loesung
solution_dirs = $(addsuffix loesung/, $(step_dirs))


# build/example-report-step-{06,...,11}/loesung/v16516/
report_dirs = $(addsuffix v16516/, $(wordlist 6,11,$(solution_dirs)))

# build/example-report-step-{01,05}/data/
step_data_dirs = $(addsuffix data/, $(word 1,$(step_dirs)) $(word 5,$(step_dirs)))

# build/example-report-step-{01,...,05}/loesung/data/
solution_data_dirs = $(addsuffix data/, $(wordlist 1,5,$(solution_dirs)))

# build/example-report-step-{06,...,11}/loesung/v16516/data
report_data_dirs = $(addsuffix data/, $(report_dirs))

# all */data dirs
data_dirs = $(solution_data_dirs) $(report_data_dirs) $(step_data_dirs)
data_dirs_without_unc = $(wordlist 1,4,$(data_dirs)) $(word 12,$(data_dirs))
data_dirs_with_unc = $(wordlist 5,11,$(data_dirs)) $(word 13,$(data_dirs))

# build/example-report-step-{09,...,10}/loesung/v16516/graphics/
graphics_dirs = $(addsuffix v16516/graphics/, $(wordlist 9,10,$(solution_dirs))) $(addsuffix graphics/, $(word 9,$(step_dirs)))

# solution_dirs containing tex files
solution_dirs_with_tex = $(wordlist 7,11,$(solution_dirs))
#build/example-report-step-{07,...,11}/loesung/v16516/content/
content_dirs = $(addsuffix v16516/content/, $(solution_dirs_with_tex))

### Taskfiles

task_files = $(addsuffix aufgabe.txt,$(step_dirs))

### Datafiles

append_datafilenames = $(foreach filename,$(datafilenames),$(addsuffix $(filename), $(1)))

data_files_without_unc = $(call append_datafilenames,$(data_dirs_without_unc))
data_files_with_unc = $(call append_datafilenames, $(data_dirs_with_unc))
data_files = $(data_files_without_unc) $(data_files_with_unc)

### Python files
solution_python_files = $(addsuffix auswertung.py, $(wordlist 1,5,$(solution_dirs)))
report_python_files = $(addsuffix auswertung.py, $(report_dirs))
python_files = $(solution_python_files) $(report_python_files)

### LaTeX Files
header_tex_files=$(addsuffix header.tex, $(solution_dirs_with_tex))
main_tex_files= $(addsuffix v16516/v16516.tex, $(solution_dirs_with_tex))
implementation_tex_files=$(addsuffix durchfuehrung.tex, $(content_dirs))
theory_tex_files=$(addsuffix theorie.tex, $(content_dirs))
evaluation_tex_files=$(addsuffix auswertung.tex, $(content_dirs))
discussion_tex_files=$(addsuffix diskussion.tex, $(content_dirs))

setup_image_files = $(addsuffix versuchsaufbau.png, $(graphics_dirs))

lit_bib_files = $(addsuffix lit.bib, $(wordlist 9,11,$(solution_dirs)) $(word 9,$(step_dirs)))
programms_bib_files = $(addsuffix programme.bib, $(wordlist 9,11,$(solution_dirs)) $(word 9,$(step_dirs)))
bib_files = $(lit_bib_files) $(programms_bib_files)

matplotlibrc_files= $(addsuffix matplotlibrc, $(wordlist 10,11,$(solution_dirs)) $(word 10,$(step_dirs)))
header_matplotlib_files = $(addsuffix header-matplotlib.tex, $(wordlist 10,11,$(solution_dirs)) $(word 10,$(step_dirs)))

advanced_mpl_files = $(matplotlibrc_files) $(header_matplotlib_files)

tex_files = $(header_tex_files) \
$(main_tex_files) \
$(implementation_tex_files) \
$(theory_tex_files) \
$(evaluation_tex_files) \
$(discussion_tex_files) \
$(bib_files) \
$(advanced_mpl_files)

### Makefiles
solution_makefile_files = $(addsuffix Makefile-loesung, $(wordlist 2,5,$(solution_dirs))) \
$(addsuffix v16516/Makefile-loesung, $(wordlist 6,9,$(solution_dirs)))

target_makefile_files = $(addsuffix v16516/Makefile, $(wordlist 10,11,$(solution_dirs)))
makefile_files = $(solution_makefile_files) $(target_makefile_files)

python_libs = $(addprefix build/example-report-step-11/loesung/v16516/, curve_fit.py latex_formatting.py)

run: all
# Run all Makefile-loesung
set -- $(wordlist 1, 5,$(solution_dirs)); \
for i do\
make -C $$i -f Makefile-loesung; \
done
# Run all Makefile-loesung in the additional subdir v16516
set -- $(addsuffix v16516/, $(wordlist 6, 9,$(solution_dirs))); \
for i do\
make -C $$i -f Makefile-loesung; \
done
# Run the Makefile in the last two steps
set -- $(addsuffix v16516/, $(wordlist 10, 11,$(solution_dirs))); \
for i do\
make -C $$i -f Makefile; \
done
# copy the final report into the first step_dir
cp $(addsuffix v16516/build/v16516.pdf,$(word 11, $(solution_dirs))) $(addsuffix v16516.pdf,$(word 1, $(solution_dirs)))


all: $(task_files) \
$(python_files) \
$(data_files) \
$(tex_files) \
$(setup_image_files) \
$(makefile_files)\
$(python_libs)

$(word 1, $(python_libs)): templates/curve_fit.py | $(report_dirs)
cp $< $@

$(word 2, $(python_libs)): templates/latex_formatting.py | $(report_dirs)
cp $< $@


build/example-report-step-%/aufgabe.txt &: $(template_task_files) | $(step_dirs)
cp templates/aufgabe-step-$*.txt build/example-report-step-$*/aufgabe.txt

copy_file_loop=set -- $(2); for i do cp $(1) $$i; done

$(solution_makefile_files) &: templates/Makefile-loesung_template | $(solution_dirs) $(report_dirs)
python generate-step-files.py -t $< -s 2 $(addprefix -o=,$(solution_makefile_files))

$(target_makefile_files) &: templates/Makefile | $(report_dirs)
$(call copy_file_loop, $<, $(target_makefile_files))

$(matplotlibrc_files) &: templates/matplotlibrc | $(solution_dirs)
$(call copy_file_loop, $<,$(matplotlibrc_files))

$(programms_bib_files) &: templates/programme.bib | $(solution_dirs)
$(call copy_file_loop, $<, $(programms_bib_files))

$(lit_bib_files) &: templates/lit.bib | $(solution_dirs)
$(call copy_file_loop, $<, $(lit_bib_files))

$(setup_image_files) &: templates/versuchsaufbau.png | $(graphics_dirs)
$(call copy_file_loop, $<, $(setup_image_files))

$(header_matplotlib_files) &: templates/header-matplotlib.tex | $(solution_dirs)
$(call copy_file_loop, $<, $(header_matplotlib_files))

$(header_tex_files) &: templates/latex/header_tex_template | $(solution_dirs)
python generate-step-files.py -t $< -s 7 $(addprefix -o=,$(header_tex_files))

$(main_tex_files) &: templates/latex/v16516_tex_template | $(content_dirs)
python generate-step-files.py -t $< -s 7 $(addprefix -o=,$(main_tex_files))

$(theory_tex_files) &: templates/latex/theorie_tex_template | $(content_dirs)
python generate-step-files.py -t $< -s 7 $(addprefix -o=,$(theory_tex_files))

$(implementation_tex_files) &: templates/latex/durchfuehrung_tex_template | $(content_dirs)
python generate-step-files.py -t $< -s 7 $(addprefix -o=,$(implementation_tex_files))

$(evaluation_tex_files) &: templates/latex/auswertung_tex_template | $(content_dirs)
python generate-step-files.py -t $< -s 7 $(addprefix -o=,$(evaluation_tex_files))

$(discussion_tex_files) &: templates/latex/diskussion_tex_template | $(content_dirs)
python generate-step-files.py -t $< -s 7 $(addprefix -o=,$(discussion_tex_files))

$(python_files) &: templates/auswertung_py_template | $(solution_dirs) $(report_dirs)
touch build/example-report-step-01/loesung/auswertung.py
python generate-step-files.py -t templates/auswertung_py_template $(addprefix -o=,$(python_files))


copy_dir_loop=set -- $(2); for i do cp -r $(1) $$i; done
$(data_files_without_unc) &: templates/data_without_uncertainties/* | $(solution_dirs) $(report_dirs)
$(call copy_dir_loop, templates/data_without_uncertainties, $(data_dirs_without_unc))

$(data_files_with_unc) &: templates/data_with_uncertainties/* | $(solution_dirs) $(report_dirs)
$(call copy_dir_loop, templates/data_with_uncertainties, $(data_dirs_with_unc))

$(content_dirs) &:|$(report_dirs)
mkdir -p $(content_dirs)

$(graphics_dirs)&: |$(report_dirs)
mkdir -p $(graphics_dirs)

$(report_dirs)&: | $(solution_dirs)
mkdir -p $(report_dirs)

$(solution_dirs) &: | $(step_dirs)
mkdir -p $(solution_dirs)

$(step_dirs): | build
mkdir -p $(step_dirs)

build:
mkdir -p build

clean:
rm -r build

.PHONY: all clean

151 changes: 151 additions & 0 deletions exercises-toolbox/8-all/example-report/generate-step-files.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import argparse
import re
import sys
from collections import defaultdict
from dataclasses import dataclass
from collections.abc import Iterable

STEPRANGEREGEX = re.compile(r"(?:#|%)\s*<(\d*)(-(\d*)|)>")

@dataclass
class Templateline:
linenumber: int
line: str
output_file_indices: Iterable
pattern: str

def __str__(self):
pattern_length = len(self.pattern)
indicies = f"{self.output_file_indices[0]},...,{self.output_file_indices[-1]}"
# magic number 10: the amount of padding necessary to print a pattern with two two-digit numbers
return f"({self.pattern} → [{indicies}]) {" "*(10-pattern_length)} {self.linenumber:>3} {self.line}"


def setup_arg_parser():
parser = argparse.ArgumentParser(
prog="generate-step-files",
description="Generate multiple (step)files containing lines from a template file",
epilog='')

parser.add_argument('-v', '--verbose', action='store_true',
help="Get info on parsed args, the step maximum steprange in the template and to be removed lines.")
parser.add_argument('-n', '--dry-run', action='store_true',
help="Print the content of each output file to stdout instead of generating any files.")
# This option allows to use the same step numbering in differnt independent files
parser.add_argument('-s', '--start-step', type=int, default=1,
help="Set the step that should be considered step 1 for this file")
parser.add_argument('-t','--template_filepath', dest='template_filepath', required=True,
help="Filepath to the template file.")
parser.add_argument('-o', '--output_filepaths', dest='output_filepaths', action="append", required=True,
help="Filepaths to the output files (you need to use one Option -o <file> for each file). Hint: use -o=file{1,2,3} for example, to generate the multiple options.)")
return parser

def parse_lines_and_stepranges(lines, start_step, end_step):
template_lines = []
removed_lines = []
for i,l in enumerate(lines, start=1):
found = STEPRANGEREGEX.search(l)

# a line containing no pattern will not be saved to any output file, hence 'removed'
if found is None:
removed_lines.append(Templateline(i,l, [], ""))
continue
groups = found.groups()

try:
lower_step_limit = int(groups[0])
except ValueError:
raise ValueError(f"The pattern ({found.group()}) in line {i} of the template file has not starting step.")

# Since the end_step is calculated from the number of output files given
# the lower index has to be changed to be less then the upper index
lower_index = lower_step_limit - start_step
if lower_index < 0:
raise ValueError(f"The given star_step {start_step} is higher then the lower limit in the pattern '{found.group()}' in line {i} of the template file.")

# The dash and second number can be omitted:
# e.g. <4> is equivalent to <4-4>
if (not groups[1]) and (groups[2] is None):
# To include anything the upper index has to be increased by 1
step_limits = (lower_index, lower_index + 1)

# If the second number is omitted but the dash is not, the upper limit is the last step:
# e.g. <4-> is equivalent to <4-10> if 10 output files are generated
elif not groups[2]:
# the number of files given is used for the upper index (it is already 1 greater then the highest possible index)
upper_index = end_step
step_limits = (lower_index, upper_index)

# both numbers are present in the pattern
else:
upper_step_limit = int(groups[2])
upper_index = upper_step_limit - start_step + 1

step_limits = (lower_index, upper_index)

num_files_with_current_line = (step_limits[1] - step_limits[0])
if num_files_with_current_line > end_step:
raise ValueError(f"The number of given output files is {end_step},"
f" but line {i} of the template file is expected to appear in {num_files_with_current_line} output files (pattern: {found.group()}).")

# remove the steprange pattern and spaces between line content and pattern
line_content = STEPRANGEREGEX.sub("", l).rstrip()
template_lines.append(Templateline(i, line_content, list(range(*step_limits)), found.group()))

return template_lines, removed_lines


def split_stepfile_lines(template_lines, output_filepaths):

lines_per_stepfile = defaultdict(list)
for line in template_lines:
for step in line.output_file_indices:
lines_per_stepfile[output_filepaths[step]].append(line)

return lines_per_stepfile


def main():
parser = setup_arg_parser()
args = parser.parse_args()

template_filepath = args.template_filepath
output_filepaths = args.output_filepaths


if args.verbose:
print("Input:")
print(' '.join(sys.argv))
print("Parsed:")
print(f" - template file: {template_filepath}")
print(f" - output files: {output_filepaths}")
print(f" - start step: {args.start_step}")


with open(template_filepath) as fh:
template_lines = fh.readlines()

template_lines, removed_lines = parse_lines_and_stepranges(template_lines, args.start_step, len(output_filepaths))

lines_per_stepfiles = split_stepfile_lines(template_lines, output_filepaths)

if args.verbose:
print("Removed lines:")
print(f"{'\n'.join(str(rl) for rl in removed_lines)}")
print(f"Found steps: {lines_per_stepfiles.keys()}")


if args.dry_run:
for stepfile, lines in lines_per_stepfiles.items():
print(f"\nOutput file '{stepfile}' with index ({output_filepaths.index(stepfile)}) would contain these lines from the template file:")
print(f"pattern → indicies{" "*9}ln line")
print(f"{"\n".join(str(l) for l in lines)}")
return


for stepfile, lines in lines_per_stepfiles.items():
with open(stepfile, "w") as fh:
fh.write("\n".join(l.line for l in lines).strip())

if __name__ == "__main__":
main()
33 changes: 33 additions & 0 deletions exercises-toolbox/8-all/example-report/templates/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
all: build/v16516.pdf

# hier Python-Skripte:
build/plot-I_kugel.pdf build/plot-I_zylinder.pdf build/plot-g_kugel.pdf build/plot-g_zylinder.pdf: auswertung.py ../matplotlibrc ../header-matplotlib.tex | build
# so that matplotlib can find the tex header when running
# LaTeX in the tmp directory
# and set the matplotlibrc
TEXINPUTS=$$(pwd)/..: MATPLOTLIBRC=../matplotlibrc python auswertung.py

# hier weitere Abhängigkeiten für build/vXXX.pdf deklarieren:
build/v16516.pdf: build/plot-I_kugel.pdf build/plot-I_zylinder.pdf build/plot-g_kugel.pdf build/plot-g_zylinder.pdf

build/v16516.pdf: FORCE | build
# to find header and bib files in the main directory
TEXINPUTS=..: \
BIBINPUTS=..: \
max_print_line=1048576 \
latexmk \
--lualatex \
--output-directory=build \
--interaction=nonstopmode \
--halt-on-error \
v16516.tex

build:
mkdir -p build

clean:
rm -rf build

FORCE:

.PHONY: all clean
Loading
Loading