Wie implementiere ich mit Bash ein textbasiertes Quiz?

Wie implementiere ich mit Bash ein textbasiertes Quiz?

Gibt es eine vernünftige Möglichkeit, ein Quiz in Bash zu implementieren, bei dem die Fragen jedes Mal nach dem Zufallsprinzip ausgewählt werden und die verschiedenen Antworten der Benutzer (richtig, falsch, bestanden) aufgezeichnet und dann am Ende des Quiz angegeben werden?

Ich nehme an, dass Arrays zum Speichern der Quizfragen und -antworten verwendet werden könnten und dass die Quizfragen selbst innerhalb einer while- oder till-Schleife gestellt werden könnten und dass die Anzahl der einzelnen Fragen erhöht werden könnte, bis die letzte erreicht ist. Anschließend könnte die Leistung des Benutzers anhand verschiedener bedingter Anweisungen bewertet werden?


Bitte beachte, dassdiese alte FrageIch habe über grafische Quiz-Software gesprochen und dabei explizit Sound/Grafiken usw. erwähnt, während ich nur über ein textbasiertes Quiz über die Befehlszeile spreche.

(Ich habe meine eigene Frage unten beantwortet … aber wenn jemand ein anderes Framework für ein Quiz in Bash hat, posten Sie es bitte.)

Antwort1

Das Quiz-Framework, das ich mir ausgedacht habe, ist unten veröffentlicht, und auch aufGitHub(die ursprüngliche GitHub-Seite des Benutzers existiert nicht mehr).

Da es ziemlich kompliziert aussieht, möchte ich besser erklären, wie es funktioniert.

Im Skript werden die Ubuntu-Versionen und Codenamen aller bisherigen Releases in zwei Arrays gespeichert. Die Variablen werden dann initialisiertdraußender Until-Schleife, sodass sie in der Schleife mithilfe der C- (( var++ ))Notation nach Bedarf erhöht werden können.

Anschließend erstelle ich ein weiteres Array für die Fragenummern. In diesem Fall muss ich für 19 Fragen die Zahlen 0 - 18 (einschließlich) einschließen:

questions_order=(15 4 1 10 8 3 13 0 11 16 2 7 5 17 6 9 14 18 12)

und mische es dann shuf, erstelle ein neues Array und verwende es für diesen bestimmten Lauf des Skripts:

shuffled_order=( $(shuf -n19 -e ${questions_order[@]}) )

Das muss getan werdendraußender Schleife, da ich sie nur einmal ausführen möchte.

Kurz gesagt läuft die Schleife nun so lange, bis die aktuelle Fragenanzahl gleich der "${target_questions}"Variablen ist, und dann werden die Ergebnisse ausgegeben.

Wenn ein Benutzer eine Antwort auf eine Frage gibt, wird diese anhand der verschiedenen Bedingungen in der caseAnweisung interpretiert. Nicht-Antworten (Leerzeichen), falsche Antworten, richtige Antworten und bestandene Antworten werden alle erkannt und erhalten Antworten, und die verschiedenen Variablen werden alle erhöht (z. B. für eine falsche Antwort (( wrong++ ))).

Nach Beantwortung der letzten Frage wird die Leistung des Benutzers ausgewertet. Dabei wird die Anzahl der richtigen und falschen Antworten sowie der ggf. bestandenen Antworten übermittelt und die benötigte Zeit angegeben.

Dies ist eine kurze Erklärung, aber das Skript selbst enthält verschiedene Kommentare, die die Funktionsweise (mehr oder weniger) klar machen sollten! Es könnte für jede andere Art von Quiz angepasst werden, beispielsweise zu Hauptstädten und Ländern.

Wenn Sie das Skript in eine Datei kopiert haben, machen Sie es ausführbar ( chmod u+x), und führen Sie es mit aus ./scriptnameoder platzieren Sie es in Ihrem ~/binOrdner und rufen Sie es wie jedes andere Programm beim Namen auf, vorausgesetzt, Ihr Programm ~/binbefindet sich im PATH.

#!/usr/bin/env bash

# by mik, aka Exactus29, https://github.com/Exactus29
# 
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

######### 

# Requires at least bash 3.1. As it makes extensive use of arrays, it would be a pain to 
# try to write it to be sh compatible, but it may be possible.

# arrays for questions and answers
codenames=("Warty Wharthog" "Hoary Hedgehog" "Breezy Badger" "Dapper Drake" "Edgy Eft" "Feisty Fawn" 
"Gutsy Gibbon" "Hardy Heron" "Intrepid Ibex" "Jaunty Jackalope" "Karmic Koala" "Lucid Lynx" "Maverick Meerkat" 
"Natty Narwahl" "Oneric Ocelot" "Precise Pangolin" "Quantal Quentzal" "Raring Ringtail" "Saucy Salamander")
versions=(4.10 5.04 5.10 6.06 6.10 7.04 7.10 8.04 8.10 9.04 9.10 10.04 10.10 
11.04 11.10 12.04 12.10 13.04 13.10)

# must intialize quest_index at -1 so we can use array index 0
quest_index=-1
target_questions=19
# we start question counter at 0, so we can increment it to the value in number_questions
questions=0 
# the other variables below will all be incremented as necessary in the quiz
correct=0 
wrong=0
no_response=0
pass=0

# declare questions_order array and then shuffle it and use that for this run of the script.
# must be declared outside of the loop, as only want it executed once
questions_order=(15 4 1 10 8 3 13 0 11 16 2 7 5 17 6 9 14 18 12)
shuffled_order=( $(shuf -n19 -e ${questions_order[@]}) )

printf "\nPress 0 to exit the quiz at any time.\n"
printf "You can ignore case in your answers, but correct spelling of the Ubuntu codenames is crucial.\n"
printf "Please enter the word pass if you don't know the answer.\n\n\n"


timer_begin=$SECONDS


until (( questions == target_questions )); do
 
(( questions++ ))

(( quest_index++ ))

new_index=$( echo ${shuffled_order[$quest_index]})

# alternate style of questions, separate odd and even 

    if (( questions % 2 > 0 )); then 
        new_question="${codenames[$new_index]}"
        ans="${versions[$new_index]}"
        question_text="Ubuntu release had the development codename"
    else
        new_question="${versions[$new_index]}"
        ans="${codenames[$new_index]}"
        question_text="was the Ubuntu development codename (both adjective and animal) for release"
    fi

read -p "(${questions}) What ${question_text} ${new_question}? " response 

# necessary to switch on nocasematch to cover if the answer is in capitals, as can't use normal [Mm] in case statement
shopt -s nocasematch

    case $response in 
    "$ans") 
          printf "Well done, correct answer. " 
          (( correct++ ))
          if (( questions < target_questions )); then 
              printf "Next question.\n\n" 
          else
              printf "\nHowever, the quiz has now finished. Let us calculate your performance...\n"
              sleep 1
          fi
       ;; 
       0) 
          printf "\nOk, time to finish with the quiz.\n"
          break
       ;;
    "pass")
         (( pass++ ))
         printf "Ok, you passed on this one..."
         if (( pass >= 10 )); then 
            printf "The passes are mounting, as you have now had ${pass} passes.\n"
         elif (( pass >= 2 )); then
            printf "Please try to give an answer, as you have now had ${pass} passes.\n" 
         fi
            
         if (( questions < target_questions )); then 
            printf "Let us try another question.\n\n"
         else
            printf "\nHowever, the quiz has now finished. Let us calculate your performance.....\n"
            sleep 1
         fi
         
       ;;
       *) 
          if [[ -z ${response} ]]; then
              printf "Please provide an answer, as a blank answer is counted as a wrong answer; "
              (( no_response++ ))
              (( wrong++ ))
                if (( no_response == 1  )); then
                    printf "${no_response} blank response has been given so far. \n"
                elif (( no_response > 1 )); then
                    printf "${no_response} blank responses have been given so far. \n"   
                fi
          else
              (( wrong++ ))
                if  (( questions % 2 > 0 )); then
                    printf "That is incorrect..."
                else 
                    printf "That is incorrect, ${response} was not the codename of ${new_question}. \n"
                fi
          fi
           
         if (( questions < target_questions )); then 
            printf "Let us try another question.\n\n"
         else
            printf "\nHowever, the quiz has now finished. Let us calculate your performance.....\n"
            sleep 1
         fi
       ;;
    esac

done

quiz_duration=$(( SECONDS - timer_begin ))
# could further process the $quiz_duration if it is over 60 seconds, and output the total in
# minutes and seconds using bc or awk

# checking against target_questions here, i.e. all of the questions
if (( questions == target_questions )); then 
    if (( correct == target_questions )); then
        printf "\nYou got them all right in ${quiz_duration} seconds, well done!\n\n"
    elif (( no_response == target_questions )); then 
        printf "\nYou gave ${no_response} blank responses, and so effectively gave ${no_response} wrong answers.\n\n"                
    elif (( wrong == target_questions )); then
        printf "\nYou got them all wrong in ${quiz_duration} seconds, oh dear!\n\n"
    elif (( pass == target_questions )); then 
        printf "\nYou passed on all the questions. Was this just a trial run?\n\n"             
    else
        printf "\nOut of ${target_questions} questions, you got "
        # have to do this now because we have added the pass option, as you can have none wrong/correct,
        # some correct/wrong, and some passes
        (( wrong > 0 )) && printf "${wrong} wrong and "
        (( correct > 0 )) && printf "${correct} correct "
        
        if (( pass == 0 )); then
            printf "with no passess at all in a time of ${quiz_duration} seconds.\n "
        elif (( pass == 1 )); then 
            printf "with 1 pass in a time of ${quiz_duration} seconds.\n "
        elif (( pass > 1 )); then
            printf "with ${pass} passes in a time of ${quiz_duration} seconds.\n"
        fi
    fi
fi

exit 

Das Quiz selbst in Aktion, mit zufällig ausgewählten Fragen:

Bildbeschreibung hier eingeben

verwandte Informationen