answer-php-assert_tpl.php

1 lines ASCII Unix (LF)
1
<?="<?php\n"?>
/**
 * PHP dbwebb class for asserting and auto correcting labs.
 *
 * It reads the answers from a json-file and use it
 * for checking with assertEqual().
 *
 */
class Dbwebb
{
    const PROMPT = ">>> ";

    /**
     * Constructor, init by reading json-file with answers.
     *
     */
    public function __construct()
    {
        $this->answers = json_decode(file_get_contents(".answer.json"), true);
        $this->correct = 0;
        $this->failed  = 0;
        $this->notDone = 0;
        $this->points  = 0;
        $this->jsonOptions = JSON_PRETTY_PRINT;

        if (php_sapi_name() == "cli") {
            $this->pre    = null;
            $this->preEnd = "\n";
            $this->colorBlue   = "\033[96m";
            $this->colorGreen  = "\033[92m";
            $this->colorYellow = "\033[93m";
            $this->colorStop   = "\033[0m";
        } else {
            $this->pre    = "<pre>";
            $this->preEnd = "</pre>";
            $this->colorBlue   = "<span style='color: #0296ff'>";
            $this->colorGreen  = "<span style='color: #006400'>";
            $this->colorYellow = "<span style='color: #FF8C00'>";
            $this->colorStop   = "</span>";

        }

        echo "{$this->pre}" . self::PROMPT . "Ready to begin.\n";
    }



    /**
     * Check if the answer is correct or not, present a hint if asked for.
     *
     * @param string  $question the id of the question
     * @param mixed   $answer   the answer to test
     * @param boolean $hint     true to show a hint, false to not (default)
     *
     * @return string representing if the answer was correct or not
     */
    public function assertEqual($question, $answer, $hint = false)
    {
        $status   = null;
        $noanswer = "Replace this text with the variable holding the answer.";
        $correct  = $this->answers["answers"][$question];

        if ($answer === $noanswer) {

            $status = self::PROMPT . $question . " NOT YET DONE.";
            $this->notDone += 1;

        } elseif ($answer === $correct) {

            $status = self::PROMPT . $question . " CORRECT. Well done!\n"
                . json_encode($answer, $this->jsonOptions);
            $this->correct += 1;
            $this->points += isset($this->answers["points"][$question])
                ? $this->answers["points"][$question]
                : 0;

        } else {

            $status = self::PROMPT . $question . " FAIL.\n" . self::PROMPT . "You said:\n"
                . json_encode($answer, $this->jsonOptions)
                . " (" . gettype($answer) . ")";
            $status .= $hint
                ? "\n" . self::PROMPT . "Hint:\n" . json_encode($correct) . " (" . gettype($correct) . ")"
                : "";
            $this->failed += 1;

        }

        return $status . "\n";
    }



    /**
     * Print a exit message with the result of all tests.
     *
     * @return boolean true if all answers are correct, else false
     */
    public function exitWithSummary()
    {
        $questions    = $this->answers["summary"]["questions"];
        $points       = $this->answers["summary"]["points"];
        $pass         = $this->answers["summary"]["pass"];
        $passDistinct = $this->answers["summary"]["passdistinct"];

        echo self::PROMPT
            . "Done with status {$questions}/{$this->correct}/{$this->failed}/"
            . "{$this->notDone} (Total/Correct/Failed/Not done).\n";

        $withDistinct = "";
        if (!is_null($passDistinct)) {
            $withDistinct = ", PASS W DISTINCTION=>{$passDistinct}p";
        }

        if ($pass) {
            echo self::PROMPT
                . "Points earned: {$this->points}p of {$points}p"
                . " (PASS=>{$pass}p{$withDistinct}).\n";
        }

        // Check if pass, pass w distinction or not
        $didPass = $this->correct == $questions;
        if ($pass) {
            $didPass = $this->points >= $pass;
        }

        $didPassDistinct = null;
        if ($passDistinct) {
            $didPassDistinct = $this->points >= $passDistinct;
        }

        if ($didPassDistinct) {
            echo $this->colorBlue
                . self::PROMPT
                . "Grade: PASS WITH DISTINCTION!!! :-D"
                . $this->colorStop;
        } elseif ($didPass) {
            echo $this->colorGreen
                . self::PROMPT
                . "Grade: PASS! :-)"
                . $this->colorStop;
        } else {
            echo $this->colorYellow
                . self::PROMPT
                . "Grade: Thou Did Not Pass. :-|"
                . $this->colorStop;
        }
        echo $this->preEnd;
        return $didPass ? 0 : 42;
    }
}