## DESCRIPTION
## Match each of the following stattest terms with their corresponding definitions.
## ENDDESCRIPTION
## KEYWORDS('stattest terms','definitions')
## DBsubject('Biostatistics')
## DBchapter('')
## DBsection('')
## Date('2026-07-12')
## Author('Neil R. Voss')
## Institution('Roosevelt University')

DOCUMENT();

loadMacros(
    'PGstandard.pl',
    'PGML.pl',
    'PGchoicemacros.pl',
    'parserPopUp.pl',
    'parserUtils.pl',
    'PGgraders.pl',
    'PGcourse.pl'
);
our @ALPHABET = ('A' .. 'Z');

# ================================
# Full matching data
# ================================
%match_data = (
  'critical value' => [
    'found in a table for given degrees of freedom and <span style="color: #a719db; font-weight:700;">level of significance, &alpha;</span>',
    'the boundary for how extreme a <span style="color: #00775f; font-weight:700;">test statistic</span> must be to <span style="color: #d40000; font-weight:700;">reject</span>the <span style="color: #007576; font-weight:700;">null hypothesis, H<sub>0</sub></span>',
    'the cutoff used to compare against the observed <span style="color: #00775f; font-weight:700;">test statistic</span>',
  ],
  'test statistic' => [
    'a function of the data computed to test the <span style="color: #007576; font-weight:700;">null hypothesis, H<sub>0</sub></span>',
    'a function of the data designed to measure agreement or disagreement with the null hypothesis',
    'if this value is large in the direction favoring the <span style="color: #b74300; font-weight:700;">alternative hypothesis, H<sub>a</sub></span>, there is stronger evidence against the <span style="color: #007576; font-weight:700;">null hypothesis, H<sub>0</sub></span>',
    'the more extreme this value is under the <span style="color: #007576; font-weight:700;">null hypothesis, H<sub>0</sub></span>, the smaller the <span style="color: #c80085; font-weight:700;">p-value</span>',
  ],
  'level of significance, &alpha;' => [
    'the probability cutoff used to decide whether to <span style="color: #d40000; font-weight:700;">reject</span>the <span style="color: #007576; font-weight:700;">null hypothesis, H<sub>0</sub></span>',
    'the probability cutoff that limits how often we mistakenly <span style="color: #d40000; font-weight:700;">reject</span>a <span style="color: #127663; font-weight:700;">TRUE</span><span style="color: #007576; font-weight:700;">null hypothesis, H<sub>0</sub></span> (later called a Type I error).',
    'the cutoff for how small a <span style="color: #c80085; font-weight:700;">p-value</span> must be to <span style="color: #d40000; font-weight:700;">reject</span>the <span style="color: #007576; font-weight:700;">null hypothesis, H<sub>0</sub></span>',
    'standard cutoff probability used to determine statistical significance',
    'biologists often use a probability of 0.05 (5%) for this value',
  ],
  'p-value' => [
    'the probability, under the <span style="color: #007576; font-weight:700;">null hypothesis, H<sub>0</sub></span>, of obtaining a result at least as extreme as the one observed',
    'if this value is small, there is stronger evidence in favor of the <span style="color: #b74300; font-weight:700;">alternative hypothesis, H<sub>a</sub></span>',
    'if this value is small, it suggests that the observed data are NOT consistent with the <span style="color: #007576; font-weight:700;">null hypothesis, H<sub>0</sub></span>',
    'smaller values typically correspond to more extreme <span style="color: #00775f; font-weight:700;">test statistic</span> values',
  ],
  'null hypothesis, H<sub>0</sub>' => [
    'the hypothesis we attempt to find evidence against in a stattest',
    'the hypothesis we want to <span style="color: #d40000; font-weight:700;">reject</span>in a stattest',
    'this hypothesis defines the distribution used for comparison in the test',
    'defines the distribution used for comparison in the test',
    'defines the reference distribution used for comparison',
  ],
  'alternative hypothesis, H<sub>a</sub>' => [
    'the hypothesis we aim to support indirectly by rejecting another hypothesis',
    'this hypothesis can sometimes be <span style="color: #127663; font-weight:700;">TRUE</span>even when the test fails to detect it (later called a Type II error)',
    'can be <span style="color: #127663; font-weight:700;">TRUE</span>even if the test fails to detect it (later called a Type II error)',
    'this hypothesis represents the possibility that the observed effect is real and NOT random',
    'this hypothesis represents the possibility that the observed effect is NOT due to random chance',
    'represents the possibility that an observed effect or relationship is real and NOT random',
    'represents the possibility that an observed effect or relationship is NOT due to random chance',
  ],
  'degrees of freedom' => [
    'a parameter based on sample size and estimated parameters or constraints',
    'a parameter determined by sample size and the number of parameters',
    'based on how many independent pieces of information are available',
    'the count of values free to vary once constraints are applied',
    'depends on sample size and restrictions from estimated parameters',
  ],
);

# -------------------------------
# Select N random keys
# -------------------------------
my $n = 5;
@all_keys = PGsort(sub { $_[0] lt $_[1] }, keys %match_data);
my $local_seed = (defined($problemSeed) && $problemSeed ne '') ? $problemSeed : 1;
my $local_random = new PGrandom($local_seed);

my @indices = (0 .. $#all_keys);
my @shuffled = ();
while (@indices) {
  my $pick = $local_random->random(0, $#indices, 1);
  push @shuffled, splice(@indices, $pick, 1);
}
my @selected_keys = @all_keys[@shuffled[0..$n-1]];

# -------------------------------
# Build question/answer pairs
# -------------------------------
# Each entry: [prompt, choice]
@q_and_a = ();
foreach my $key (@selected_keys) {
  my $values_ref = $match_data{$key};
  my $i = $local_random->random(0, $#$values_ref, 1);
  my $value = $values_ref->[$i];
  push @q_and_a, [ $value, $key ];
}

# -------------------------------
# Randomize the questions
# -------------------------------
my @q_indices = (0 .. $#q_and_a);
my @q_shuffled = ();
while (@q_indices) {
  my $pick = $local_random->random(0, $#q_indices, 1);
  push @q_shuffled, $q_and_a[splice(@q_indices, $pick, 1)];
}
@q_and_a = @q_shuffled;

# -------------------------------
# Sort the choices alphabetically
# -------------------------------
@answers = ();
push(@answers, (map { $_->[1] } @q_and_a));
@answers_sorted = PGsort(sub { $_[0] lt $_[1] }, @answers);

# -------------------------------
# HTML-safe answer labels
# -------------------------------
%answer_html = (
  'critical value' => '<span style="color: #003fff; font-weight:700;">critical value</span>',
  'test statistic' => '<span style="color: #00775f; font-weight:700;">test statistic</span>',
  'level of significance, &alpha;' => '<span style="color: #a719db; font-weight:700;">level of significance, &alpha;</span>',
  'p-value' => '<span style="color: #c80085; font-weight:700;">p-value</span>',
  'null hypothesis, H<sub>0</sub>' => '<span style="color: #007576; font-weight:700;">null hypothesis, H<sub>0</sub></span>',
  'alternative hypothesis, H<sub>a</sub>' => '<span style="color: #b74300; font-weight:700;">alternative hypothesis, H<sub>a</sub></span>',
  'degrees of freedom' => '<span style="color: #6c6c00; font-weight:700;">degrees of freedom</span>',
);

@answers_sorted_html = map { $answer_html{$_} || $_ } @answers_sorted;

# -------------------------------
# Create answer index lookup
# -------------------------------
our %answer_index;
for (my $i = 0; $i <= $#answers_sorted; $i++) {
  $answer_index{$answers_sorted[$i]} = $i;
}

# -------------------------------
# PopUp/DropDown compatibility
# -------------------------------
sub make_popup {
  return defined &DropDown ? DropDown(@_) : PopUp(@_);
}

# -------------------------------
# Create popup objects (blank default)
# -------------------------------
my @answer_letters = @ALPHABET[0 .. $#answers_sorted];
my @answer_letters_with_blank = ('', @answer_letters);
@answer_dropdowns =
  map { make_popup([ @answer_letters_with_blank ], $answer_index{$q_and_a[$_][1]} + 1 ) }
  0 .. $#q_and_a;

# -------------------------------
# Render the question
# -------------------------------
HEADER_TEXT(<<END_STYLE);
<style>
.pgml-bold { font-weight: 700; }
.two-column {
    display: flex;
	flex-wrap: wrap;
	gap: 2rem;
	align-items: center;
	justify-content: space-evenly;
}
</style>
END_STYLE

$question_text = 'Match each of the following statistical test terms with their corresponding definitions.';
$note_text = 'Note: Each choice will be used exactly once.';

BEGIN_PGML
[$question_text]*
[$note_text]*

[@ MODES(HTML => '<div class="two-column"><div>') @]*
[@ join(
    "\n\n",
    map {
        '[_]{$answer_dropdowns[' . $_ . ']} '
            . '*' . ($_ + 1) . '.* '
            . '[$q_and_a[' . $_ . '][0]]*'
    } 0 .. $#q_and_a
) @]**
[@ MODES(HTML => '</div><div class="right-col">') @]*
[@ join(
    "\n\n",
    map {
        chr(65 + $_) . '\\.' . ' ' . '[$answers_sorted_html[' . $_ . ']]*'
    } 0 .. $#answers_sorted
) @]**
[@ MODES(HTML => '</div></div>') @]*
END_PGML

# -------------------------------
# Dynamic Partial Credit Based on $n
# -------------------------------
$showPartialCorrectAnswers = 0;
my @thresholds;
my @scores;
for (my $i = 1; $i <= $n; $i++) {
  push @thresholds, $i;
  push @scores, sprintf("%.2f", $i / $n);
}

install_problem_grader(~~&custom_problem_grader_fluid);
$ENV{grader_numright} = [@thresholds];
$ENV{grader_scores}   = [@scores];
$ENV{grader_message} = 'You can earn partial credit.';

# -------------------------------
# Solution
# -------------------------------
$answer_list = join(', ', map { ($_ + 1) . '-' . $ALPHABET[$answer_index{$q_and_a[$_][1]}] } 0 .. $#q_and_a);
BEGIN_PGML_SOLUTION
The correct answers are: [$answer_list].
END_PGML_SOLUTION

ENDDOCUMENT();

