From 89e2776f50cfbec7ade7247eaadf555283f0e0c2 Mon Sep 17 00:00:00 2001 From: stormdragon2976 Date: Sun, 18 Jun 2023 11:18:48 -0400 Subject: [PATCH] Initial commit. --- LICENSE | 14 +++++ README.md | 18 ++++++ quiz.sh | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 211 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100755 quiz.sh diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ee7d6a5 --- /dev/null +++ b/LICENSE @@ -0,0 +1,14 @@ + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2004 Sam Hocevar + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..2b0f9ec --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +## Quiz + +Simple quiz app. Answers can be multiple choice or true/false. + +## Usage + +Rename quiz.sh to the subject for which you want to create a quiz. + + cp quiz.sh history.sh + +Run with the -a flag to add questions and follow the prompts. + + ./history.sh -a + + +## Taking the quiz + +Simply run the file with no arguments to take the quiz. At the end, your results will be calculated on a 100 point grading scale. diff --git a/quiz.sh b/quiz.sh new file mode 100755 index 0000000..b1a4f4d --- /dev/null +++ b/quiz.sh @@ -0,0 +1,179 @@ +#!/usr/bin/env bash + + +add_question() { + question="|" + until [[ ${#question} -eq 0 ]]; do + read -p "Enter the question. (leave blank to end): " question + if [[ ${#question} -eq 0 ]]; then + continue + fi + while [[ $question == *"|"* ]]; do + echo "Question cannot contain '|'. Please try again." + read -p "Enter the question (without '|' character): " question + done + question="${question^}" + + answers=() + read -p "Enter the answer (or press Enter to proceed to correct answer): " answer + while [[ -n $answer ]]; do + answers+=("$answer") + if [[ "${answer^^}" =~ ^(T(R(U(E)?)?)?|F(A(L(S(E)?)?)?)?)$ ]]; then + break + fi + read -p "Next answer? (press Enter to proceed): " answer + done + + if [[ ${#answers[@]} -gt 1 ]]; then + choices=() + for ((i=1; i<=${#answers[@]}; i++)); do + letter=$(printf "%s" $((i)) | tr '1-9' 'A-J') + choices+=("${letter}: ${answers[$((i-1))]}") + done + + choicesStr="${choices[0]}" + for ((i=1; i<${#choices[@]}; i++)); do + choicesStr+="|${choices[$i]}" + done + + echo "Enter the correct choice:" + read -p "${choicesStr//|/$'\n'}: " correct + correct="${correct^}" + while [[ ! $correct =~ ^[A-${letter}]$ ]]; do + echo "Invalid choice. Please try again." + read -p "Enter the correct choice (${choicesStr}): " correct + done + correctChoice="${correct:0:1}" + elif [[ ${#answers[@]} -eq 1 ]]; then + choice=${answers[0]} + if [[ "${choice^^}" =~ ^[T][R][U][E]?$ ]]; then + correctChoice="T" + elif [[ "$choice" =~ ^[F][A][L][S][E]?$ ]]; then + correctChoice="F" + else + echo "Invalid choice. Assuming 'T' (True) as the correct answer." + correctChoice="T" + fi + else + echo "No answers provided. Skipping the question." + return + fi + + question="${question}|${correctChoice:0:1}|${choicesStr}" + question="${question%|}" + echo "${question}" >> "$0" + echo "Question added successfully!" + done + exit 0 +} + + +shuffle_choices() { + if [[ ${#answers[@]} -lt 2 ]]; then + return + fi + local letter=({A..Z}) + local length="${#answers[@]}" + local newAnswer + local shuffledChoices + mapfile -t shuffledChoices < <(shuf -e "${answers[@]#*: }") + for i in "${!answers[@]}" ; do + if [[ "${answers[$i]:0:1}" == "${answer}" ]]; then + newAnswer="${answers[$i]}" + fi +done + for i in "${!shuffledChoices[@]}" ; do + shuffledChoices[$i]="${letter[$i]}: ${shuffledChoices[$i]}" + if [[ "${shuffledChoices[$i]#*:}" == "${newAnswer#*:}" ]]; then + answer="${letter[$i]}" + fi + done + answers=("${shuffledChoices[@]}") +} + + +if [[ $# -gt 1 ]]; then + echo "Only 1 argument supported, -a or --question." + exit 0 +fi + +if [[ $# -eq 1 ]]; then + if [[ "${1}" == "-a" ]] || [[ "${1}" == "--add-question" ]]; then + add_question + else + echo "Only 1 argument supported, -a or --question." + exit 0 + fi +fi + + +startPosition="$(grep -n '^exit 0$' "${0}")" +startPosition="${startPosition%%:*}" +((startPosition++)) +mapfile -t data < <(tail -n +${startPosition} "$0" | grep -v "^#" | grep -v "^$" | shuf) +right=0 +wrong=0 + +echo "Total questions: ${#data[@]}" +if [[ ${#data[@]} -eq 0 ]]; then + echo "To add questions use the -a or --add-questions flag." +fi + +for i in "${data[@]}" ; do + question="${i%%|*}" + i="${i#*|}" + answer="${i%%|*}" + answer="${answer^}" + i="${i#*|}" + unset answers + while [[ ${#i} -gt 1 ]]; do + answers+=("${i%%|*}") + i="${i#*|}" + if [[ "${i%%|*}" == "${i}" ]]; then + answers+=("${i}") + break + fi + done + shuffle_choices + echo + echo "${question}" + for i in "${answers[@]}" ; do + echo "${i}" + done + read -r choice + choice="${choice:0:1}" + choice="${choice^}" + if [[ "${choice}" == "${answer}" ]]; then + echo "Correct!" + ((right++)) + else + echo -n "Wrong, the answer is: " + for i in "${answers[@]}" ; do + if [[ "${answer}" == "${i:0:1}" ]]; then + echo "$i" + fi + done + ((wrong++)) + fi + if [[ "${answer}" == "F" ]] || [[ "${answer}" == "T" ]]; then + answer="${answer/F/False}" + answer="${answer/T/True}" + echo "${answer}" + fi + read -rp "Press enter to continue" +done + + +# Results +echo +echo "Out of ${#data[@]} questions, you got ${right} correct." +if [[ ${#wrong} -gt 0 ]]; then + echo "You missed ${wrong} questions." +fi +if command -v bc &> /dev/null ; then + grade=$(echo "scale=2; $right * 100 / ${#data[@]}" | bc) + echo "On a 100 based grading scale, this gives you a score of $grade." +fi + + +exit 0