diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem1.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem1.pg
new file mode 100644
index 0000000000..6216cfa259
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem1.pg
@@ -0,0 +1,283 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Sample Spaces & Events (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Sample Spaces and Events)
+## Level(2)
+## KEYWORDS('probability','sample space','event','random experiment','trial')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "contextString.pl",
+ "scaffold.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1; # set to 0 to hide/remove the rating step
+
+# =======================================================
+# Evaluators for set-entry (order doesn't matter)
+# =======================================================
+Context("String");
+
+# Critical: allow comma-separated lists of strings to be parsed as a List
+Context()->operators->redefine(',', using => ',');
+
+# Allowed outcomes
+Context()->strings->add(
+ "WW" => {},
+ "WB" => {},
+ "BW" => {},
+ "BB" => {},
+);
+
+$correctS = List( String("WW"), String("WB"), String("BW"), String("BB") );
+$correctE = List( String("WB"), String("BW") );
+
+# =======================================================
+# Rating evaluator (integer 1–5)
+# =======================================================
+Context("Numeric");
+$cmp_rating = Real(1)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return ($v >= 1 && $v <= 5) ? 1 : 0;
+ }
+);
+
+# Switch back to String for the rest of the problem display/inputs
+Context("String");
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ hardcopy_is_open => "always",
+);
+
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_TEXT
+A bag contains 12 white marbles and 8 black marbles.
+$PAR
+You will draw two marbles, one after the other, with replacement.
+END_TEXT
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Build the definitions");
+BEGIN_TEXT
+For each blank, choose the best option by typing its letter (A, B, or C).
+$PAR
+
+Build the definition of a random experiment:
+$BR
+A random experiment in probability is a (1) ____ procedure or process that can be (2) ____,
+has (3) ____ possible outcomes, but whose specific result cannot be predicted with (4) ____ beforehand,
+though the set of all possible outcomes (the (5) ____) is known.
+$PAR
+
+(1)
+$BR
+A) random B) well-defined C) unclear
+$BR
+Answer: \{ ans_rule(2) \}
+$PAR
+
+(2)
+$BR
+A) ignored B) repeated C) guessed
+$BR
+Answer: \{ ans_rule(2) \}
+$PAR
+
+(3)
+$BR
+A) one B) none C) multiple
+$BR
+Answer: \{ ans_rule(2) \}
+$PAR
+
+(4)
+$BR
+A) certainty B) luck C) noise
+$BR
+Answer: \{ ans_rule(2) \}
+$PAR
+
+(5)
+$BR
+A) trial B) sample space C) event
+$BR
+Answer: \{ ans_rule(2) \}
+$PAR
+
+Each performance of the experiment is called a (6) ____.
+$BR
+A) event B) trial C) outcome
+$BR
+Answer: \{ ans_rule(2) \}
+$PAR
+
+The sample space is the (7) ____ of all possible outcomes.
+$BR
+A) set B) formula C) number
+$BR
+Answer: \{ ans_rule(2) \}
+$PAR
+
+An event is a (8) ____ of the sample space.
+$BR
+A) average B) equation C) subset
+$BR
+Answer: \{ ans_rule(2) \}
+$PAR
+
+We say an event (9) ____ when the observed outcome is in that event.
+$BR
+A) occurred B) repeated C) vanished
+$BR
+Answer: \{ ans_rule(2) \}
+END_TEXT
+
+ANS( str_cmp("B") ); # (1) well-defined
+ANS( str_cmp("B") ); # (2) repeated
+ANS( str_cmp("C") ); # (3) multiple
+ANS( str_cmp("A") ); # (4) certainty
+ANS( str_cmp("B") ); # (5) sample space
+ANS( str_cmp("B") ); # (6) trial
+ANS( str_cmp("A") ); # (7) set
+ANS( str_cmp("C") ); # (8) subset
+ANS( str_cmp("A") ); # (9) occurred
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Identify the random experiment");
+BEGIN_TEXT
+Which option correctly describes the random experiment for this situation?
+$PAR
+A) Draw a marble, replace it, draw again, and record the ordered pair of colors (first, second).
+$BR
+B) Draw two marbles without replacement and record only the final color.
+$BR
+C) Shake the bag and predict the color without drawing.
+$PAR
+Answer (A/B/C): \{ ans_rule(2) \}
+END_TEXT
+
+ANS( str_cmp("A") );
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Construct the sample space");
+BEGIN_TEXT
+We will use W for white and B for black.
+$PAR
+Example: First draw is white and second draw is black is written as WB.
+$PAR
+Enter the sample space outcomes as a comma-separated list. Order does not matter.
+$PAR
+S = { \{ ans_rule(30) \} }
+END_TEXT
+
+ANS( $correctS->cmp(ignoreOrder => 1) );
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Define an event");
+BEGIN_TEXT
+Let E be the event: "Exactly one black marble is drawn."
+$PAR
+Enter the outcomes in E as a comma-separated list. Order does not matter.
+$PAR
+E = { \{ ans_rule(20) \} }
+END_TEXT
+
+ANS( $correctE->cmp(ignoreOrder => 1) );
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Which event occurred?");
+BEGIN_TEXT
+Suppose the observed outcome is WB.
+$PAR
+Which one of the events below occurred?
+$PAR
+
+A) At least one white marble was drawn.
+$BR
+Set form: { WW, WB, BW }
+$PAR
+
+B) Both marbles drawn were black.
+$BR
+Set form: { BB }
+$PAR
+
+C) Both marbles drawn were white.
+$BR
+Set form: { WW }
+$PAR
+
+D) The first draw was black.
+$BR
+Set form: { BW, BB }
+$PAR
+
+Answer (A/B/C/D): \{ ans_rule(2) \}
+END_TEXT
+
+ANS( str_cmp("A") );
+
+Section::End();
+
+# ----------------------------------------------------------------
+# PILOT RATING (ACTIVE)
+# ----------------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+
+ Section::Begin("Feedback");
+ BEGIN_TEXT
+Rate the usefulness of this guided problem on a scale from 1 to 5.
+$PAR
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+$BR
+Note: Consider using the Email Instructor button below to suggest improvements.
+$PAR
+Rating: \{ ans_rule(6) \}
+END_TEXT
+
+ Context("Numeric");
+ ANS($cmp_rating);
+ Context("String");
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem10.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem10.pg
new file mode 100644
index 0000000000..5e354be032
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem10.pg
@@ -0,0 +1,359 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Union & Intersection (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Union and Intersection)
+## Level(2)
+## KEYWORDS('probability','event','intersection','union','two dice')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "contextString.pl",
+ "scaffold.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# IMAGES (per our BP rule):
+# Put these image files in the SAME folder as this .pg file (or a
+# relative subfolder), then use image("file.jpg", ...).
+# Required images for this problem:
+# venn_intersection.jpg
+# venn_union.jpg
+# ----------------------------------------------------------------
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Sample space table (HTML) for outcomes 11..66
+# =======================================================
+my @nums = (1..6);
+
+our $table_html = '
';
+$table_html .= '| Die 1 / Die 2 | ';
+for my $j (@nums) { $table_html .= "$j | "; }
+$table_html .= '
';
+
+for my $i (@nums) {
+ $table_html .= "| $i | ";
+ for my $j (@nums) {
+ my $code = "$i$j";
+ $table_html .= "$code | ";
+ }
+ $table_html .= "
";
+}
+$table_html .= "
";
+
+# =======================================================
+# Set-entry context for outcomes like 46, 55, 66
+# =======================================================
+my $ctxSet = Context("String");
+$ctxSet->operators->redefine(',', using => ',');
+
+my %allowed = ();
+for my $i (@nums) {
+ for my $j (@nums) {
+ $allowed{"$i$j"} = {};
+ }
+}
+$ctxSet->strings->add(%allowed);
+
+# =======================================================
+# NEW PROBLEM (Option 2)
+# A: doubles
+# B: sum is at least 9
+# =======================================================
+my @A = qw(11 22 33 44 55 66);
+
+my @B = qw(36 45 54 63 46 55 64 56 65 66);
+
+my @AiB = qw(55 66);
+
+my @AuB = qw(11 22 33 44 55 66 36 45 54 63 46 64 56 65);
+
+# Set comparators (order doesn't matter)
+my $cmp_A_set = List(map { String($_) } @A)->cmp(ignoreOrder => 1);
+my $cmp_B_set = List(map { String($_) } @B)->cmp(ignoreOrder => 1);
+my $cmp_AiB_set = List(map { String($_) } @AiB)->cmp(ignoreOrder => 1);
+my $cmp_AuB_set = List(map { String($_) } @AuB)->cmp(ignoreOrder => 1);
+
+# =======================================================
+# Numeric comparators
+# =======================================================
+Context("Numeric");
+
+my $cmp_nS = Real(36)->cmp();
+
+my $cmp_PA = Real(1/6)->cmp( tolType => "absolute", tolerance => 0.001 ); # 6/36
+my $cmp_PB = Real(5/18)->cmp( tolType => "absolute", tolerance => 0.001 ); # 10/36
+my $cmp_PAiB = Real(1/18)->cmp( tolType => "absolute", tolerance => 0.001 ); # 2/36
+my $cmp_PAuB = Real(7/18)->cmp( tolType => "absolute", tolerance => 0.001 ); # 14/36
+
+my $cmp_add_rhs = Real(7/18)->cmp(tolType => "absolute", tolerance => 0.001 );
+my $cmp_zero = Real(0)->cmp( tolType => "absolute", tolerance => 0.001 );
+
+my $cmp_rating = Real(1)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return ($v >= 1 && $v <= 5) ? 1 : 0;
+ }
+);
+
+# Back to set context for set-entry blanks
+Context($ctxSet);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ hardcopy_is_open => "always",
+);
+
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+
+BEGIN_TEXT
+Two fair six-sided dice are rolled at the same time.
+We record the ordered pair (first die, second die) using a two-digit code.
+For example, 54 means (first die = 5, second die = 4).
+$PAR
+Here is the sample space:
+$PAR
+\{ $table_html \}
+$PAR
+How many outcomes are in the sample space?
+$BR
+\{ ans_rule(5) \}
+END_TEXT
+
+Context("Numeric");
+ANS($cmp_nS);
+Context($ctxSet);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Define the events");
+
+BEGIN_TEXT
+Define these two events:
+$PAR
+\(A\): The roll is a double. (Both dice show the same number.)
+$BR
+\(B\): The sum of the two dice is at least 9.
+$PAR
+
+Step 1 (List event \(A\)).
+Comma-separated, order doesn't matter. Do not type braces.
+$BR
+\(A\) = { \{ ans_rule(70) \} }
+$PAR
+
+Step 2 (Find P(\(A\))).
+Because all 36 outcomes are equally likely:
+$BR
+P(\(A\)) = (number of outcomes in \(A\)) / 36
+$BR
+Enter P(\(A\)) as a fraction or a decimal:
+$BR
+P(\(A\)) = \{ ans_rule(12) \}
+$PAR
+
+Step 3 (List event \(B\)).
+Comma-separated, order doesn't matter. Do not type braces.
+$BR
+\(B\) = { \{ ans_rule(90) \} }
+$PAR
+
+Step 4 (Find P(\(B\))).
+Because all 36 outcomes are equally likely:
+$BR
+P(\(B\)) = (number of outcomes in \(B\)) / 36
+$BR
+Enter P(\(B\)) as a fraction or a decimal:
+$BR
+P(\(B\)) = \{ ans_rule(12) \}
+END_TEXT
+
+Context($ctxSet);
+ANS($cmp_A_set);
+
+Context("Numeric");
+ANS($cmp_PA);
+
+Context($ctxSet);
+ANS($cmp_B_set);
+
+Context("Numeric");
+ANS($cmp_PB);
+
+Context($ctxSet);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Intersection");
+
+BEGIN_TEXT
+Intersection
+$PAR
+The intersection of \(A\) and \(B\), written \(A \cap B\), is the set of outcomes that are in both events.
+In words, it corresponds to combining the descriptions using and.
+$PAR
+\{ image("venn_intersection.jpg", width => 300) \}
+$PAR
+
+Step 1 (Build \(A \cap B\)).
+List all outcomes (two-digit codes) that satisfy:
+$BR
+"the roll is a double" and "the sum is at least 9".
+$PAR
+Comma-separated, order doesn't matter. Do not type braces.
+$BR
+\(A \cap B\) = { \{ ans_rule(50) \} }
+$PAR
+
+Step 2 (Probability of the intersection).
+Because all 36 outcomes are equally likely:
+$BR
+P(\(A \cap B\)) = (number of outcomes in \(A \cap B\)) / 36
+$PAR
+Enter P(\(A \cap B\)) as a fraction or a decimal:
+$BR
+P(\(A \cap B\)) = \{ ans_rule(12) \}
+END_TEXT
+
+Context($ctxSet);
+ANS($cmp_AiB_set);
+
+Context("Numeric");
+ANS($cmp_PAiB);
+
+Context($ctxSet);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Union (Final Answer)");
+
+BEGIN_TEXT
+Union
+$PAR
+The union of \(A\) and \(B\), written \(A \cup B\), is the set of outcomes that are in at least one of the events.
+In words, it corresponds to combining the descriptions using or (including “both”).
+$PAR
+\{ image("venn_union.jpg", width => 300) \}
+$PAR
+
+Step 1 (Build \(A \cup B\)).
+List all outcomes (two-digit codes) that satisfy:
+$BR
+"the roll is a double" or "the sum is at least 9" (or both).
+$PAR
+Comma-separated, order doesn't matter. Do not type braces.
+$BR
+\(A \cup B\) = { \{ ans_rule(120) \} }
+$PAR
+
+Step 2 (Final Answer: Probability of the union).
+Because all 36 outcomes are equally likely:
+$BR
+P(\(A \cup B\)) = (number of outcomes in \(A \cup B\)) / 36
+$PAR
+Enter P(\(A \cup B\)) as a fraction or a decimal:
+$BR
+P(\(A \cup B\)) = \{ ans_rule(12) \}
+END_TEXT
+
+Context($ctxSet);
+ANS($cmp_AuB_set);
+
+Context("Numeric");
+ANS($cmp_PAuB);
+
+Context($ctxSet);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Addition Rule of Probability (Verify)");
+
+BEGIN_TEXT
+Addition Rule of Probability
+$PAR
+For any two events \(A\) and \(B\):
+$BR
+P(\(A \cup B\)) = P(\(A\)) + P(\(B\)) - P(\(A \cap B\))
+$PAR
+
+Step 1.
+Compute the right-hand side:
+$BR
+P(\(A\)) + P(\(B\)) - P(\(A \cap B\)) = \{ ans_rule(12) \}
+$PAR
+
+Step 2 (Verify).
+Now compute:
+$BR
+P(\(A \cup B\)) - (P(\(A\)) - P(\(B\)) + P(\(A \cap B\))) = \{ ans_rule(12) \}
+$PAR
+If the rule checks out, that last answer should be 0 (up to rounding).
+END_TEXT
+
+Context("Numeric");
+ANS($cmp_add_rhs);
+ANS($cmp_zero);
+
+Context($ctxSet);
+
+Section::End();
+
+# ----------------------------------------------------------------
+# PILOT RATING (ACTIVE)
+# ----------------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+
+ Section::Begin("Feedback");
+ BEGIN_TEXT
+Rate the usefulness of this guided problem on a scale from 1 to 5.
+$PAR
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+$BR
+Note: Consider using the Email Instructor button below to suggest improvements.
+$PAR
+Rating:
+$BR
+\{ ans_rule(6) \}
+END_TEXT
+
+ Context("Numeric");
+ ANS($cmp_rating);
+ Context($ctxSet);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem11.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem11.pg
new file mode 100644
index 0000000000..55f8907dba
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem11.pg
@@ -0,0 +1,384 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Mutually Exclusive Events (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Mutually Exclusive Events)
+## Level(2)
+## KEYWORDS('probability','event','mutually exclusive','intersection','union','two dice','4-sided dice')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "contextString.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# IMAGES (per BP rule):
+# Put image files in the SAME folder as this .pg file (or a relative
+# subfolder), then insert them with image() inside BEGIN_TEXT.
+# Required image for this problem (optional but used here):
+# venn_union.jpg
+# ----------------------------------------------------------------
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Sample space table (HTML) for outcomes 11..44 (4-sided dice)
+# =======================================================
+my @nums = (1..4);
+
+our $table_html = '';
+$table_html .= '| Die 1 / Die 2 | ';
+for my $j (@nums) { $table_html .= "$j | "; }
+$table_html .= '
';
+
+for my $i (@nums) {
+ $table_html .= "| $i | ";
+ for my $j (@nums) {
+ my $code = "$i$j";
+ $table_html .= "$code | ";
+ }
+ $table_html .= "
";
+}
+$table_html .= "
";
+
+# =======================================================
+# Set context: allow comma-separated outcomes + "none"
+# =======================================================
+my $ctxSet = Context("String");
+$ctxSet->operators->redefine(',', using => ',');
+
+my %allowed = ();
+for my $i (@nums) {
+ for my $j (@nums) {
+ $allowed{"$i$j"} = {};
+ }
+}
+$allowed{"none"} = { caseSensitive => 0 };
+$ctxSet->strings->add(%allowed);
+
+# =======================================================
+# Events
+# A: double
+# B: sum is an odd prime (3, 5, or 7)
+# =======================================================
+my @A = qw(11 22 33 44);
+my @B = qw(12 21 14 23 32 41 34 43);
+my @AuB = qw(11 22 33 44 12 21 14 23 32 41 34 43);
+
+# Build evaluators while in String context
+Context($ctxSet);
+
+$cmp_A_set = List(map { String($_) } @A)->cmp(ignoreOrder => 1);
+$cmp_B_set = List(map { String($_) } @B)->cmp(ignoreOrder => 1);
+$cmp_AiB = String("none")->cmp(); # intersection is empty; students type "none"
+$cmp_AuB_set = List(map { String($_) } @AuB)->cmp(ignoreOrder => 1);
+
+# Numeric evaluators
+Context("Numeric");
+
+$cmp_nS = Real(16)->cmp();
+
+$cmp_PA = Real(1/4)->cmp( tolType => "absolute", tolerance => 0.001 );
+$cmp_PB = Real(1/2)->cmp( tolType => "absolute", tolerance => 0.001 );
+$cmp_PAiB = Real(0)->cmp( tolType => "absolute", tolerance => 0.001 );
+$cmp_PAuB = Real(3/4)->cmp( tolType => "absolute", tolerance => 0.001 );
+
+$cmp_sum_PA_PB = Real(3/4)->cmp( tolType => "absolute", tolerance => 0.001 );
+$cmp_zero = Real(0)->cmp( tolType => "absolute", tolerance => 0.001 );
+
+# =======================================================
+# Quiz Time (Radio Buttons): Which statement is FALSE?
+# (Use simple MathJax in option strings; avoid nested P(\(...\)) patterns.)
+# =======================================================
+$rb_false_me = RadioButtons(
+ [
+ '\(P(A \cap B)=0\).',
+ 'If \(A\) happens, then \(B\) cannot happen (and vice versa).',
+ '\(P(A \cup B)=P(A)+P(B)\).',
+ 'Mutually exclusive events are always independent.',
+ '\(A \cap B\) is an empty set.',
+ ],
+ 3, # 0-based index => D is the false statement
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Rating checker (integer 1..5)
+# =======================================================
+$rating = Real(3); # placeholder only
+
+$rating_cmp = $rating->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ if (!defined($student)) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ my $val;
+ eval { $val = $student->value; };
+ if (!defined($val)) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ my $ival = int($val);
+ if (abs($val - $ival) > 1e-12) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ if ($ival < 1 || $ival > 5) {
+ $ansHash->{ans_message} = "Your rating must be 1, 2, 3, 4, or 5.";
+ return 0;
+ }
+
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ hardcopy_is_open => "always",
+);
+
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+
+BEGIN_TEXT
+Two fair four-sided dice are rolled at the same time.
+We record the ordered pair (first die, second die) using a two-digit code.
+For example, 34 means (first die = 3, second die = 4).
+$PAR
+Here is the sample space:
+$PAR
+\{ $table_html \}
+$PAR
+How many outcomes are in the sample space?
+$BR
+\{ ans_rule(5) \}
+END_TEXT
+
+Context("Numeric");
+ANS($cmp_nS);
+Context($ctxSet);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Define the events");
+
+BEGIN_TEXT
+Define these two events:
+$PAR
+\(A\): The roll is a double. (Both dice show the same number.)
+$BR
+\(B\): The sum of the two dice is an odd prime.
+$BR
+(So the sum is 3, 5, or 7.)
+$PAR
+
+Step 1 (List event \(A\)).
+Comma-separated, order doesn't matter. Do not type braces.
+$BR
+\(A\) = { \{ ans_rule(70) \} }
+$PAR
+
+Step 2 (Find \(P(A)\)).
+Enter \(P(A)\) as a fraction or a decimal:
+$BR
+\(P(A)\) = \{ ans_rule(12) \}
+$PAR
+
+Step 3 (List event \(B\)).
+Comma-separated, order doesn't matter. Do not type braces.
+$BR
+\(B\) = { \{ ans_rule(90) \} }
+$PAR
+
+Step 4 (Find \(P(B)\)).
+Enter \(P(B)\) as a fraction or a decimal:
+$BR
+\(P(B)\) = \{ ans_rule(12) \}
+END_TEXT
+
+Context($ctxSet);
+ANS($cmp_A_set);
+
+Context("Numeric");
+ANS($cmp_PA);
+
+Context($ctxSet);
+ANS($cmp_B_set);
+
+Context("Numeric");
+ANS($cmp_PB);
+
+Context($ctxSet);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Intersection and Mutually Exclusive");
+
+BEGIN_TEXT
+Definition
+$PAR
+Events \(A\) and \(B\) are mutually exclusive if they have no elements in common.
+$PAR
+\{ image("venn_mutually_exclusive.png", width => 400) \}
+$PAR
+Step 1 (Build the intersection).
+List all outcomes (two-digit codes) that are in both events.
+$BR
+If there is no shared outcome, type none.
+$PAR
+\(A \cap B\) = { \{ ans_rule(40) \} }
+$PAR
+
+Step 2 (Probability of the intersection).
+Enter \(P(A \cap B)\) as a fraction or a decimal:
+$BR
+\(P(A \cap B)\) = \{ ans_rule(12) \}
+END_TEXT
+
+Context($ctxSet);
+ANS($cmp_AiB);
+
+Context("Numeric");
+ANS($cmp_PAiB);
+
+Context($ctxSet);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Probability Rule and Quiz Time");
+
+BEGIN_TEXT
+Probability Rule for Mutually Exclusive Events
+$PAR
+Events \(A\) and \(B\) are mutually exclusive if and only if \(P(A \cap B)=0\).
+$PAR
+Quiz Time
+$BR
+Which statement is false for mutually exclusive events \(A\) and \(B\)?
+$PAR
+\{ $rb_false_me->buttons \}
+END_TEXT
+
+ANS($rb_false_me->cmp());
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Union (Final Answer)");
+
+BEGIN_TEXT
+Union
+$PAR
+The union of \(A\) and \(B\), written \(A \cup B\), is the set of outcomes that are in at least one of the events.
+$PAR
+Step 1 (Build the union).
+Comma-separated, order doesn't matter. Do not type braces.
+$BR
+\(A \cup B\) = { \{ ans_rule(120) \} }
+$PAR
+
+Step 2 (Final Answer).
+Enter \(P(A \cup B)\) as a fraction or a decimal:
+$BR
+\(P(A \cup B)\) = \{ ans_rule(12) \}
+END_TEXT
+
+Context($ctxSet);
+ANS($cmp_AuB_set);
+
+Context("Numeric");
+ANS($cmp_PAuB);
+
+Context($ctxSet);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Mutually Exclusive Union Rule (Verify)");
+
+BEGIN_TEXT
+If \(A\) and \(B\) are mutually exclusive, then there is no overlap to subtract.
+So the Additive Rule of Probability:
+$BR
+\(P(A \cup B)=P(A)+P(B)-P(A \cap B)\)
+$BR
+reduces to:
+$BR
+\(P(A \cup B)=P(A)+P(B)\)
+$PAR
+
+Step 1. Compute \(P(A)+P(B)\):
+$BR
+\(P(A)+P(B)\) = \{ ans_rule(12) \}
+$PAR
+
+Step 2 (Verify). Compute:
+$BR
+\(P(A \cup B) - (P(A)+P(B))\) = \{ ans_rule(12) \}
+$PAR
+If your reasoning is correct, that last answer should be 0 (up to rounding).
+END_TEXT
+
+Context("Numeric");
+ANS($cmp_sum_PA_PB);
+ANS($cmp_zero);
+
+Context($ctxSet);
+
+Section::End();
+
+# ----------------------------------------------------------------
+# PILOT RATING
+# ----------------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+
+ Section::Begin("Feedback");
+ BEGIN_PGML
+Rate the usefulness of this guided problem on a scale from 1 to 5.
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating: [__]{$rating_cmp}
+END_PGML
+ Section::End();
+
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem12.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem12.pg
new file mode 100644
index 0000000000..5ed01c2808
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem12.pg
@@ -0,0 +1,338 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — General Additive Rule (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Addition Rule)
+## Level(2)
+## KEYWORDS('probability','event','union','intersection','addition rule','Venn diagram','language')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "parserRadioButtons.pl",
+ "answerHints.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# IMAGES (same folder as this .pg, per your server rule)
+# venn_3.png (A shades E, B shades E union F, C shades E intersection F)
+# venn_2.png (English Only / French Only; intersection is pure white)
+# ----------------------------------------------------------------
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+$showPartialCorrectAnswers = 1;
+
+Context("Numeric");
+
+# -------------------------------------------------------
+# Given probabilities (decimals)
+# -------------------------------------------------------
+$P_E = Real(0.56);
+$P_EuF = Real(0.78);
+$P_EiF = Real(0.23);
+
+# Derived
+$P_F = Real(0.78 - 0.56 + 0.23); # 0.45
+$P_Eonly = Real(0.56 - 0.23); # 0.33
+$P_Fonly = Real((0.78 - 0.56 + 0.23) - 0.23); # 0.22
+
+# -------------------------------------------------------
+# Numeric comparators (with AnswerHints; hints stay enabled)
+# -------------------------------------------------------
+$cmp_PE = $P_E->cmp->withPostFilter(AnswerHints(
+ Real(56) => "Use decimals (example: 56% = 0.56).",
+));
+
+$cmp_PEuF = $P_EuF->cmp->withPostFilter(AnswerHints(
+ Real(78) => "Use decimals (example: 78% = 0.78).",
+));
+
+$cmp_PEiF = $P_EiF->cmp->withPostFilter(AnswerHints(
+ Real(23) => "Use decimals (example: 23% = 0.23).",
+));
+
+$cmp_PF = $P_F->cmp->withPostFilter(AnswerHints(
+ Real(0.79) => "General additive rule: subtract the intersection once.",
+ Real(0.33) => "That looks like English-only. Here we want P(F).",
+));
+
+$cmp_Eonly = $P_Eonly->cmp->withPostFilter(AnswerHints(
+ Real(0.23) => "English-only is NOT the overlap. Subtract the overlap from P(English).",
+));
+
+$cmp_Fonly = $P_Fonly->cmp->withPostFilter(AnswerHints(
+ Real(0.45) => "That is P(F). French-only subtracts the overlap.",
+));
+
+$cmp_union_check = $P_EuF->cmp->withPostFilter(AnswerHints(
+ Real(1) => "If you got 1, you counted everyone. Use only + only + both.",
+));
+
+# -------------------------------------------------------
+# Radio buttons (PGML style: [_]{$rb})
+# -------------------------------------------------------
+$rb_E = RadioButtons(
+ [
+ 'Diagram A',
+ 'Diagram B',
+ 'Diagram C',
+ ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+$rb_EuF = RadioButtons(
+ [
+ 'Diagram A',
+ 'Diagram B',
+ 'Diagram C',
+ ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+$rb_EiF = RadioButtons(
+ [
+ 'Diagram A',
+ 'Diagram B',
+ 'Diagram C',
+ ],
+ 2,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+$rb_add_rule = RadioButtons(
+ [
+ '\(P(E \cup F)=P(E)+P(F)\)',
+ '\(P(E \cup F)=P(E)+P(F)-P(E \cap F)\)',
+ '\(P(E \cap F)=P(E)+P(F)\)',
+ '\(P(F)=P(E \cup F)-P(E)-P(E \cap F)\)',
+ '\(P(E \cup F)=P(E)-P(F)+P(E \cap F)\)',
+ ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# -------------------------------------------------------
+# Rating checker (integer 1..5)
+# -------------------------------------------------------
+$rating = Real(3); # placeholder only
+
+$rating_cmp = $rating->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ if (!defined($student)) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ my $val;
+ eval { $val = $student->value; };
+ if (!defined($val)) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ my $ival = int($val);
+ if (abs($val - $ival) > 1e-12) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ if ($ival < 1 || $ival > 5) {
+ $ansHash->{ans_message} = "Your rating must be 1, 2, 3, 4, or 5.";
+ return 0;
+ }
+
+ return 1;
+ }
+);
+
+# -------------------------------------------------------
+# Scaffold
+# -------------------------------------------------------
+Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ hardcopy_is_open => "always",
+);
+
+
+# -------------------------------------------------------
+Section::Begin("Step 1: Problem Statement and Diagrams");
+
+BEGIN_TEXT
+In a Montreal community center, residents commonly communicate in two languages:
+English and French.
+$PAR
+Let \(E\) be the event "a randomly chosen resident speaks English"
+and let \(F\) be the event "a randomly chosen resident speaks French."
+$PAR
+We are told:
+$BR
+56% of the residents speak English.
+$BR
+78% speak at least one of the two languages.
+$BR
+23% speak both languages.
+$PAR
+Here are three Venn diagrams labeled A, B, and C:
+$PAR
+\{ image("venn_3.png", width => 720) \}
+$PAR
+END_TEXT
+
+BEGIN_TEXT
+Which diagram represents the event: "speaks English"?
+$PAR
+\{ $rb_E->buttons \}
+$PAR
+Which diagram represents the event: "speaks at least one of the two languages"?
+$PAR
+\{ $rb_EuF->buttons \}
+$PAR
+Which diagram represents the event: "speaks both languages"?
+$PAR
+\{ $rb_EiF->buttons \}
+END_TEXT
+
+ANS($rb_E->cmp());
+ANS($rb_EuF->cmp());
+ANS($rb_EiF->cmp());
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Step 2: Enter the given probabilities");
+
+BEGIN_TEXT
+Enter the three given probabilities as decimals.
+$PAR
+\(P(E)\) = \{ ans_rule(8) \}
+$BR
+\(P(E \cup F)\) = \{ ans_rule(8) \}
+$BR
+\(P(E \cap F)\) = \{ ans_rule(8) \}
+END_TEXT
+
+ANS($cmp_PE);
+ANS($cmp_PEuF);
+ANS($cmp_PEiF);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Step 3: General Additive Rule");
+
+BEGIN_TEXT
+To connect union, intersection, and individual probabilities, we use the
+general additive rule.
+$PAR
+Quiz Time
+$BR
+Which formula is the correct general additive rule?
+$PAR
+\{ $rb_add_rule->buttons \}
+END_TEXT
+
+ANS($rb_add_rule->cmp());
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Step 4: Solve for P(F)");
+
+BEGIN_TEXT
+Use the general additive rule:
+$BR
+\(P(E \cup F)=P(E)+P(F)-P(E \cap F)\)
+$PAR
+Solve for \(P(F)\) and enter your answer as a decimal.
+$PAR
+\(P(F)\) = \{ ans_rule(10) \}
+END_TEXT
+
+ANS($cmp_PF);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Step 5: English only and French only (with Venn help)");
+
+BEGIN_TEXT
+Now we will find the "only" probabilities.
+Use the Venn diagrams below as a visual hint.
+(The intersection is pure white.)
+$PAR
+\{ image("venn_2.png", width => 720) \}
+$PAR
+
+English only means "English but not French."
+$BR
+\(P(\text{English only})\) = \{ ans_rule(10) \}
+$PAR
+
+French only means "French but not English."
+$BR
+\(P(\text{French only})\) = \{ ans_rule(10) \}
+$PAR
+
+Quick check:
+(English only) + (French only) + (both) should equal \(P(E \cup F)\).
+$BR
+\(P(\text{English only}) + P(\text{French only}) + P(E \cap F)\) = \{ ans_rule(10) \}
+END_TEXT
+
+ANS($cmp_Eonly);
+ANS($cmp_Fonly);
+ANS($cmp_union_check);
+
+Section::End();
+
+# ----------------------------------------------------------------
+# PILOT RATING
+# ----------------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+
+ Section::Begin("Feedback");
+
+ BEGIN_TEXT
+Rate the usefulness of this guided problem on a scale from 1 to 5.
+$PAR
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+$BR
+Note: Consider using the Email Instructor button below to suggest improvements.
+$PAR
+Rating:
+$BR
+\{ ans_rule(6) \}
+END_TEXT
+
+ ANS($rating_cmp);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem13.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem13.pg
new file mode 100644
index 0000000000..d1374e6d08
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem13.pg
@@ -0,0 +1,475 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Union & Intersection from a Contingency Table (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Union and Intersection)
+## Level(2)
+## KEYWORDS('probability','event','intersection','union','contingency table','additive rule')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "contextString.pl",
+ "scaffold.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Population data (counts)
+# Rows: Gender (F = Female, M = Male)
+# Cols: Program (A = Arts, E = Engineering, C = Commerce)
+# =======================================================
+%cnt = (
+ F => { A => 120, E => 210, C => 90 }, # row total 420
+ M => { A => 180, E => 150, C => 50 }, # row total 380
+);
+
+$rowF = $cnt{F}{A} + $cnt{F}{E} + $cnt{F}{C};
+$rowM = $cnt{M}{A} + $cnt{M}{E} + $cnt{M}{C};
+
+$colA = $cnt{F}{A} + $cnt{M}{A};
+$colE = $cnt{F}{E} + $cnt{M}{E};
+$colC = $cnt{F}{C} + $cnt{M}{C};
+
+$N = $rowF + $rowM;
+
+# =======================================================
+# Working set-entry method (String context + comma redefine)
+# Students enter comma-separated outcome codes like: FA, ME, MC
+# =======================================================
+$ctxSet = Context("String");
+$ctxSet->operators->redefine(',', using => ',');
+
+$ctxSet->strings->add(
+ "FA" => {}, "FE" => {}, "FC" => {},
+ "MA" => {}, "ME" => {}, "MC" => {},
+);
+
+# Correct event sets (order doesn't matter)
+$set_E = List( String("FE"), String("ME") ); # Engineering
+$set_Cc = List( String("FA"), String("FE"), String("MA"), String("ME") ); # not Commerce
+$set_MuA = List( String("FA"), String("MA"), String("ME"), String("MC") ); # Male or Arts
+
+$cmp_set_E = $set_E->cmp(ignoreOrder => 1);
+$cmp_set_Cc = $set_Cc->cmp(ignoreOrder => 1);
+$cmp_str_FE = String("FE")->cmp(); # Female and Engineering
+$cmp_set_MuA = $set_MuA->cmp(ignoreOrder => 1);
+
+# =======================================================
+# Numeric comparators (probabilities + rating)
+# =======================================================
+Context("Numeric");
+
+$prob_E = $colE / $N;
+$prob_Cc = 1 - ($colC / $N);
+$prob_FE = $cnt{F}{E} / $N;
+$prob_MuA = ($rowM + $colA - $cnt{M}{A}) / $N; # general additive rule value
+
+$cmp_prob_E = Real($prob_E)->cmp(tolType => "absolute", tolerance => 0.001);
+$cmp_prob_Cc = Real($prob_Cc)->cmp(tolType => "absolute", tolerance => 0.001);
+$cmp_prob_FE = Real($prob_FE)->cmp(tolType => "absolute", tolerance => 0.001);
+$cmp_prob_MuA = Real($prob_MuA)->cmp(tolType => "absolute", tolerance => 0.001);
+
+# For new additive-rule verification section (Male or Arts)
+$prob_M = $rowM / $N;
+$prob_A = $colA / $N;
+$prob_MiA = $cnt{M}{A} / $N;
+
+$cmp_prob_M = Real($prob_M)->cmp(tolType => "absolute", tolerance => 0.001);
+$cmp_prob_A = Real($prob_A)->cmp(tolType => "absolute", tolerance => 0.001);
+$cmp_prob_MiA = Real($prob_MiA)->cmp(tolType => "absolute", tolerance => 0.001);
+
+$cmp_add_expr = Real($prob_M + $prob_A - $prob_MiA)->cmp(tolType => "absolute", tolerance => 0.001);
+
+$cmp_rating = Real(1)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return ($v >= 1 && $v <= 5) ? 1 : 0;
+ }
+);
+
+# Restore set context for set-building blanks
+Context($ctxSet);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ hardcopy_is_open => "always",
+);
+
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+
+BEGIN_TEXT
+The breakdown of the students enrolled in a college by gender and program is shown in the contingency table below.
+A student is selected at random, and we record the student's gender and program.
+$PAR
+
+
+
+ |
+ Arts (A) |
+ Engineering (E) |
+ Commerce (C) |
+ Row total |
+
+
+ | Female (F) |
+ $cnt{F}{A} | $cnt{F}{E} | $cnt{F}{C} |
+ $rowF |
+
+
+ | Male (M) |
+ $cnt{M}{A} | $cnt{M}{E} | $cnt{M}{C} |
+ $rowM |
+
+
+ | Column total |
+ $colA | $colE | $colC |
+ $N |
+
+
+
+$PAR
+In this problem, each cell of the table is one outcome.
+END_TEXT
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Outcome codes and the sample space");
+
+BEGIN_TEXT
+We label outcomes using a two-letter code.
+$PAR
+
+First letter (gender):
+$BR
+F = Female, M = Male
+$PAR
+
+Second letter (program):
+$BR
+A = Arts, E = Engineering, C = Commerce
+$PAR
+
+Examples:
+$BR
+FA means (Female, Arts)
+$BR
+ME means (Male, Engineering)
+$BR
+MC means (Male, Commerce)
+$PAR
+
+So the sample space looks like this:
+$BR
+\(S = \lbrace FA, FE, FC, MA, ME, MC \rbrace\)
+$PAR
+
+Checkpoint: Which code represents "Female and Engineering"?
+$BR
+A) EF
+$BR
+B) FE
+$BR
+C) ME
+$BR
+D) FC
+$PAR
+Answer (A/B/C/D): \{ ans_rule(2) \}
+END_TEXT
+
+ANS( str_cmp("B") );
+
+Section::End();
+
+# =======================================================
+# EVENT 1 (simple)
+# =======================================================
+Section::Begin("Event 1 — Engineering");
+
+BEGIN_TEXT
+Event 1 (Simple event)
+$PAR
+Let \(E\) be the event: "The student is enrolled in Engineering."
+$PAR
+
+Step 1 (Build the event).
+List all outcome codes that satisfy "enrolled in Engineering".
+Comma-separated, order doesn't matter. Do not type braces.
+$BR
+\(E\) = { \{ ans_rule(40) \} }
+$PAR
+
+Step 2 (Find the probability).
+Use the table to compute:
+$BR
+\(P(E) = \dfrac{\text{(number in Engineering)}}{\text{(total number of students)}}\)
+$PAR
+Enter \(P(E)\) as a decimal (example: 40% would be 0.40):
+$BR
+\(P(E)\) = \{ ans_rule(10) \}
+END_TEXT
+
+ANS($cmp_set_E);
+
+Context("Numeric");
+ANS($cmp_prob_E);
+Context($ctxSet);
+
+Section::End();
+
+# =======================================================
+# EVENT 2 (complement)
+# =======================================================
+Section::Begin("Event 2 — Not Commerce");
+
+BEGIN_TEXT
+Event 2 (Complement event)
+$PAR
+Let \(C\) be the event: "The student is enrolled in Commerce."
+Then \(C^c\) means: "The student is NOT enrolled in Commerce."
+$PAR
+
+Step 1 (Build the complement event).
+List all outcome codes that satisfy "not Commerce".
+Comma-separated, order doesn't matter. Do not type braces.
+$BR
+\(C^c\) = { \{ ans_rule(40) \} }
+$PAR
+
+Step 2 (Find the probability).
+You may compute it directly from counts, or use:
+$BR
+\(P(C^c)=1-P(C)\)
+$PAR
+Enter \(P(C^c)\) as a decimal:
+$BR
+\(P(C^c)\) = \{ ans_rule(10) \}
+END_TEXT
+
+ANS($cmp_set_Cc);
+
+Context("Numeric");
+ANS($cmp_prob_Cc);
+Context($ctxSet);
+
+Section::End();
+
+# =======================================================
+# EVENT 3a (choose notation for "and")
+# =======================================================
+Section::Begin("Event 3A — Choose the correct notation (and)");
+
+BEGIN_TEXT
+Event 3 (Compound event with "and")
+$PAR
+Consider the event: "Female and Engineering".
+$PAR
+Which option correctly represents this compound event?
+$PAR
+$BR
+A) \(F \cup E\)
+$BR
+B) \(F^c \cap E\)
+$BR
+C) \(F \cap E\)
+$BR
+D) \(F \cap E^c\)
+$PAR
+Answer (A/B/C/D): \{ ans_rule(2) \}
+END_TEXT
+
+ANS( str_cmp("C") );
+
+Section::End();
+
+# =======================================================
+# EVENT 3b ("and" = intersection; build + probability)
+# =======================================================
+Section::Begin("Event 3B — Build the event and find its probability");
+
+BEGIN_TEXT
+Now build the event "Female and Engineering" and compute its probability.
+$PAR
+
+Step 1 (Build the event).
+List all outcome codes that satisfy: Female and Engineering.
+(If the event has only one outcome, just type that one code.)
+$BR
+\(F \cap E\) = { \{ ans_rule(20) \} }
+$PAR
+
+Step 2 (Find the probability).
+Enter \(P(F \cap E)\) as a decimal:
+$BR
+\(P(F \cap E)\) = \{ ans_rule(10) \}
+END_TEXT
+
+ANS($cmp_str_FE);
+
+Context("Numeric");
+ANS($cmp_prob_FE);
+Context($ctxSet);
+
+Section::End();
+
+# =======================================================
+# EVENT 4a (choose notation for "or")
+# =======================================================
+Section::Begin("Event 4A — Choose the correct notation (or)");
+
+BEGIN_TEXT
+Event 4 (Compound event with "or")
+$PAR
+Consider the event: "Male or Arts".
+(Remember: "or" includes the case where both happen.)
+$PAR
+Which option correctly represents this compound event?
+$PAR
+$BR
+A) \(M \cap A\)
+$BR
+B) \(M \cup A\)
+$BR
+C) \(M^c \cup A\)
+$BR
+D) \(M \cup A^c\)
+$PAR
+Answer (A/B/C/D): \{ ans_rule(2) \}
+END_TEXT
+
+ANS( str_cmp("B") );
+
+Section::End();
+
+# =======================================================
+# EVENT 4b ("or" = union; build + probability)
+# =======================================================
+Section::Begin("Event 4B — Build the event and find its probability");
+
+BEGIN_TEXT
+Now build the event "Male or Arts" and compute its probability.
+$PAR
+
+Step 1 (Build the event).
+List all outcome codes that satisfy: Male or Arts (or both).
+Comma-separated, order doesn't matter. Do not type braces.
+$BR
+\(M \cup A\) = { \{ ans_rule(40) \} }
+$PAR
+
+Step 2 (Find the probability).
+Compute \(P(M \cup A)\) using the table (be careful not to double-count).
+$PAR
+Enter \(P(M \cup A)\) as a decimal:
+$BR
+\(P(M \cup A)\) = \{ ans_rule(10) \}
+END_TEXT
+
+ANS($cmp_set_MuA);
+
+Context("Numeric");
+ANS($cmp_prob_MuA);
+Context($ctxSet);
+
+Section::End();
+
+# =======================================================
+# NEW SECTION: General Additive Rule verification
+# =======================================================
+Section::Begin("General Additive Rule");
+
+BEGIN_TEXT
+General Additive Rule
+$PAR
+For any two events \(X\) and \(Y\):
+$BR
+\(P(X \cup Y)=P(X)+P(Y)-P(X \cap Y)\)
+$PAR
+
+In the previous section we calculated the probability of "Male or Arts" to be \(5/8\).
+Now let's use the general additive rule to get the same result.
+$PAR
+
+Step 1. Find \(P(M)\):
+$BR
+\(P(M)\) = \{ ans_rule(10) \}
+$PAR
+
+Step 2. Find \(P(A)\):
+$BR
+\(P(A)\) = \{ ans_rule(10) \}
+$PAR
+
+Step 3. Find \(P(M \cap A)\):
+$BR
+\(P(M \cap A)\) = \{ ans_rule(10) \}
+$PAR
+
+Step 4. Compute:
+$BR
+\(P(M \cup A)=P(M)+P(A)-P(M \cap A)\) = \{ ans_rule(10) \}
+END_TEXT
+
+Context("Numeric");
+ANS($cmp_prob_M);
+ANS($cmp_prob_A);
+ANS($cmp_prob_MiA);
+ANS($cmp_add_expr);
+
+Context($ctxSet);
+
+Section::End();
+
+# ----------------------------------------------------------------
+# PILOT RATING (ACTIVE)
+# ----------------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+
+ Section::Begin("Feedback");
+ BEGIN_TEXT
+Rate the usefulness of this guided problem on a scale from 1 to 5.
+$PAR
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+$BR
+Note: Consider using the Email Instructor button below to suggest improvements.
+$PAR
+Rating:
+$BR
+\{ ans_rule(6) \}
+END_TEXT
+
+ Context("Numeric");
+ ANS($cmp_rating);
+ Context($ctxSet);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem14.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem14.pg
new file mode 100644
index 0000000000..ff0f59406f
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem14.pg
@@ -0,0 +1,316 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Conditional Probability (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Conditional Probability)
+## Level(2)
+## KEYWORDS('probability','conditional probability','intersection','independence','die')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "contextString.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# Library Browser / SetMaker flag (define early; BP rule)
+# ----------------------------------------------------------------
+our $inLibraryBrowser = (defined($envir{problemSeed}) && $envir{problemSeed} == 0) ? 1 : 0;
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Set context for outcomes (BP Section P pattern)
+# =======================================================
+our $ctxSet = Context("String")->copy;
+Context($ctxSet);
+
+# Allow comma-separated lists of strings to be parsed as a List
+Context()->operators->redefine(',', using => ',');
+
+our %allowed = map { $_ => {} } qw(1 2 3 4 5 6);
+Context()->strings->add(%allowed);
+
+# Correct sets as Lists of Strings (order doesn't matter)
+# We define the objects here, but we will generate the .cmp locally later
+our $correctA = List( String("2"), String("4"), String("6") );
+our $correctB = List( String("3"), String("4"), String("5"), String("6") );
+our $correctAiB = List( String("4"), String("6") );
+
+# =======================================================
+# Numeric comparators
+# =======================================================
+Context("Numeric");
+
+# It is generally safe to keep Numeric comparators global as they are more robust
+our $cmp_pA = Real(1/2)->cmp( tolType => "absolute", tolerance => 0.001 );
+our $cmp_pB = Real(2/3)->cmp( tolType => "absolute", tolerance => 0.001 );
+our $cmp_pAiB = Real(1/3)->cmp( tolType => "absolute", tolerance => 0.001 );
+our $cmp_pA_givenB = Real(1/2)->cmp( tolType => "absolute", tolerance => 0.001 ); # (1/3)/(2/3)
+our $cmp_pB_givenA = Real(2/3)->cmp( tolType => "absolute", tolerance => 0.001 ); # (1/3)/(1/2)
+
+# =======================================================
+# Independence question (RadioButtons; avoids A/B parsing issues)
+# Correct: Yes
+# =======================================================
+our $rb_indep = RadioButtons(
+ [
+ "Yes",
+ "No",
+ ],
+ 0, # 0-based index => Yes
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Rating checker (integer 1..5)
+# =======================================================
+our $rating = Real(3); # placeholder
+our $rating_cmp = $rating->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ if (!defined($student)) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ my $val;
+ eval { $val = $student->value; };
+ if (!defined($val)) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ my $ival = int($val);
+ if (abs($val - $ival) > 1e-12) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ if ($ival < 1 || $ival > 5) {
+ $ansHash->{ans_message} = "Your rating must be 1, 2, 3, 4, or 5.";
+ return 0;
+ }
+
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ hardcopy_is_open => "always",
+);
+
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_TEXT
+A fair 6-sided die is rolled once.
+$PAR
+Sample space:
+$BR
+\(S=\lbrace 1,2,3,4,5,6\rbrace\)
+$PAR
+Define the events:
+$BR
+\(A\): the roll is even.
+$BR
+\(B\): the roll is greater than 2.
+END_TEXT
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Build the events as sets");
+BEGIN_TEXT
+Enter each event as a set of outcomes (comma-separated, order doesn't matter).
+Do not type braces.
+$PAR
+\(A\) = { \{ NAMED_ANS_RULE("Aset",30) \} }
+$BR
+\(B\) = { \{ NAMED_ANS_RULE("Bset",30) \} }
+END_TEXT
+
+# FIX: Set Context, then generate cmp immediately
+Context($ctxSet);
+NAMED_ANS("Aset", $correctA->cmp(ignoreOrder => 1));
+NAMED_ANS("Bset", $correctB->cmp(ignoreOrder => 1));
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Intersection and basic probabilities");
+BEGIN_TEXT
+Step 1 (Intersection).
+Build the intersection \(A \cap B\) as a set of outcomes.
+Comma-separated, order doesn't matter. Do not type braces.
+$BR
+\(A \cap B\) = { \{ NAMED_ANS_RULE("AiBset",30) \} }
+$PAR
+
+Step 2 (Basic probabilities).
+Because the die is fair, all 6 outcomes are equally likely.
+$PAR
+Enter each probability as a fraction or a decimal.
+$BR
+\(P(A)\) = \{ NAMED_ANS_RULE("pA",12) \}
+$BR
+\(P(B)\) = \{ NAMED_ANS_RULE("pB",12) \}
+$BR
+\(P(A \cap B)\) = \{ NAMED_ANS_RULE("pAiB",12) \}
+END_TEXT
+
+# FIX: Set Context, then generate cmp immediately
+Context($ctxSet);
+NAMED_ANS("AiBset", $correctAiB->cmp(ignoreOrder => 1));
+
+Context("Numeric");
+NAMED_ANS("pA", $cmp_pA);
+NAMED_ANS("pB", $cmp_pB);
+NAMED_ANS("pAiB", $cmp_pAiB);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Conditional probability means a restricted sample space");
+BEGIN_TEXT
+Key idea: \(P(A \mid B)\) means "the probability that \(A\) happens given that \(B\) happened."
+$PAR
+When we know \(B\) happened, we throw away all outcomes not in \(B\).
+So the new sample space is the set of outcomes in \(B\).
+$PAR
+
+Checkpoint: List the outcomes that are possible given \(B\).
+(So, list the outcomes in \(B\).)
+Comma-separated, order doesn't matter. Do not type braces.
+$BR
+\(S_B\) = { \{ NAMED_ANS_RULE("SBset",30) \} }
+$PAR
+
+Definition: If \(P(B) > 0\), then
+$BR
+\(P(A \mid B)=\dfrac{P(A \cap B)}{P(B)}\).
+$PAR
+
+Compute:
+$BR
+\(P(A \mid B)\) = \{ NAMED_ANS_RULE("pAgB",12) \}
+END_TEXT
+
+# FIX: Set Context, then generate cmp immediately
+Context($ctxSet);
+NAMED_ANS("SBset", $correctB->cmp(ignoreOrder => 1));
+
+Context("Numeric");
+NAMED_ANS("pAgB", $cmp_pA_givenB);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Final Answer");
+BEGIN_TEXT
+Final Answer.
+Use the definition of conditional probability to compute:
+$PAR
+Enter your answer as a fraction or a decimal.
+$BR
+\(P(B \mid A)\) = \{ NAMED_ANS_RULE("pBgA",12) \}
+END_TEXT
+
+Context("Numeric");
+NAMED_ANS("pBgA", $cmp_pB_givenA);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Independence (intuitive meaning)");
+BEGIN_TEXT
+Independence (intuitive meaning):
+$PAR
+Events \(A\) and \(B\) are independent if knowing that \(B\) happened does not change how likely \(A\) is.
+Another way to say it: knowing \(B\) gives no useful information about whether \(A\) happens.
+$PAR
+A common test is:
+$BR
+\(A\) and \(B\) are independent if \(P(A \mid B)=P(A)\).
+$PAR
+Based on your results, are \(A\) and \(B\) independent?
+$PAR
+\{ $rb_indep->buttons \}
+END_TEXT
+
+ANS($rb_indep->cmp());
+
+Section::End();
+
+# ----------------------------------------------------------------
+# PILOT RATING (ACTIVE)
+# ----------------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+
+ Section::Begin("Feedback");
+ BEGIN_TEXT
+Rate the usefulness of this guided problem on a scale from 1 to 5.
+$PAR
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+$BR
+Note: Consider using the Email Instructor button below to suggest improvements.
+$PAR
+Rating:
+$BR
+\{ NAMED_ANS_RULE("rating",6) \}
+END_TEXT
+
+ Context("Numeric");
+ NAMED_ANS("rating", $rating_cmp);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+BEGIN_PGML_SOLUTION
+**1.** The events are:
+
+- A = {2, 4, 6}
+- B = {3, 4, 5, 6}
+- A ∩ B = {4, 6}
+
+**2.** Basic probabilities (all 6 outcomes are equally likely):
+
+- P(A) = 3/6 = 1/2
+- P(B) = 4/6 = 2/3
+- P(A ∩ B) = 2/6 = 1/3
+
+**3.** Conditional probabilities:
+
+- P(A | B) = P(A ∩ B) / P(B) = (1/3) / (2/3) = 1/2
+- P(B | A) = P(A ∩ B) / P(A) = (1/3) / (1/2) = 2/3
+
+**4.** Independence:
+
+Since P(A | B) = P(A), the events A and B are independent.
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem15.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem15.pg
new file mode 100644
index 0000000000..22d55430a3
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem15.pg
@@ -0,0 +1,285 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Conditional Probability (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Conditional Probability)
+## Level(2)
+## KEYWORDS('probability','conditional probability','intersection','independence','two dice','4-sided dice')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "contextString.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Sample space table (HTML) for outcomes 11..44 (4-sided dice)
+# =======================================================
+my @nums = (1..4);
+
+our $table_html = '';
+$table_html .= '| Die 1 / Die 2 | ';
+for my $j (@nums) { $table_html .= "$j | "; }
+$table_html .= '
';
+
+for my $i (@nums) {
+ $table_html .= "| $i | ";
+ for my $j (@nums) {
+ my $code = "$i$j";
+ $table_html .= "$code | ";
+ }
+ $table_html .= "
";
+}
+$table_html .= "
";
+
+# =======================================================
+# Set context: allow comma-separated outcomes + "none"
+# =======================================================
+our $ctxSet = Context("String");
+$ctxSet->operators->redefine(',', using => ',');
+
+our %allowed = ();
+for my $i (@nums) {
+ for my $j (@nums) {
+ $allowed{"$i$j"} = {};
+ }
+}
+$allowed{"none"} = { caseSensitive => 0 };
+$ctxSet->strings->add(%allowed);
+
+# =======================================================
+# Events for this GP (same experiment: two 4-sided dice)
+# A: sum is even
+# B: sum is greater than 5
+# =======================================================
+our @A = qw(11 13 22 24 31 33 42 44);
+our @B = qw(24 33 42 34 43 44);
+our @AiB = qw(24 33 42 44);
+
+# =======================================================
+# Numeric answer checkers (kept simple)
+# =======================================================
+Context("Numeric");
+
+our $cmp_pB = Real(3/8)->cmp( tolType => "absolute", tolerance => 0.001 );
+our $cmp_pAiB = Real(1/4)->cmp( tolType => "absolute", tolerance => 0.001 );
+our $cmp_pAgB = Real(2/3)->cmp( tolType => "absolute", tolerance => 0.001 );
+our $cmp_pA = Real(1/2)->cmp( tolType => "absolute", tolerance => 0.001 );
+
+# =======================================================
+# Independence question (RadioButtons; correct is "No")
+# Put correct option as B (not always A)
+# =======================================================
+our $rb_indep = RadioButtons(
+ [
+ "Yes",
+ "No",
+ ],
+ 1, # 0-based index => "No"
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Rating checker (integer 1..5)
+# =======================================================
+our ($rating, $rating_cmp);
+
+if ($ENABLE_GP_RATING) {
+
+ $rating = Real(3); # placeholder only
+
+ $rating_cmp = $rating->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ if (!defined($student)) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ my $val;
+ eval { $val = $student->value; };
+ if (!defined($val)) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ my $ival = int($val);
+ if (abs($val - $ival) > 1e-12) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ if ($ival < 1 || $ival > 5) {
+ $ansHash->{ans_message} = "Your rating must be 1, 2, 3, 4, or 5.";
+ return 0;
+ }
+
+ return 1;
+ }
+ );
+}
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ hardcopy_is_open => "always",
+);
+
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+
+BEGIN_TEXT
+Two fair four-sided dice are rolled at the same time.
+We record the ordered pair (first die, second die) using a two-digit code.
+For example, 34 means (first die = 3, second die = 4).
+$PAR
+Here is the sample space:
+$PAR
+\{ $table_html \}
+$PAR
+Define the events:
+$BR
+\(A\): the sum of the two dice is even.
+$BR
+\(B\): the sum of the two dice is greater than 5.
+$PAR
+We want to calculate \(P(A \mid B)\).
+END_TEXT
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("What conditional probability means");
+
+BEGIN_TEXT
+Conditional probability
+$PAR
+\(P(A \mid B)\) means: the probability that \(A\) happens given that \(B\) happened.
+$PAR
+Thinking trick: once we know \(B\) happened, we throw away every outcome that is not in \(B\).
+So we are working inside a smaller sample space (only outcomes in \(B\)).
+$PAR
+Definition (when \(P(B)>0\)):
+$BR
+\(P(A \mid B)=\dfrac{P(A \cap B)}{P(B)}\).
+END_TEXT
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Build the outcomes in A, B, and A intersection B");
+
+BEGIN_TEXT
+List outcomes as comma-separated two-digit codes. Order does not matter. Do not type braces.
+$PAR
+\(A\) = { \{ NAMED_ANS_RULE("Aset",80) \} }
+$PAR
+\(B\) = { \{ NAMED_ANS_RULE("Bset",80) \} }
+$PAR
+\(A \cap B\) = { \{ NAMED_ANS_RULE("AiBset",80) \} }
+END_TEXT
+
+# BP rule: create set ->cmp() just-in-time under the active set context
+Context($ctxSet);
+NAMED_ANS("Aset", List(map { String($_) } @A)->cmp(ignoreOrder => 1));
+NAMED_ANS("Bset", List(map { String($_) } @B)->cmp(ignoreOrder => 1));
+NAMED_ANS("AiBset", List(map { String($_) } @AiB)->cmp(ignoreOrder => 1));
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Final Answer");
+
+BEGIN_TEXT
+Use the definition \(P(A \mid B)=P(A \cap B)/P(B)\).
+$PAR
+Enter probabilities as a fraction or a decimal.
+$PAR
+\(P(B)\) = \{ NAMED_ANS_RULE("pB",12) \}
+$BR
+\(P(A \cap B)\) = \{ NAMED_ANS_RULE("pAiB",12) \}
+$PAR
+Final Answer:
+$BR
+\(P(A \mid B)\) = \{ NAMED_ANS_RULE("pAgB",12) \}
+END_TEXT
+
+Context("Numeric");
+NAMED_ANS("pB", $cmp_pB);
+NAMED_ANS("pAiB", $cmp_pAiB);
+NAMED_ANS("pAgB", $cmp_pAgB);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Independence");
+
+BEGIN_TEXT
+Independence (meaning)
+$PAR
+Events \(A\) and \(B\) are independent if knowing that \(B\) happened does not change how likely \(A\) is.
+$PAR
+A common test is: \(A\) and \(B\) are independent if \(P(A \mid B)=P(A)\) or equivalently \(P(A \cap B)=P(A)P(B)\) .
+$PAR
+Compute \(P(A)\) (fraction or decimal):
+$BR
+\(P(A)\) = \{ NAMED_ANS_RULE("pA",12) \}
+$PAR
+Based on your results, are \(A\) and \(B\) independent?
+$PAR
+\{ $rb_indep->buttons \}
+END_TEXT
+
+Context("Numeric");
+NAMED_ANS("pA", $cmp_pA);
+
+ANS($rb_indep->cmp());
+
+Section::End();
+
+# ----------------------------------------------------------------
+# PILOT RATING (ACTIVE)
+# ----------------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+
+ Section::Begin("Feedback");
+ BEGIN_PGML
+Rate the usefulness of this guided problem on a scale from 1 to 5.
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating: [__]{$rating_cmp}
+END_PGML
+ Section::End();
+
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem16.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem16.pg
new file mode 100644
index 0000000000..dc54d97d06
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem16.pg
@@ -0,0 +1,261 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Independence of Events (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Independence)
+## Level(2)
+## KEYWORDS('probability','independence','conditional probability','cards','face cards','red cards')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Numeric context
+# =======================================================
+Context("Numeric");
+
+# Known probabilities in a standard deck (52 cards)
+# Face cards: J,Q,K in 4 suits => 12
+# Red cards: hearts, diamonds => 26
+# Face AND red: J,Q,K in 2 red suits => 6
+
+our $cmp_pF = Real(12/52)->cmp( tolType => "absolute", tolerance => 0.001 );
+our $cmp_pR = Real(26/52)->cmp( tolType => "absolute", tolerance => 0.001 );
+our $cmp_pFgR = Real(6/26)->cmp( tolType => "absolute", tolerance => 0.001 ); # P(F|R)
+our $cmp_pFiR = Real(6/52)->cmp( tolType => "absolute", tolerance => 0.001 ); # P(F∩R)
+our $cmp_pFpR = Real((12/52)*(26/52))->cmp( tolType => "absolute", tolerance => 0.001 );
+
+our $cmp_zero = Real(0)->cmp( tolType => "absolute", tolerance => 0.001 );
+
+# Independence decisions (both should be YES)
+our $rb_indep1 = RadioButtons(
+ [ "No", "Yes" ],
+ 1, # 0-based index => Yes
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+our $rb_indep2 = RadioButtons(
+ [ "No", "Yes" ],
+ 1, # 0-based index => Yes
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Rating checker (integer 1..5)
+# =======================================================
+our ($rating, $rating_cmp);
+
+if ($ENABLE_GP_RATING) {
+
+ $rating = Real(3); # placeholder only
+
+ $rating_cmp = $rating->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ if (!defined($student)) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ my $val;
+ eval { $val = $student->value; };
+ if (!defined($val)) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ my $ival = int($val);
+ if (abs($val - $ival) > 1e-12) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ if ($ival < 1 || $ival > 5) {
+ $ansHash->{ans_message} = "Your rating must be 1, 2, 3, 4, or 5.";
+ return 0;
+ }
+
+ return 1;
+ }
+ );
+}
+
+# =======================================================
+# Scaffold (sequential gating)
+# =======================================================
+Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ hardcopy_is_open => "always",
+);
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+
+BEGIN_TEXT
+A card is drawn at random from a standard 52-card deck.
+$PAR
+Define the events:
+$BR
+\(F\): the card is a face card (Jack, Queen, or King).
+$BR
+\(R\): the card is red (hearts or diamonds).
+$PAR
+We want to prove that \(F\) and \(R\) are independent.
+END_TEXT
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Independence (intuitive definition)");
+
+BEGIN_TEXT
+Independence (idea)
+$PAR
+Events \(A\) and \(B\) are independent if knowing that \(B\) happened does not change how likely \(A\) is.
+$PAR
+A common definition is:
+$BR
+\(A\) and \(B\) are independent if \(P(A \mid B)=P(A)\) (assuming \(P(B)>0\)).
+END_TEXT
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Verify independence using conditional probability");
+
+BEGIN_TEXT
+Compute the following probabilities (fraction or decimal):
+$PAR
+\(P(F)\) = \{ NAMED_ANS_RULE("pF",12) \}
+$BR
+\(P(R)\) = \{ NAMED_ANS_RULE("pR",12) \}
+$PAR
+
+Now compute \(P(F \mid R)\).
+$PAR
+Hint: You can do this without using the conditional probability formula.
+If you know the card is red, restrict the sample space to only the 26 red cards.
+Then compute:
+(number of red face cards) / (number of red cards).
+$PAR
+\(P(F \mid R)\) = \{ NAMED_ANS_RULE("pFgR",12) \}
+$PAR
+
+Based on your results, are \(F\) and \(R\) independent?
+$PAR
+\{ $rb_indep1->buttons \}
+END_TEXT
+
+Context("Numeric");
+NAMED_ANS("pF", $cmp_pF);
+NAMED_ANS("pR", $cmp_pR);
+NAMED_ANS("pFgR", $cmp_pFgR);
+
+ANS($rb_indep1->cmp());
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Equivalent definition using intersection (and algebra)");
+
+BEGIN_TEXT
+Another common definition says:
+$PAR
+\(A\) and \(B\) are independent if \(P(A \cap B)=P(A)P(B)\).
+$PAR
+These two definitions are equivalent (when \(P(B)>0\)).
+Here is the algebra:
+$PAR
+Start with the conditional probability formula:
+$BR
+\(P(A \mid B)=\dfrac{P(A \cap B)}{P(B)}\).
+$PAR
+If \(A\) and \(B\) are independent, then \(P(A \mid B)=P(A)\).
+So:
+$BR
+\(\dfrac{P(A \cap B)}{P(B)}=P(A)\).
+$PAR
+Multiply both sides by \(P(B)\):
+$BR
+\(P(A \cap B)=P(A)P(B)\).
+END_TEXT
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Verify independence using P(A intersection B)=P(A)P(B)");
+
+BEGIN_TEXT
+Compute the following (fraction or decimal). Remember that intersection means "and", so you need to count the number of cards that are Red and Face out of all possible cards:
+$PAR
+\(P(F \cap R)\) = \{ NAMED_ANS_RULE("pFiR",12) \}
+$BR
+\(P(F)P(R)\) = \{ NAMED_ANS_RULE("pFpR",12) \}
+$PAR
+
+Check the difference:
+$BR
+\(P(F \cap R)-P(F)P(R)\) = \{ NAMED_ANS_RULE("diff",12) \}
+$PAR
+If \(F\) and \(R\) are independent, that last answer should be 0.
+$PAR
+Are \(F\) and \(R\) independent?
+$PAR
+\{ $rb_indep2->buttons \}
+END_TEXT
+
+Context("Numeric");
+NAMED_ANS("pFiR", $cmp_pFiR);
+NAMED_ANS("pFpR", $cmp_pFpR);
+NAMED_ANS("diff", $cmp_zero);
+
+ANS($rb_indep2->cmp());
+
+Section::End();
+
+# ----------------------------------------------------------------
+# PILOT RATING
+# ----------------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+
+ Section::Begin("Feedback");
+ BEGIN_PGML
+Rate the usefulness of this guided problem on a scale from 1 to 5.
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating: [__]{$rating_cmp}
+END_PGML
+ Section::End();
+
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem17.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem17.pg
new file mode 100644
index 0000000000..60dbc12761
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem17.pg
@@ -0,0 +1,262 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Conditional Probability (Two-Way Tables)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Conditional Probability)
+## Level(2)
+## KEYWORDS('probability','conditional probability','contingency table','independence')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "niceTables.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# Library Browser / SetMaker flag
+# ----------------------------------------------------------------
+our $inLibraryBrowser = (defined($envir{problemSeed}) && $envir{problemSeed} == 0) ? 1 : 0;
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+Context("Numeric");
+
+# =======================================================
+# Data Setup
+# =======================================================
+$N_MorningYes = 80;
+$N_MorningNo = 120;
+$N_Total = 200;
+
+$N_CoffeeYes = 100;
+$N_CoffeeNo = 100;
+
+$N_M_and_C = 60;
+$N_M_and_NoC = 20;
+$N_NoM_and_C = 40;
+$N_NoM_and_NoC= 80;
+
+# Probabilities
+$p_M = Real($N_MorningYes / $N_Total);
+$p_C = Real($N_CoffeeYes / $N_Total);
+$p_M_and_C= Real($N_M_and_C / $N_Total);
+$p_C_given_M = Real($N_M_and_C / $N_MorningYes);
+
+# =======================================================
+# Independence Question
+# =======================================================
+our $rb_indep = RadioButtons(
+ [
+ "Yes, they are independent.",
+ "No, they are not independent.",
+ ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Rating checker
+# =======================================================
+our $rating = Real(3);
+our $rating_cmp = $rating->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ if (!defined($student)) { $ansHash->{ans_message} = "Enter an integer 1-5."; return 0; }
+ my $val = $student->value;
+ if (!defined($val)) { $ansHash->{ans_message} = "Enter an integer 1-5."; return 0; }
+ if ($val != int($val) || $val < 1 || $val > 5) {
+ $ansHash->{ans_message} = "Rating must be an integer from 1 to 5."; return 0;
+ }
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ hardcopy_is_open => "always",
+);
+
+
+# -------------------------------------------------------
+Section::Begin("The Survey Data");
+BEGIN_TEXT
+A university surveys 200 students, asking two questions:
+$BR
+1. Do you consider yourself a "Morning Person"?
+$BR
+2. Do you drink coffee daily?
+$PAR
+The results are summarized in the table below:
+$PAR
+END_TEXT
+
+TEXT(
+ DataTable(
+ [
+ ["", ["Coffee (Yes)", headerrow => 1], ["Coffee (No)", headerrow => 1], ["TOTAL", headerrow => 1, bold => 1]],
+ [["Morning Person (Yes)", headerrow => 1], "$N_M_and_C", "$N_M_and_NoC", "$N_MorningYes"],
+ [["Morning Person (No)", headerrow => 1], "$N_NoM_and_C", "$N_NoM_and_NoC", "$N_MorningNo"],
+ [["TOTAL", headerrow => 1, bold => 1], "$N_CoffeeYes", "$N_CoffeeNo", "$N_Total"]
+ ],
+ caption => "Survey Results",
+ align => '|c|c|c|c|',
+ midrules => 1,
+ )
+);
+
+BEGIN_TEXT
+$PAR
+Define the events:
+$BR
+\(M\): The student is a Morning Person.
+$BR
+\(C\): The student drinks Coffee.
+$PAR
+Step 1 (Marginal Probabilities).
+Calculate the probability that a randomly selected student belongs to each group.
+$PAR
+\(P(M)\) = \{ NAMED_ANS_RULE("pM",10) \}
+$BR
+\(P(C)\) = \{ NAMED_ANS_RULE("pC",10) \}
+END_TEXT
+
+NAMED_ANS("pM", $p_M->cmp);
+NAMED_ANS("pC", $p_C->cmp);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Intersection (The 'AND')");
+BEGIN_TEXT
+Step 2 (Intersection).
+Find the probability that a randomly selected student is both a Morning Person AND drinks coffee.
+$PAR
+\(P(M \cap C)\) = \{ NAMED_ANS_RULE("pMandC",10) \}
+END_TEXT
+
+NAMED_ANS("pMandC", $p_M_and_C->cmp);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Conditional Probability (Restricted Sample Space)");
+BEGIN_TEXT
+Step 3 (Intuitive Approach).
+We want to find \(P(C \mid M)\) by looking only at the relevant row of the table.
+$PAR
+1. How many students are in the restricted sample space (total Morning People)?
+$BR
+\{ NAMED_ANS_RULE("denom",10) \}
+$PAR
+2. Out of those specific students, how many drink coffee?
+$BR
+\{ NAMED_ANS_RULE("num",10) \}
+$PAR
+3. Based on these counts, what is the probability?
+$BR
+\(P(C \mid M)\) = \{ NAMED_ANS_RULE("pCgivenM_counts",10) \}
+END_TEXT
+
+NAMED_ANS("denom", Real($N_MorningYes)->cmp);
+NAMED_ANS("num", Real($N_M_and_C)->cmp);
+NAMED_ANS("pCgivenM_counts", $p_C_given_M->cmp);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Verifying with the Formula");
+BEGIN_TEXT
+Step 4 (Formal Approach).
+The formal definition of conditional probability is:
+$PAR
+\[ P(C \mid M) = \frac{P(C \cap M)}{P(M)} \]
+$PAR
+Using the probabilities you calculated in Step 1 and Step 2, plug the values into this formula:
+$PAR
+\(P(C \mid M) = \frac{\text{Answer from Step 2}}{\text{P(M) from Step 1}}\)
+$PAR
+\(P(C \mid M)\) = \{ NAMED_ANS_RULE("pCgivenM_formula",10) \}
+$PAR
+Note: You should get the same result as you did in Step 3!
+END_TEXT
+
+NAMED_ANS("pCgivenM_formula", $p_C_given_M->cmp);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Independence Check");
+BEGIN_TEXT
+Step 5 (Independence).
+Compare \(P(C) = \) $p_C (from Step 1) with \(P(C \mid M) = \) \{ $p_C_given_M->value \} (from Step 4).
+$PAR
+Based on this comparison, are the events \(C\) and \(M\) independent?
+$PAR
+\{ $rb_indep->buttons \}
+END_TEXT
+
+ANS($rb_indep->cmp);
+
+Section::End();
+
+# ----------------------------------------------------------------
+# PILOT RATING
+# ----------------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_TEXT
+Rate the usefulness of this guided problem on a scale from 1 to 5.
+$BR
+Rating: \{ NAMED_ANS_RULE("rating",6) \}
+END_TEXT
+ NAMED_ANS("rating", $rating_cmp);
+ Section::End();
+}
+
+Scaffold::End();
+
+# =======================================================
+# Solution
+# =======================================================
+BEGIN_PGML_SOLUTION
+**Step 1:**
+[`` P(M) = \frac{80}{200} = 0.4 ``]
+[`` P(C) = \frac{100}{200} = 0.5 ``]
+
+**Step 2:**
+[`` P(M \cap C) = \frac{60}{200} = 0.3 ``]
+
+**Step 3:**
+Restricting the table to the "Morning Person" row, we have 60 coffee drinkers out of 80 people total.
+[`` P(C \mid M) = \frac{60}{80} = 0.75 ``]
+
+**Step 4:**
+Using the formula:
+[`` P(C \mid M) = \frac{P(C \cap M)}{P(M)} = \frac{0.3}{0.4} = 0.75 ``]
+
+**Step 5:**
+Since [``P(C \mid M) = 0.75``] and [``P(C) = 0.5``], the events are **not** independent.
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem18.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem18.pg
new file mode 100644
index 0000000000..88e4cda0be
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem18.pg
@@ -0,0 +1,255 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Conditional Probability from a Contingency Table (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Conditional Probability)
+## Level(2)
+## KEYWORDS('probability','conditional probability','independence','contingency table','gender','program')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data (contingency table counts)
+# =======================================================
+our $FA = 120; # Female & Arts
+our $FE = 210;
+our $FC = 90;
+
+our $MA = 180; # Male & Arts
+our $ME = 150;
+our $MC = 50;
+
+our $rowF = 420;
+our $rowM = 380;
+
+our $colA = 300;
+our $colE = 360;
+our $colC = 140;
+
+our $N = 800;
+
+# =======================================================
+# Display table (HTML)
+# =======================================================
+our $table_html = qq{
+
+
+ |
+ Arts (A) |
+ Engineering (E) |
+ Commerce (C) |
+ Row total |
+
+
+ | Female (F) |
+ $FA |
+ $FE |
+ $FC |
+ $rowF |
+
+
+ | Male (M) |
+ $MA |
+ $ME |
+ $MC |
+ $rowM |
+
+
+ | Column total |
+ $colA |
+ $colE |
+ $colC |
+ $N |
+
+
+};
+
+# =======================================================
+# Numeric MathObjects (Fix: Store as Real, not cmp)
+# =======================================================
+Context("Numeric");
+
+our $val_pFgA = Real($FA/$colA); # P(F|A)
+our $val_pAgF = Real($FA/$rowF); # P(A|F)
+
+our $val_pAiF = Real($FA/$N); # P(A ∩ F)
+our $val_pA = Real($colA/$N); # P(A)
+our $val_pF = Real($rowF/$N); # P(F)
+
+our $val_pApF = Real(($colA/$N)*($rowF/$N)); # P(A)P(F)
+our $val_diff = Real($val_pAiF - $val_pApF);
+
+# =======================================================
+# RadioButtons
+# =======================================================
+our $rb_expect = RadioButtons([ "Yes", "No" ], 1, labels => "ABC", displayLabels => 0);
+our $rb_indep = RadioButtons([ "Yes", "No" ], 1, labels => "ABC", displayLabels => 0);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ hardcopy_is_open => "always",
+);
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_TEXT
+The breakdown of students enrolled in a college by gender and program is shown in the contingency table below.
+A student is selected at random, and we record the student's gender and program.
+$PAR
+\{ $table_html \}
+$PAR
+In this problem, each cell of the table is one outcome.
+$PAR
+Define the events:
+$BR
+\(F\): the randomly selected student is female.
+$BR
+\(A\): the randomly selected student studies arts.
+END_TEXT
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Female given Arts");
+BEGIN_TEXT
+Find the probability that the randomly selected student is Female given they study Arts.
+$PAR
+Hint: "Given Arts" means restrict the sample space to the Arts column only.
+Then you are choosing from Arts students only.
+$PAR
+\(P(F \mid A)\) = \{ NAMED_ANS_RULE("pFgA",12) \}
+END_TEXT
+
+Context("Numeric");
+NAMED_ANS("pFgA", $val_pFgA->cmp(tolType => "absolute", tolerance => 0.001));
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Arts given Female");
+BEGIN_TEXT
+Find the probability that the randomly selected student studies Arts given they are Female.
+$PAR
+Hint: "Given Female" means restrict the sample space to the Female row only.
+Then you are choosing from Female students only.
+$PAR
+\(P(A \mid F)\) = \{ NAMED_ANS_RULE("pAgF",12) \}
+END_TEXT
+
+Context("Numeric");
+NAMED_ANS("pAgF", $val_pAgF->cmp(tolType => "absolute", tolerance => 0.001));
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Independence using intersection definition");
+BEGIN_TEXT
+Independence (definition)
+$PAR
+The events \(A\) and \(F\) are independent if:
+$BR
+\(P(A \cap F)=P(A)P(F)\).
+$PAR
+Use the table to compute each quantity (fraction or decimal):
+$PAR
+\(P(A \cap F)\) = \{ NAMED_ANS_RULE("pAiF",12) \}
+$BR
+\(P(A)\) = \{ NAMED_ANS_RULE("pA",12) \}
+$BR
+\(P(F)\) = \{ NAMED_ANS_RULE("pF",12) \}
+$PAR
+Now compute:
+$BR
+\(P(A)P(F)\) = \{ NAMED_ANS_RULE("pApF",12) \}
+$PAR
+Check the difference:
+$BR
+\(P(A \cap F)-P(A)P(F)\) = \{ NAMED_ANS_RULE("diff",12) \}
+$PAR
+Are \(A\) and \(F\) independent?
+$PAR
+\{ $rb_indep->buttons \}
+END_TEXT
+
+Context("Numeric");
+NAMED_ANS("pAiF", $val_pAiF->cmp());
+NAMED_ANS("pA", $val_pA->cmp());
+NAMED_ANS("pF", $val_pF->cmp());
+NAMED_ANS("pApF", $val_pApF->cmp());
+NAMED_ANS("diff", $val_diff->cmp(tolType => "absolute", tolerance => 0.001));
+ANS($rb_indep->cmp());
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Prediction: do you expect P(A given F) to equal P(A)?");
+BEGIN_TEXT
+Before calculating, do you expect \(P(A \mid F)\) to be the same as \(P(A)\)?
+$PAR
+\{ $rb_expect->buttons \}
+END_TEXT
+ANS($rb_expect->cmp());
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Verify your prediction");
+BEGIN_TEXT
+Now compute both probabilities and compare:
+$PAR
+\(P(A \mid F)\) = \{ NAMED_ANS_RULE("pAgF2",12) \}
+$BR
+\(P(A)\) = \{ NAMED_ANS_RULE("pA2",12) \}
+$PAR
+If they are the same, then knowing "Female" does not change how likely "Arts" is.
+If they are different, then knowing "Female" does change the probability.
+END_TEXT
+
+Context("Numeric");
+NAMED_ANS("pAgF2", $val_pAgF->cmp());
+NAMED_ANS("pA2", $val_pA->cmp());
+Section::End();
+
+# ----------------------------------------------------------------
+# PILOT RATING
+# ----------------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+Rate the usefulness of this guided problem on a scale from 1 to 5.
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Rating: [__]{Real(3)->cmp(checker => sub {
+ my ($c,$s,$ans) = @_;
+ return 0 unless defined($s);
+ my $v = $s->value;
+ return ($v == int($v) && $v >= 1 && $v <= 5) ? 1 : 0;
+})}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem19.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem19.pg
new file mode 100644
index 0000000000..11d37f2a1f
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem19.pg
@@ -0,0 +1,286 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Conditional Probability from a 2x2 Table (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Conditional Probability)
+## Level(2)
+## KEYWORDS('probability','conditional probability','contingency table','independence','blood pressure','exercise')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Given joint proportions
+# E = exercises regularly
+# B = high blood pressure
+# =======================================================
+our $pEB = 0.06; # P(E and B)
+our $pEcB = 0.18; # P(not E and B)
+our $pEBc = 0.26; # P(E and not B)
+
+# Missing cell computed from total probability = 1
+our $pEcBc = 1 - ($pEB + $pEcB + $pEBc); # P(not E and not B)
+
+# Row/column totals
+our $pE = $pEB + $pEBc;
+our $pEc = $pEcB + $pEcBc;
+our $pB = $pEB + $pEcB;
+our $pBc = $pEBc + $pEcBc;
+
+# Conditional probabilities
+our $pBgE = $pEB / $pE; # P(B|E)
+our $pBgEc = $pEcB / $pEc; # P(B|not E)
+
+# =======================================================
+# Numeric comparators
+# =======================================================
+Context("Numeric");
+
+our $cmp_pEB = Real($pEB)->cmp( tolType => "absolute", tolerance => 0.001 );
+our $cmp_pEBc = Real($pEBc)->cmp( tolType => "absolute", tolerance => 0.001 );
+our $cmp_pEcB = Real($pEcB)->cmp( tolType => "absolute", tolerance => 0.001 );
+our $cmp_pEcBc = Real($pEcBc)->cmp( tolType => "absolute", tolerance => 0.001 );
+
+our $cmp_pE = Real($pE)->cmp( tolType => "absolute", tolerance => 0.001 );
+our $cmp_pEc = Real($pEc)->cmp( tolType => "absolute", tolerance => 0.001 );
+our $cmp_pB = Real($pB)->cmp( tolType => "absolute", tolerance => 0.001 );
+our $cmp_pBc = Real($pBc)->cmp( tolType => "absolute", tolerance => 0.001 );
+our $cmp_one = Real(1)->cmp( tolType => "absolute", tolerance => 0.001 );
+
+our $cmp_pBgE = Real($pBgE)->cmp( tolType => "absolute", tolerance => 0.001 );
+our $cmp_pBgEc = Real($pBgEc)->cmp( tolType => "absolute", tolerance => 0.001 );
+
+# Conclusion MC (correct: non-exercisers more likely to have high BP)
+our $rb_conclusion = RadioButtons(
+ [
+ "People who exercise regularly tend to have high blood pressure more often.",
+ "People who do not exercise regularly tend to have high blood pressure more often.",
+ "There is no difference (the probabilities are the same).",
+ ],
+ 1, # 0-based index => option B
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Rating checker (integer 1..5)
+# =======================================================
+our ($rating, $rating_cmp);
+
+if ($ENABLE_GP_RATING) {
+
+ $rating = Real(3); # placeholder only
+
+ $rating_cmp = $rating->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ if (!defined($student)) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ my $val;
+ eval { $val = $student->value; };
+ if (!defined($val)) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ my $ival = int($val);
+ if (abs($val - $ival) > 1e-12) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ if ($ival < 1 || $ival > 5) {
+ $ansHash->{ans_message} = "Your rating must be 1, 2, 3, 4, or 5.";
+ return 0;
+ }
+
+ return 1;
+ }
+ );
+}
+
+# =======================================================
+# Scaffold (sequential gating)
+# =======================================================
+Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ hardcopy_is_open => "always",
+);
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+
+BEGIN_TEXT
+Suppose that in an adult population the proportion of people who exercise regularly and have high blood pressure is \(0.06\).
+The proportion of people who do not exercise regularly but have high blood pressure is \(0.18\).
+The proportion of people who exercise regularly but do not have high blood pressure is \(0.26\).
+$PAR
+An adult is randomly selected from this population.
+$PAR
+Let:
+$BR
+\(E\): the person exercises regularly
+$BR
+\(B\): the person has high blood pressure
+$PAR
+We will compute:
+$BR
+(a) \(P(B \mid E)\)
+$BR
+(b) \(P(B \mid E^c)\)
+$BR
+(c) Compare the two results.
+END_TEXT
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Complete the 2x2 table");
+
+BEGIN_TEXT
+Complete the contingency table below. Enter probabilities as decimals (or fractions).
+$PAR
+Hint: The missing cell can be found because the four joint probabilities must add up to 1.
+$PAR
+
+
+
+ |
+ High blood pressure \(B\) |
+ No high blood pressure \(B^c\) |
+ Row total |
+
+
+
+ | Exercises \(E\) |
+ \{ NAMED_ANS_RULE("pEB",8) \} |
+ \{ NAMED_ANS_RULE("pEBc",8) \} |
+ \{ NAMED_ANS_RULE("pE",8) \} |
+
+
+
+ | Does not exercise \(E^c\) |
+ \{ NAMED_ANS_RULE("pEcB",8) \} |
+ \{ NAMED_ANS_RULE("pEcBc",8) \} |
+ \{ NAMED_ANS_RULE("pEc",8) \} |
+
+
+
+ | Column total |
+ \{ NAMED_ANS_RULE("pB",8) \} |
+ \{ NAMED_ANS_RULE("pBc",8) \} |
+ \{ NAMED_ANS_RULE("pTot",8) \} |
+
+
+END_TEXT
+
+Context("Numeric");
+NAMED_ANS("pEB", $cmp_pEB);
+NAMED_ANS("pEBc", $cmp_pEBc);
+NAMED_ANS("pEcB", $cmp_pEcB);
+NAMED_ANS("pEcBc", $cmp_pEcBc);
+
+NAMED_ANS("pE", $cmp_pE);
+NAMED_ANS("pEc", $cmp_pEc);
+NAMED_ANS("pB", $cmp_pB);
+NAMED_ANS("pBc", $cmp_pBc);
+NAMED_ANS("pTot", $cmp_one);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Part (a): P(B given E)");
+
+BEGIN_TEXT
+Find \(P(B \mid E)\): the probability the person has high blood pressure given that they exercise regularly.
+$PAR
+Hint: "Given \(E\)" means restrict the sample space to the \(E\) row only.
+Inside that row, compare the high-blood-pressure cell to the row total.
+$PAR
+\(P(B \mid E)\) = \(\dfrac{P(B \cap E)}{P(E)}\) = \{ NAMED_ANS_RULE("pBgE",12) \}
+END_TEXT
+
+Context("Numeric");
+NAMED_ANS("pBgE", $cmp_pBgE);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Part (b): P(B given not E)");
+
+BEGIN_TEXT
+Find \(P(B \mid E^c)\): the probability the person has high blood pressure given that they do not exercise regularly.
+$PAR
+Hint: "Given \(E^c\)" means restrict the sample space to the \(E^c\) row only.
+Inside that row, compare the high-blood-pressure cell to the row total.
+$PAR
+\(P(B \mid E^c)\) = \(\dfrac{P(B \cap E^c)}{P(E^c)}\) = \{ NAMED_ANS_RULE("pBgEc",12) \}
+END_TEXT
+
+Context("Numeric");
+NAMED_ANS("pBgEc", $cmp_pBgEc);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Part (c): Compare and conclude");
+
+BEGIN_TEXT
+Compare your answers from parts (a) and (b).
+$PAR
+Which conclusion is supported by the probabilities you found?
+$PAR
+\{ $rb_conclusion->buttons \}
+END_TEXT
+
+ANS($rb_conclusion->cmp());
+
+Section::End();
+
+# ----------------------------------------------------------------
+# PILOT RATING
+# ----------------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+
+ Section::Begin("Feedback");
+ BEGIN_PGML
+Rate the usefulness of this guided problem on a scale from 1 to 5.
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating: [__]{$rating_cmp}
+END_PGML
+ Section::End();
+
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem2.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem2.pg
new file mode 100644
index 0000000000..010233a81e
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem2.pg
@@ -0,0 +1,273 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Sample Spaces & Events (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Sample Spaces and Events)
+## Level(2)
+## KEYWORDS('probability','sample space','event','random experiment','trial','free throws')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "contextString.pl",
+ "scaffold.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1; # set to 0 to hide/remove the rating step
+
+# =======================================================
+# Set-entry evaluators (order doesn't matter)
+# =======================================================
+Context("String");
+
+# Critical: allow comma-separated lists of strings to be parsed as a List
+Context()->operators->redefine(',', using => ',');
+
+# Allowed outcomes for "number of successes in 5 shots"
+Context()->strings->add(
+ "0" => {}, "1" => {}, "2" => {}, "3" => {}, "4" => {}, "5" => {},
+);
+
+$correctS = List( String("0"), String("1"), String("2"), String("3"), String("4"), String("5") );
+$correctE = List( String("4"), String("5") ); # at least 4 successes
+
+# =======================================================
+# Rating evaluator (integer 1–5)
+# =======================================================
+Context("Numeric");
+$cmp_rating = Real(1)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return ($v >= 1 && $v <= 5) ? 1 : 0;
+ }
+);
+
+# Switch back to String for the rest of the problem display/inputs
+Context("String");
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ hardcopy_is_open => "always",
+);
+
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_TEXT
+A random college student is given 5 free basketball shots.
+$PAR
+We record the number of made shots (the number of successes).
+END_TEXT
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Build the definitions");
+BEGIN_TEXT
+For each blank, choose the best option by typing its letter (A, B, or C).
+$PAR
+
+Complete the description of a random experiment:
+$BR
+A random experiment is a (1) ____ process that can be (2) ____ under the same conditions.
+It has a (3) ____ list of possible outcomes, but the result of one run cannot be predicted with (4) ____ in advance.
+$PAR
+
+(1)
+$BR
+A) confusing B) well-specified C) imaginary
+$BR
+Answer: \{ ans_rule(2) \}
+$PAR
+
+(2)
+$BR
+A) erased B) hidden C) repeated
+$BR
+Answer: \{ ans_rule(2) \}
+$PAR
+
+(3)
+$BR
+A) secret B) known C) random
+$BR
+Answer: \{ ans_rule(2) \}
+$PAR
+
+(4)
+$BR
+A) sarcasm B) volume C) certainty
+$BR
+Answer: \{ ans_rule(2) \}
+$PAR
+
+The set of all possible outcomes is called the (5) ____.
+$BR
+A) average B) sample space C) trial
+$BR
+Answer: \{ ans_rule(2) \}
+$PAR
+
+One performance of the experiment is called a (6) ____.
+$BR
+A) equation B) outcome C) trial
+$BR
+Answer: \{ ans_rule(2) \}
+$PAR
+
+An event is a (7) ____ of the sample space.
+$BR
+A) subset B) decimal C) fraction
+$BR
+Answer: \{ ans_rule(2) \}
+$PAR
+
+We say an event (8) ____ when the observed outcome is inside that event.
+$BR
+A) multiplies B) evaporates C) occurs
+$BR
+Answer: \{ ans_rule(2) \}
+END_TEXT
+
+ANS( str_cmp("B") ); # (1) well-specified
+ANS( str_cmp("C") ); # (2) repeated
+ANS( str_cmp("B") ); # (3) known
+ANS( str_cmp("C") ); # (4) certainty
+ANS( str_cmp("B") ); # (5) sample space
+ANS( str_cmp("C") ); # (6) trial
+ANS( str_cmp("A") ); # (7) subset
+ANS( str_cmp("C") ); # (8) occurs
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Identify the random experiment");
+BEGIN_TEXT
+Which option correctly describes the random experiment in this situation?
+$PAR
+A) Give a random college student free shots until the first made shot, and record how many shots it took (number of trials until first success).
+$BR
+B) Give a random college student 5 free shots and record the number of made shots out of 5.
+$BR
+C) Give a random college student 5 free shots and record the time (in seconds) between shots.
+$PAR
+Answer (A/B/C): \{ ans_rule(2) \}
+END_TEXT
+
+ANS( str_cmp("B") );
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Construct the sample space");
+BEGIN_TEXT
+The outcome is the number of made shots out of 5.
+$PAR
+Enter the sample space outcomes as a comma-separated list. Order does not matter.
+$BR
+Do not type braces.
+$PAR
+S = { \{ ans_rule(30) \} }
+END_TEXT
+
+ANS( $correctS->cmp(ignoreOrder => 1) );
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Define an event");
+BEGIN_TEXT
+Let E be the event: "At least 4 successful shots".
+$PAR
+Enter the outcomes in E as a comma-separated list. Order does not matter.
+$BR
+Do not type braces.
+$PAR
+E = { \{ ans_rule(20) \} }
+END_TEXT
+
+ANS( $correctE->cmp(ignoreOrder => 1) );
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Which event occurred?");
+BEGIN_TEXT
+Suppose the student made 3 shots out of 5.
+$PAR
+Which one of the events below occurred?
+$PAR
+
+A) The student made at least 4 shots.
+$BR
+Set form: { 4, 5 }
+$PAR
+
+B) The student missed at least one shot.
+$BR
+Set form: { 0, 1, 2, 3, 4 }
+$PAR
+
+C) The student made exactly 0 shots.
+$BR
+Set form: { 0 }
+$PAR
+
+D) The student made at most 2 shots.
+$BR
+Set form: { 0, 1, 2 }
+$PAR
+
+Answer (A/B/C/D): \{ ans_rule(2) \}
+END_TEXT
+
+ANS( str_cmp("B") );
+
+Section::End();
+
+# ----------------------------------------------------------------
+# PILOT RATING (ACTIVE)
+# ----------------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+
+ Section::Begin("Feedback");
+ BEGIN_TEXT
+Rate the usefulness of this guided problem on a scale from 1 to 5.
+$PAR
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+$BR
+Note: Consider using the Email Instructor button below to suggest improvements.
+$PAR
+Rating: \{ ans_rule(6) \}
+END_TEXT
+
+ Context("Numeric");
+ ANS($cmp_rating);
+ Context("String");
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem20.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem20.pg
new file mode 100644
index 0000000000..305ff46ae7
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem20.pg
@@ -0,0 +1,329 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Sensitivity and Independent Testing (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Conditional Probability and Independence)
+## Level(2)
+## KEYWORDS('probability','independence','sensitivity','complement rule','diagnostic test')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "contextString.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Parameters (given)
+# =======================================================
+our $sens = 0.92; # sensitivity = P(positive | disease)
+our $neg = 1 - $sens; # P(negative | disease)
+
+# Values used only for answer checking (not displayed)
+our $p_PP = $sens * $sens; # P(A ∩ B)
+our $p_NN = $neg * $neg; # P(A^c ∩ B^c)
+our $p_atleast1 = 1 - $p_NN; # P(E) where E = at least one positive
+
+# =======================================================
+# Numeric answer evaluators
+# =======================================================
+Context("Numeric");
+
+our $cmp_pPP = Real($p_PP)->cmp( tolType => "absolute", tolerance => 0.001 );
+our $cmp_pNN = Real($p_NN)->cmp( tolType => "absolute", tolerance => 0.001 );
+our $cmp_pE = Real($p_atleast1)->cmp( tolType => "absolute", tolerance => 0.001 );
+
+# =======================================================
+# Set/List context for sample space outcomes: NN, NP, PN, PP
+# =======================================================
+our $ctxSet = Context("String");
+$ctxSet->operators->redefine(',', using => ',');
+
+our %allowed = map { $_ => {} } qw(NN NP PN PP);
+$allowed{"none"} = { caseSensitive => 0 };
+$ctxSet->strings->add(%allowed);
+
+# =======================================================
+# MC: independence intersection rule (5 options; correct is D)
+# =======================================================
+our $rb_indep_rule = RadioButtons(
+ [
+ '\(P(A \cap B)=P(A)+P(B)\)',
+ '\(P(A \cap B)=P(A)-P(B)\)',
+ '\(P(A \cap B)=P(A)/P(B)\)',
+ '\(P(A \cap B)=P(A)P(B)\)',
+ '\(P(A \cap B)=P(A \cup B)\)',
+ ],
+ 3, # 0-based index => D
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# MC: why complement makes sense (5 options; correct is C)
+# =======================================================
+our $rb_complement = RadioButtons(
+ [
+ "Because it makes the arithmetic look nicer, even if it changes the event.",
+ "Because 'at least one positive' is impossible to compute directly.",
+ "Because the complement is the single outcome NN (both negative), which is easier to compute.",
+ "Because complements only work when events are independent.",
+ "Because it guarantees the answer will be close to 1.",
+ ],
+ 2, # 0-based index => C
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# MC: moral (5 options; correct is B)
+# =======================================================
+our $rb_moral = RadioButtons(
+ [
+ "Doing the test twice guarantees detection.",
+ "Getting tested independently at two labs increases the chance of detection.",
+ "Two tests always cancel each other out, so it does not matter.",
+ "If one test is negative, the other must be positive.",
+ "Sensitivity only matters when the person does not have the disease.",
+ ],
+ 1, # 0-based index => B
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Scaffold (sequential gating)
+# =======================================================
+Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ hardcopy_is_open => "always",
+);
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+
+BEGIN_TEXT
+Many diagnostic tests for detecting diseases do not test for the disease directly but for a chemical or biological product of the disease, so they are not perfectly reliable.
+The sensitivity of a test is the probability that the test will be positive when administered to a person who actually has the disease.
+$PAR
+Suppose the sensitivity of a diagnostic procedure is \(92\%\).
+A person who actually has the disease is tested by two independent laboratories.
+$PAR
+Let:
+$BR
+\(A\): Lab 1 result is positive (for a person who actually has the disease)
+$BR
+\(B\): Lab 2 result is positive (for a person who actually has the disease)
+$PAR
+(a) What is the probability that both test results will be positive?
+$BR
+(b) What is the probability that at least one of the two test results will be positive?
+END_TEXT
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Interpret sensitivity and independence");
+
+BEGIN_TEXT
+Since the person actually has the disease, the sensitivity \(0.92\) applies directly to each lab:
+$BR
+\(P(A)=0.92\) and \(P(B)=0.92\).
+$PAR
+The labs are independent, meaning the result from one lab does not affect the other.
+So knowing whether \(A\) happened does not change how likely \(B\) is (and vice versa).
+END_TEXT
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Independence and the intersection rule");
+
+BEGIN_TEXT
+If we want the probability that both labs are positive, we want the probability that \(A\) and \(B\) happen together.
+That event is the intersection \(A \cap B\).
+$PAR
+Because the labs are independent, \(A\) and \(B\) are independent events.
+$PAR
+Checkpoint: If \(A\) and \(B\) are independent, which equation should we use?
+$PAR
+\{ $rb_indep_rule->buttons \}
+END_TEXT
+
+ANS($rb_indep_rule->cmp());
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Part (a): both test results positive");
+
+BEGIN_TEXT
+Compute the probability that both test results are positive.
+$PAR
+Hint: Use the independence equation from the previous step with \(P(A)=0.92\) and \(P(B)=0.92\).
+$PAR
+\(P(A \cap B)\) = \{ NAMED_ANS_RULE("pPP",12) \}
+END_TEXT
+
+Context("Numeric");
+NAMED_ANS("pPP", $cmp_pPP);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Sample space and event E");
+
+BEGIN_TEXT
+For two tests, each lab result can be Positive (P) or Negative (N). For example, both positive can be denoted as PP.
+$PAR
+List the sample space outcomes (comma-separated, order does not matter):
+$BR
+\{ NAMED_ANS_RULE("S",40) \}
+$PAR
+Now define the event:
+$BR
+\(E\): at least one positive test result
+END_TEXT
+
+Context($ctxSet);
+NAMED_ANS("S", List(map { String($_) } qw(NN NP PN PP))->cmp(ignoreOrder => 1));
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Why the complement helps");
+
+BEGIN_TEXT
+We want \(P(E)\), where \(E\) means "at least one positive."
+$PAR
+Checkpoint: Why does it make sense to use the complement here?
+$PAR
+\{ $rb_complement->buttons \}
+$PAR
+The complement of "at least one positive" is "no positives," meaning both negative, which is the single outcome NN.
+$PAR
+Also, NN means:
+$BR
+Lab 1 is negative AND Lab 2 is negative.
+So:
+$BR
+\(P(NN)=P(A^c \cap B^c)\).
+END_TEXT
+
+ANS($rb_complement->cmp());
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Part (b): at least one positive");
+
+BEGIN_TEXT
+Now compute the probability that at least one of the two test results is positive.
+$PAR
+Hint:
+$BR
+\(P(E)=1-P(E^c)\), and \(E^c\) is NN.
+$BR
+Also, \(P(NN)=P(A^c \cap B^c)\), and since the labs are independent, you can multiply:
+\(P(A^c \cap B^c)=P(A^c)P(B^c)\).
+$PAR
+\(P(NN)\) = \{ NAMED_ANS_RULE("pNN",12) \}
+$PAR
+\(P(E)\) = \{ NAMED_ANS_RULE("pE",12) \}
+END_TEXT
+
+Context("Numeric");
+NAMED_ANS("pNN", $cmp_pNN);
+NAMED_ANS("pE", $cmp_pE);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Moral of the story");
+
+BEGIN_TEXT
+Checkpoint: What is the moral of these calculations?
+$PAR
+\{ $rb_moral->buttons \}
+END_TEXT
+
+ANS($rb_moral->cmp());
+
+Section::End();
+
+# ----------------------------------------------------------------
+# PILOT RATING (FIXED: force Numeric context inside the block)
+# ----------------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+
+ Section::Begin("Feedback");
+
+ Context("Numeric");
+
+ our $rating = Real(3); # placeholder only
+
+ our $rating_cmp = $rating->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ if (!defined($student)) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ my $val;
+ eval { $val = $student->value; };
+ if (!defined($val)) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ my $ival = int($val);
+ if (abs($val - $ival) > 1e-12) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ if ($ival < 1 || $ival > 5) {
+ $ansHash->{ans_message} = "Your rating must be 1, 2, 3, 4, or 5.";
+ return 0;
+ }
+
+ return 1;
+ }
+ );
+
+ BEGIN_PGML
+Rate the usefulness of this guided problem on a scale from 1 to 5.
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating: [__]{$rating_cmp}
+END_PGML
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem21.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem21.pg
new file mode 100644
index 0000000000..7396324839
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem21.pg
@@ -0,0 +1,265 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Specificity and False Positives (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Conditional Probability and Independence)
+## Level(2)
+## KEYWORDS('probability','independence','specificity','false positive','complement rule','diagnostic test')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Parameters
+# specificity = P(negative | no disease)
+# For a person with no disease:
+# P(positive) = 1 - specificity (false positive rate)
+# =======================================================
+our $spec = 0.89;
+our $pA = 1 - $spec; # P(A) = Lab 1 positive (false positive)
+our $pB = 1 - $spec; # P(B) = Lab 2 positive (false positive), same procedure
+
+our $pAiB = $pA * $pB; # P(A ∩ B) for independent labs
+
+# =======================================================
+# Numeric comparators
+# =======================================================
+Context("Numeric");
+
+our $cmp_pA = Real($pA)->cmp( tolType => "absolute", tolerance => 0.001 );
+our $cmp_pAiB = Real($pAiB)->cmp( tolType => "absolute", tolerance => 0.001 );
+
+# =======================================================
+# Moral MC (5 options; correct is D to vary)
+# =======================================================
+our $rb_moral = RadioButtons(
+ [
+ "Getting tested twice guarantees you will never get a false positive.",
+ "Testing at two labs increases the chance of a false positive.",
+ "Specificity is the probability the test is positive for a healthy person.",
+ "Getting tested at two independent labs decreases the chance of false positives significantly.",
+ "Independence means the two labs always give the same result.",
+ ],
+ 3, # 0-based index => D
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Rating checker (integer 1..5)
+# =======================================================
+our ($rating, $rating_cmp);
+
+if ($ENABLE_GP_RATING) {
+
+ $rating = Real(3); # placeholder only
+
+ $rating_cmp = $rating->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ if (!defined($student)) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ my $val;
+ eval { $val = $student->value; };
+ if (!defined($val)) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ my $ival = int($val);
+ if (abs($val - $ival) > 1e-12) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ if ($ival < 1 || $ival > 5) {
+ $ansHash->{ans_message} = "Your rating must be 1, 2, 3, 4, or 5.";
+ return 0;
+ }
+
+ return 1;
+ }
+ );
+}
+
+# =======================================================
+# Scaffold (sequential gating)
+# =======================================================
+Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ hardcopy_is_open => "always",
+);
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+
+BEGIN_TEXT
+The specificity of a diagnostic test for a disease is the probability that the test will be negative when administered to a person who does not have the disease.
+The higher the specificity, the lower the false positive rate.
+$PAR
+Suppose the specificity of a diagnostic procedure is \(89\%\).
+$PAR
+A person who does not have the disease is tested for it using this procedure.
+$PAR
+Define events:
+$BR
+\(A\): Lab 1 result is positive (for a person who does not have the disease)
+$BR
+\(B\): Lab 2 result is positive (for a person who does not have the disease)
+$PAR
+(a) What is the probability that the test result will be positive?
+$BR
+(b) If two independent laboratories test the person, what is the probability that both test results will be positive?
+END_TEXT
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Translate specificity into P(A)");
+
+BEGIN_TEXT
+Since the person does not have the disease, the specificity \(0.89\) means:
+$BR
+The probability the test is negative is \(0.89\).
+$PAR
+A positive result is the opposite of a negative result in this situation.
+So the probability of a positive result is the complement.
+END_TEXT
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Part (a): one lab false positive");
+
+BEGIN_TEXT
+Compute the probability that the test result is positive.
+$PAR
+In our notation, this is \(P(A)\).
+$PAR
+Hint: Use the complement of the specificity.
+$PAR
+\(P(A)\) = \{ NAMED_ANS_RULE("pA",12) \}
+END_TEXT
+
+Context("Numeric");
+NAMED_ANS("pA", $cmp_pA);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Part (b): two independent labs both positive");
+
+BEGIN_TEXT
+Now suppose two independent laboratories test the person using this procedure.
+$PAR
+We want the probability that both results are positive.
+That event is \(A \cap B\).
+$PAR
+Hint: Independence means Lab 1 being positive does not affect the probability Lab 2 is positive.
+So you can multiply the probabilities.
+Also, both labs use the same procedure, so \(P(A)=P(B)\).
+$PAR
+\(P(A \cap B)\) = \{ NAMED_ANS_RULE("pAiB",12) \}
+END_TEXT
+
+Context("Numeric");
+NAMED_ANS("pAiB", $cmp_pAiB);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Moral of the story");
+
+BEGIN_TEXT
+Checkpoint: What is the moral of the story?
+$PAR
+\{ $rb_moral->buttons \}
+END_TEXT
+
+ANS($rb_moral->cmp());
+
+Section::End();
+
+# ----------------------------------------------------------------
+# PILOT RATING (fixed: keep Numeric inside the block)
+# ----------------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+
+ Section::Begin("Feedback");
+
+ Context("Numeric");
+
+ our $rating = Real(3); # placeholder only
+
+ our $rating_cmp = $rating->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ if (!defined($student)) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ my $val;
+ eval { $val = $student->value; };
+ if (!defined($val)) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ my $ival = int($val);
+ if (abs($val - $ival) > 1e-12) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ if ($ival < 1 || $ival > 5) {
+ $ansHash->{ans_message} = "Your rating must be 1, 2, 3, 4, or 5.";
+ return 0;
+ }
+
+ return 1;
+ }
+ );
+
+ BEGIN_PGML
+Rate the usefulness of this guided problem on a scale from 1 to 5.
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating: [__]{$rating_cmp}
+END_PGML
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem22.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem22.pg
new file mode 100644
index 0000000000..d06c50b4ee
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem22.pg
@@ -0,0 +1,277 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Redundancy and Detection (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Independence)
+## Level(2)
+## KEYWORDS('probability','independence','complement rule','redundancy','reliability','detection')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "contextString.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Parameters
+# Each dog detects contraband (given contraband is present) with p = 0.90
+# Three independent dogs
+# =======================================================
+our $p_detect = 0.90;
+our $p_fail = 1 - $p_detect;
+
+our $p_none = $p_fail * $p_fail * $p_fail; # P(NNN) = P(A^c ∩ B^c ∩ C^c)
+our $p_detected = 1 - $p_none; # P(E) = 1 - P(E^c)
+
+# =======================================================
+# Numeric evaluators
+# =======================================================
+Context("Numeric");
+
+our $cmp_p_none = Real($p_none)->cmp( tolType => "absolute", tolerance => 0.001 );
+our $cmp_p_detected = Real($p_detected)->cmp( tolType => "absolute", tolerance => 0.001 );
+
+# =======================================================
+# String context for sample space outcomes (8 outcomes)
+# =======================================================
+our $ctxSet = Context("String");
+$ctxSet->operators->redefine(',', using => ',');
+
+our %allowed = map { $_ => {} } qw(NNN NND NDN NDD DNN DND DDN DDD);
+$allowed{"none"} = { caseSensitive => 0 };
+$ctxSet->strings->add(%allowed);
+
+# =======================================================
+# Moral MC (5 options; correct is C)
+# =======================================================
+our $rb_moral = RadioButtons(
+ [
+ "Redundancy guarantees detection, so the probability becomes 1.",
+ "Independence makes redundancy useless because the dogs do not communicate.",
+ "Independent redundancy increases reliability because the chance that all devices fail at the same time is much smaller than one device failing in a system with no redundancy.",
+ "Redundancy only helps if the dogs are dependent (influenced by each other).",
+ "With three dogs, the probability of detection is the same as with one dog.",
+ ],
+ 2, # 0-based index => C
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Rating checker (integer 1..5)
+# =======================================================
+our ($rating, $rating_cmp);
+
+# =======================================================
+# Scaffold (sequential gating)
+# =======================================================
+Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ hardcopy_is_open => "always",
+);
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+
+BEGIN_TEXT
+The reliability of a system can be enhanced by redundancy, which means building two or more independent devices to do the same job.
+For example, an automobile may have two independent braking systems.
+$PAR
+Suppose a particular species of trained dogs has a \(90\%\) chance of detecting contraband in airline luggage.
+Assume contraband is present in the luggage.
+If the luggage is checked three times by three different dogs independently of one another, what is the probability that contraband will be detected?
+$PAR
+Define events:
+$BR
+\(A\): Dog 1 detects contraband (given contraband is present in the luggage)
+$BR
+\(B\): Dog 2 detects contraband (given contraband is present in the luggage)
+$BR
+\(C\): Dog 3 detects contraband (given contraband is present in the luggage)
+END_TEXT
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("What event are we trying to compute?");
+
+BEGIN_TEXT
+Contraband is detected if at least one dog detects it.
+So the event we care about is:
+$BR
+\(E\): "contraband is detected"
+$PAR
+In event notation, that means at least one of \(A\), \(B\), or \(C\) happens.
+END_TEXT
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Sample space outcomes and why complement helps");
+
+BEGIN_TEXT
+For each dog, there are only two outcomes:
+$BR
+D = detects
+$BR
+N = does not detect
+$PAR
+List all outcomes in the sample space for three dogs. For example all dogs detect can be denoted as DDD. (comma-separated, order does not matter):
+$BR
+\{ NAMED_ANS_RULE("S",80) \}
+$PAR
+Now define \(E\) as the event "contraband is detected" (at least one D).
+$PAR
+Key idea: It is easier to compute \(P(E)\) using the complement,
+because \(E\) contains many outcomes, while the complement is only one outcome.
+END_TEXT
+
+# Create set comparator just-in-time under String context (BP rule)
+Context($ctxSet);
+NAMED_ANS(
+ "S",
+ List(map { String($_) } qw(NNN NND NDN NDD DNN DND DDN DDD))->cmp(ignoreOrder => 1)
+);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Complement event");
+
+BEGIN_TEXT
+The complement of \(E\) is:
+$BR
+\(E^c\): "contraband is not detected"
+$PAR
+That happens only if all three dogs fail.
+In outcome notation, that is the single outcome:
+$BR
+NNN
+$PAR
+Also, NNN means:
+$BR
+Dog 1 fails AND Dog 2 fails AND Dog 3 fails.
+So:
+$BR
+\(P(NNN)=P(A^c \cap B^c \cap C^c)\).
+END_TEXT
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Compute P(E^c) and then P(E)");
+
+BEGIN_TEXT
+Each dog detects with probability \(0.90\), so each dog fails with probability \(1-0.90\).
+$PAR
+Because the dogs are independent, you can multiply the failure probabilities:
+$BR
+\(P(E^c)=P(A^c \cap B^c \cap C^c)=P(A^c)P(B^c)P(C^c)\).
+$PAR
+Compute:
+$PAR
+\(P(E^c)\) = \{ NAMED_ANS_RULE("pNone",12) \}
+$PAR
+Then use the complement rule:
+$BR
+\(P(E)=1-P(E^c)\).
+$PAR
+\(P(E)\) = \{ NAMED_ANS_RULE("pDetect",12) \}
+END_TEXT
+
+Context("Numeric");
+NAMED_ANS("pNone", $cmp_p_none);
+NAMED_ANS("pDetect", $cmp_p_detected);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Moral of the story");
+
+BEGIN_TEXT
+Checkpoint: What is the moral of the story?
+$PAR
+\{ $rb_moral->buttons \}
+END_TEXT
+
+ANS($rb_moral->cmp());
+
+Section::End();
+
+# ----------------------------------------------------------------
+# PILOT RATING (fixed: force Numeric inside the block)
+# ----------------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+
+ Section::Begin("Feedback");
+
+ Context("Numeric");
+
+ $rating = Real(3); # placeholder only
+
+ $rating_cmp = $rating->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ if (!defined($student)) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ my $val;
+ eval { $val = $student->value; };
+ if (!defined($val)) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ my $ival = int($val);
+ if (abs($val - $ival) > 1e-12) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ if ($ival < 1 || $ival > 5) {
+ $ansHash->{ans_message} = "Your rating must be 1, 2, 3, 4, or 5.";
+ return 0;
+ }
+
+ return 1;
+ }
+ );
+
+ BEGIN_PGML
+Rate the usefulness of this guided problem on a scale from 1 to 5.
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating: [__]{$rating_cmp}
+END_PGML
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem23.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem23.pg
new file mode 100644
index 0000000000..6a3337a7f2
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem23.pg
@@ -0,0 +1,283 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Probabilities on Tree Diagrams (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Conditional Probability)
+## Level(2)
+## KEYWORDS('probability','tree diagram','conditional probability','without replacement','marbles')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "contextString.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Parameters (Values only)
+# =======================================================
+Context("Numeric");
+our $pB1 = Real(7/10);
+our $pW1 = Real(3/10);
+
+our $pB2gB1 = Real(6/9);
+our $pW2gB1 = Real(3/9);
+
+our $pB2gW1 = Real(7/9);
+our $pW2gW1 = Real(2/9);
+
+our $pBB = Real($pB1 * $pB2gB1);
+our $pBW = Real($pB1 * $pW2gB1);
+our $pWB = Real($pW1 * $pB2gW1);
+our $pWW = Real($pW1 * $pW2gW1);
+
+our $p_exact1B = Real($pBW + $pWB);
+our $p_atleast1B = Real(1 - $pWW);
+
+# =======================================================
+# Wrap-up MC (tree reading)
+# =======================================================
+our $rb_path = RadioButtons(
+ [ "BB", "BW", "WB", "WW", "none of these" ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Scaffold (sequential gating)
+# =======================================================
+Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ hardcopy_is_open => "always",
+);
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+
+BEGIN_TEXT
+A jar contains 10 marbles: 7 black (B) and 3 white (W).
+Two marbles are drawn without replacement, meaning the first marble is not put back before the second draw.
+$PAR
+a) What is the probability that both marbles are black?
+$BR
+b) What is the probability that exactly one marble is black?
+$BR
+c) What is the probability that at least one marble is black?
+$PAR
+To keep the notation clear:
+$BR
+\(B_1\): first draw is black, \(\;W_1\): first draw is white
+$BR
+\(B_2\): second draw is black, \(\;W_2\): second draw is white
+END_TEXT
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Sample space outcomes");
+
+BEGIN_TEXT
+List all 4 outcomes of this experiment using codes like BB (both Black):
+$PAR
+Enter the sample space outcomes (comma-separated, order does not matter). Do not type braces.
+$BR
+\{ NAMED_ANS_RULE("S",40) \}
+$PAR
+Note that \(P(BB)=P(B_1 \text{ and } B_2)\).
+END_TEXT
+
+# Local String context definition
+Context("String");
+Context()->operators->redefine(',', using => ',');
+Context()->strings->add(BB=>{}, BW=>{}, WB=>{}, WW=>{});
+NAMED_ANS("S", List(map { String($_) } qw(BB BW WB WW))->cmp(ignoreOrder => 1));
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Compute the probability of each outcome");
+
+BEGIN_TEXT
+Enter probabilities as a fraction or a decimal.
+$PAR
+Outcome BB
+$BR
+\(P(BB)=P(B_1 \text{ and } B_2)=P(B_1 \cap B_2)=P(B_2 \mid B_1)\,P(B_1)\)
+$PAR
+\(P(B_2 \mid B_1)=\) \{ NAMED_ANS_RULE("pB2gB1",12) \}
+$BR
+\(P(B_1)=\) \{ NAMED_ANS_RULE("pB1",12) \}
+$BR
+\(P(BB)=\) \{ NAMED_ANS_RULE("pBB",12) \}
+$PAR
+
+Outcome BW
+$BR
+\(P(BW)=P(B_1 \text{ and } W_2)=P(W_2 \mid B_1)\,P(B_1)\)
+$PAR
+\(P(W_2 \mid B_1)=\) \{ NAMED_ANS_RULE("pW2gB1",12) \}
+$BR
+\(P(B_1)=\) \{ NAMED_ANS_RULE("pB1b",12) \}
+$BR
+\(P(BW)=\) \{ NAMED_ANS_RULE("pBW",12) \}
+$PAR
+
+Outcome WB
+$BR
+\(P(WB)=P(W_1 \text{ and } B_2)=P(B_2 \mid W_1)\,P(W_1)\)
+$PAR
+\(P(B_2 \mid W_1)=\) \{ NAMED_ANS_RULE("pB2gW1",12) \}
+$BR
+\(P(W_1)=\) \{ NAMED_ANS_RULE("pW1",12) \}
+$BR
+\(P(WB)=\) \{ NAMED_ANS_RULE("pWB",12) \}
+$PAR
+
+Outcome WW
+$BR
+\(P(WW)=P(W_1 \text{ and } W_2)=P(W_2 \mid W_1)\,P(W_1)\)
+$PAR
+\(P(W_2 \mid W_1)=\) \{ NAMED_ANS_RULE("pW2gW1",12) \}
+$BR
+\(P(W_1)=\) \{ NAMED_ANS_RULE("pW1b",12) \}
+$BR
+\(P(WW)=\) \{ NAMED_ANS_RULE("pWW",12) \}
+$PAR
+
+Hints
+$BR
+Without replacement means the second draw is out of 9 marbles.
+$BR
+After a black first draw, there is one fewer black remaining.
+After a white first draw, there is one fewer white remaining.
+END_TEXT
+
+Context("Numeric");
+NAMED_ANS("pB2gB1", $pB2gB1->cmp(tolType => "absolute", tolerance => 0.001));
+NAMED_ANS("pB1", $pB1->cmp(tolType => "absolute", tolerance => 0.001));
+NAMED_ANS("pBB", $pBB->cmp(tolType => "absolute", tolerance => 0.001));
+
+NAMED_ANS("pW2gB1", $pW2gB1->cmp(tolType => "absolute", tolerance => 0.001));
+NAMED_ANS("pB1b", $pB1->cmp(tolType => "absolute", tolerance => 0.001));
+NAMED_ANS("pBW", $pBW->cmp(tolType => "absolute", tolerance => 0.001));
+
+NAMED_ANS("pB2gW1", $pB2gW1->cmp(tolType => "absolute", tolerance => 0.001));
+NAMED_ANS("pW1", $pW1->cmp(tolType => "absolute", tolerance => 0.001));
+NAMED_ANS("pWB", $pWB->cmp(tolType => "absolute", tolerance => 0.001));
+
+NAMED_ANS("pW2gW1", $pW2gW1->cmp(tolType => "absolute", tolerance => 0.001));
+NAMED_ANS("pW1b", $pW1->cmp(tolType => "absolute", tolerance => 0.001));
+NAMED_ANS("pWW", $pWW->cmp(tolType => "absolute", tolerance => 0.001));
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Probability of exactly one black");
+
+BEGIN_TEXT
+Exactly one black means one black and one white in any order.
+So the successful outcomes are BW and WB.
+$PAR
+Compute:
+$BR
+\(P(\text{exactly one black}) = P(BW) + P(WB)\)
+$PAR
+Answer:
+$BR
+\{ NAMED_ANS_RULE("pExact1B",12) \}
+END_TEXT
+
+Context("Numeric");
+NAMED_ANS("pExact1B", $p_exact1B->cmp(tolType => "absolute", tolerance => 0.001));
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Probability of at least one black");
+
+BEGIN_TEXT
+At least one black means the outcome is not WW.
+So it is easiest to use the complement:
+$PAR
+\(P(\text{at least one black}) = 1 - P(WW)\)
+$PAR
+Answer:
+$BR
+\{ NAMED_ANS_RULE("pAtLeast1B",12) \}
+END_TEXT
+
+Context("Numeric");
+NAMED_ANS("pAtLeast1B", $p_atleast1B->cmp(tolType => "absolute", tolerance => 0.001));
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Tree diagram (wrap-up)");
+
+BEGIN_TEXT
+
+Here is a tree diagram for this experiment:
+$PAR
+\{ image("tree.jpg", width => 700) \}
+$PAR
+A tree diagram helps you do two things:
+$BR
+1) Identify the sample space outcomes (BB, BW, WB, WW) by reading off the paths.
+$BR
+2) Compute the probability of each outcome by multiplying along a path.
+$PAR
+For example, the BB path corresponds to \(P(B_2 \mid B_1)\) multiplied by \(P(B_1)\).
+$PAR
+Checkpoint: If the first draw is black and the second draw is white, which outcome label matches that path?
+$PAR
+\{ $rb_path->buttons \}
+END_TEXT
+
+ANS($rb_path->cmp());
+
+Section::End();
+
+# ----------------------------------------------------------------
+# PILOT RATING
+# ----------------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ Context("Numeric");
+ BEGIN_PGML
+Rate the usefulness of this guided problem on a scale from 1 to 5.
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Rating: [__]{Real(3)->cmp(checker => sub {
+ my ($correct,$student,$ansHash) = @_;
+ return 0 unless defined($student);
+ my $v = $student->value;
+ return ($v == int($v) && $v >= 1 && $v <= 5) ? 1 : 0;
+})}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem24.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem24.pg
new file mode 100644
index 0000000000..30e74339dc
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem24.pg
@@ -0,0 +1,234 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Probabilities With Replacement (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Conditional Probability)
+## Level(2)
+## KEYWORDS('probability','independence','with replacement','conditional probability','marbles')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "contextString.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Values (not displayed)
+# =======================================================
+Context("Numeric");
+
+our $pB = Real(7/10);
+our $pW = Real(3/10);
+
+our $pBB = Real($pB * $pB);
+our $pBW = Real($pB * $pW);
+our $pWB = Real($pW * $pB);
+our $pWW = Real($pW * $pW);
+
+our $p_exact1B = Real($pBW + $pWB);
+our $p_atleast1B = Real(1 - $pWW);
+
+# =======================================================
+# Scaffold (sequential gating)
+# =======================================================
+Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ hardcopy_is_open => "always",
+);
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+
+BEGIN_TEXT
+Jar has 10 marbles: 7 black (B) and 3 white (W).
+$PAR
+Two marbles are drawn with replacement.
+$PAR
+Define events for clear labeling:
+$BR
+\(B_1\) = “first draw is black”, \(\;W_1\) = “first draw is white”
+$BR
+\(B_2\) = “second draw is black”, \(\;W_2\) = “second draw is white”
+$PAR
+Tasks:
+$BR
+(a) \(P(\text{both black}) = P(B_1 \cap B_2)\)
+$BR
+(b) \(P(\text{exactly one black})\)
+$BR
+(c) \(P(\text{at least one black})\)
+END_TEXT
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Sample space outcomes");
+
+BEGIN_TEXT
+List all 4 outcomes of this experiment using codes like BB (both Black).
+$PAR
+Enter the sample space outcomes (comma-separated, order does not matter). Do not type braces.
+$BR
+\{ NAMED_ANS_RULE("S",40) \}
+END_TEXT
+
+# Local String context (just-in-time)
+Context("String");
+Context()->operators->redefine(',', using => ',');
+Context()->strings->add(BB=>{}, BW=>{}, WB=>{}, WW=>{});
+
+NAMED_ANS("S", List(map { String($_) } qw(BB BW WB WW))->cmp(ignoreOrder => 1));
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Compute the probability of each outcome");
+
+BEGIN_TEXT
+Because we draw with replacement, the jar is the same on each draw.
+So the second draw does not depend on the first draw.
+That means:
+$BR
+\(P(B_2 \mid B_1)=P(B_2)\)
+$PAR
+So the two draws are independent.
+Therefore:
+$BR
+\(P(BB)=P(B_1 \text{ and } B_2)=P(B_1 \cap B_2)=P(B_1)P(B_2)\)
+$PAR
+Enter each probability as a fraction or a decimal:
+$PAR
+\(P(BB)=\) \{ NAMED_ANS_RULE("pBB",12) \}
+$BR
+\(P(BW)=\) \{ NAMED_ANS_RULE("pBW",12) \}
+$BR
+\(P(WB)=\) \{ NAMED_ANS_RULE("pWB",12) \}
+$BR
+\(P(WW)=\) \{ NAMED_ANS_RULE("pWW",12) \}
+END_TEXT
+
+Context("Numeric");
+NAMED_ANS("pBB", $pBB->cmp(tolType => "absolute", tolerance => 0.001));
+NAMED_ANS("pBW", $pBW->cmp(tolType => "absolute", tolerance => 0.001));
+NAMED_ANS("pWB", $pWB->cmp(tolType => "absolute", tolerance => 0.001));
+NAMED_ANS("pWW", $pWW->cmp(tolType => "absolute", tolerance => 0.001));
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Probability of exactly one black");
+
+BEGIN_TEXT
+Exactly one black means one black and one white in any order.
+So the successful outcomes are BW and WB.
+$PAR
+Compute:
+$BR
+\(P(\text{exactly one black}) = P(BW) + P(WB)\)
+$PAR
+Answer:
+$BR
+\{ NAMED_ANS_RULE("pExact1B",12) \}
+END_TEXT
+
+Context("Numeric");
+NAMED_ANS("pExact1B", $p_exact1B->cmp(tolType => "absolute", tolerance => 0.001));
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Probability of at least one black (complement)");
+
+BEGIN_TEXT
+At least one black means the outcome is not WW.
+So it is easiest to use the complement:
+$PAR
+\(P(\text{at least one black}) = 1 - P(WW)\)
+$PAR
+Answer:
+$BR
+\{ NAMED_ANS_RULE("pAtLeast1B",12) \}
+END_TEXT
+
+Context("Numeric");
+NAMED_ANS("pAtLeast1B", $p_atleast1B->cmp(tolType => "absolute", tolerance => 0.001));
+
+Section::End();
+
+# ----------------------------------------------------------------
+# PILOT RATING
+# ----------------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+
+ Section::Begin("Feedback");
+
+ Context("Numeric");
+
+ our $rating = Real(3); # placeholder only
+
+ our $rating_cmp = $rating->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ if (!defined($student)) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ my $val;
+ eval { $val = $student->value; };
+ if (!defined($val)) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ my $ival = int($val);
+ if (abs($val - $ival) > 1e-12) {
+ $ansHash->{ans_message} = "Enter an integer from 1 to 5.";
+ return 0;
+ }
+
+ if ($ival < 1 || $ival > 5) {
+ $ansHash->{ans_message} = "Your rating must be 1, 2, 3, 4, or 5.";
+ return 0;
+ }
+
+ return 1;
+ }
+ );
+
+ BEGIN_PGML
+Rate the usefulness of this guided problem on a scale from 1 to 5.
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating: [__]{$rating_cmp}
+END_PGML
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem3.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem3.pg
new file mode 100644
index 0000000000..e45fd810c4
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem3.pg
@@ -0,0 +1,240 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Probability Distributions (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Probability Distributions)
+## Level(2)
+## KEYWORDS('probability','probability distribution','categorical variable','events','additive rule')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "scaffold.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Distribution (one categorical variable) with one missing value p
+# =======================================================
+# Categories:
+# Sports/Fitness, Video games, Music, Reading, Creative arts, Cooking/Baking, Outdoors
+
+$prob_sports = 0.22;
+$prob_games = 0.18;
+$prob_music = 0.14;
+$prob_reading = 0.12;
+$prob_arts = 0.10;
+$prob_outdoors = 0.16;
+
+# Missing probability:
+# Cooking/Baking = p
+$p_val = 1 - ($prob_sports + $prob_games + $prob_music + $prob_reading + $prob_arts + $prob_outdoors); # = 0.08
+
+# Event probabilities (computed, not shown)
+# E1 Active = Sports/Fitness + Outdoors
+$P_E1 = $prob_sports + $prob_outdoors;
+
+# E2 Creative = Music + Creative arts + Cooking/Baking
+$P_E2 = $prob_music + $prob_arts + $p_val;
+
+# E3 Indoors = Video games + Music + Reading + Creative arts + Cooking/Baking
+$P_E3 = $prob_games + $prob_music + $prob_reading + $prob_arts + $p_val;
+
+# E4 Quiet = Reading + Music + Creative arts
+$P_E4 = $prob_reading + $prob_music + $prob_arts;
+
+# =======================================================
+# Numeric comparators
+# =======================================================
+Context("Numeric");
+
+$cmp_p = Real($p_val)->cmp(tolType => "absolute", tolerance => 0.001);
+$cmp_E1 = Real($P_E1)->cmp(tolType => "absolute", tolerance => 0.001);
+$cmp_E2 = Real($P_E2)->cmp(tolType => "absolute", tolerance => 0.001);
+$cmp_E3 = Real($P_E3)->cmp(tolType => "absolute", tolerance => 0.001);
+$cmp_E4 = Real($P_E4)->cmp(tolType => "absolute", tolerance => 0.001);
+
+$cmp_rating = Real(1)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return ($v >= 1 && $v <= 5) ? 1 : 0;
+ }
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ hardcopy_is_open => "always",
+);
+
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_TEXT
+A census was conducted at Dawson where every student was asked:
+$BR
+"What is your favorite hobby?"
+$PAR
+
+Definition: A census collects data from every member of the population (not just a sample).
+$PAR
+
+Based on the census results, the table below gives a probability distribution for the variable "favorite hobby."
+$PAR
+
+If we randomly select a Dawson student, the probability of an event (like "active hobby") is found by adding the probabilities of the categories in that event.
+END_TEXT
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Probability Distribution Table");
+BEGIN_TEXT
+Favorite Hobby (one categorical variable)
+$PAR
+
+
+| Category | Probability |
+| Sports / Fitness | $prob_sports |
+| Video games | $prob_games |
+| Music | $prob_music |
+| Reading | $prob_reading |
+| Creative arts | $prob_arts |
+| Cooking / Baking | p |
+| Outdoors | $prob_outdoors |
+
+
+$PAR
+Reminder: The probabilities in a distribution add up to 1.
+END_TEXT
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Step 2 — Find the missing probability p");
+BEGIN_TEXT
+Find the missing probability p for Cooking / Baking.
+$PAR
+Enter p as a decimal:
+$BR
+p = \{ ans_rule(10) \}
+END_TEXT
+
+ANS($cmp_p);
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Additive Rule for Categories");
+BEGIN_TEXT
+When an event includes several categories in a probability distribution,
+the probability of that event is found by adding the probabilities of those categories.
+END_TEXT
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Event E1 — Active hobby");
+BEGIN_TEXT
+Let E1 be the event: "The student pursues an active hobby."
+$PAR
+Hint: Active = Sports / Fitness + Outdoors
+$PAR
+If we randomly select a student, what is the probability of E1?
+$PAR
+Enter P(E1) as a decimal:
+$BR
+P(E1) = \{ ans_rule(10) \}
+END_TEXT
+
+ANS($cmp_E1);
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Event E2 — Creative hobby");
+BEGIN_TEXT
+Let E2 be the event: "The student pursues a creative hobby."
+$PAR
+Hint: Creative = Music + Creative arts + Cooking / Baking
+$PAR
+Enter P(E2) as a decimal:
+$BR
+P(E2) = \{ ans_rule(10) \}
+END_TEXT
+
+ANS($cmp_E2);
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Event E3 — Indoors hobby");
+BEGIN_TEXT
+Let E3 be the event: "The student pursues an indoors hobby."
+$PAR
+Hint: Indoors = Video games + Music + Reading + Creative arts + Cooking / Baking
+$PAR
+Enter P(E3) as a decimal:
+$BR
+P(E3) = \{ ans_rule(10) \}
+END_TEXT
+
+ANS($cmp_E3);
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Event E4 — Quiet hobby");
+BEGIN_TEXT
+Let E4 be the event: "The student pursues a quiet hobby."
+$PAR
+Hint: Quiet = Reading + Music + Creative arts
+$PAR
+Enter P(E4) as a decimal:
+$BR
+P(E4) = \{ ans_rule(10) \}
+END_TEXT
+
+ANS($cmp_E4);
+Section::End();
+
+# ----------------------------------------------------------------
+# PILOT RATING (ACTIVE)
+# ----------------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+
+ Section::Begin("Feedback");
+ BEGIN_TEXT
+Rate the usefulness of this guided problem on a scale from 1 to 5.
+$PAR
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+$BR
+Note: Consider using the Email Instructor button below to suggest improvements.
+$PAR
+Rating:
+$BR
+\{ ans_rule(6) \}
+END_TEXT
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem4.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem4.pg
new file mode 100644
index 0000000000..2a5834a179
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem4.pg
@@ -0,0 +1,363 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Sample Spaces & Events (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Sample Spaces and Events)
+## Level(2)
+## KEYWORDS('probability','sample space','event','equally likely','contingency table','additive rule')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "contextString.pl",
+ "scaffold.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data (percentages)
+# Rows: Bus(B), Metro(M), Car(C), Walk(W), Bike(K), Other commute(O)
+# Cols: Montreal(M), West Island(W), Other region(O)
+# =======================================================
+%pct = (
+ B => { M => 6.0, W => 1.5, O => 10.5 }, # 18.0
+ M => { M => 10.0, W => 2.0, O => 10.0 }, # 22.0
+ C => { M => 8.0, W => 5.0, O => 12.0 }, # 25.0
+ W => { M => 8.0, W => 0.8, O => 1.2 }, # 10.0
+ K => { M => 2.0, W => 0.6, O => 2.4 }, # 5.0
+ O => { M => 6.0, W => 1.1, O => 12.9 }, # 20.0
+);
+
+# Correct event probabilities (decimals) — used only for grading
+$p_public = (18.0 + 22.0)/100; # Bus or Metro
+$p_active = (10.0 + 5.0)/100; # Walk or Bike
+$p_island = (40.0 + 11.0)/100; # Montreal or West Island
+
+# =======================================================
+# Working set-entry method (String context + comma redefine)
+# Students enter comma-separated outcome codes like: BM, MW, OO
+# =======================================================
+$ctxSet = Context("String");
+$ctxSet->operators->redefine(',', using => ',');
+
+# Allowed outcome codes (6 commute modes x 3 regions = 18 outcomes)
+$ctxSet->strings->add(
+ "BM" => {}, "BW" => {}, "BO" => {},
+ "MM" => {}, "MW" => {}, "MO" => {},
+ "CM" => {}, "CW" => {}, "CO" => {},
+ "WM" => {}, "WW" => {}, "WO" => {},
+ "KM" => {}, "KW" => {}, "KO" => {},
+ "OM" => {}, "OW" => {}, "OO" => {},
+);
+
+# Correct event sets (order doesn't matter)
+$eventP = List( String("BM"), String("BW"), String("BO"), String("MM"), String("MW"), String("MO") );
+$eventA = List( String("WM"), String("WW"), String("WO"), String("KM"), String("KW"), String("KO") );
+$eventI = List(
+ String("BM"), String("BW"),
+ String("MM"), String("MW"),
+ String("CM"), String("CW"),
+ String("WM"), String("WW"),
+ String("KM"), String("KW"),
+ String("OM"), String("OW")
+);
+
+$cmp_eventP = $eventP->cmp(ignoreOrder => 1);
+$cmp_eventA = $eventA->cmp(ignoreOrder => 1);
+$cmp_eventI = $eventI->cmp(ignoreOrder => 1);
+
+# =======================================================
+# Numeric comparators (probabilities + rating)
+# =======================================================
+Context("Numeric");
+
+$cmp_prob_public = Real($p_public)->cmp(tolType => "absolute", tolerance => 0.001);
+$cmp_prob_active = Real($p_active)->cmp(tolType => "absolute", tolerance => 0.001);
+$cmp_prob_island = Real($p_island)->cmp(tolType => "absolute", tolerance => 0.001);
+
+$cmp_rating = Real(1)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return ($v >= 1 && $v <= 5) ? 1 : 0;
+ }
+);
+
+# Restore set context for set-building blanks
+Context($ctxSet);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ hardcopy_is_open => "always",
+);
+
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_TEXT
+The breakdown of the student body at Dawson in terms of commute mode and home region is shown in the contingency table below.
+A student is selected at random, and we record the student's commute mode and home region.
+$PAR
+
+
+
+ |
+ Montreal (M) |
+ West Island (W) |
+ Other region (O) |
+
+
+ | Bus (B) |
+ $pct{B}{M}% | $pct{B}{W}% | $pct{B}{O}% |
+
+
+ | Metro (M) |
+ $pct{M}{M}% | $pct{M}{W}% | $pct{M}{O}% |
+
+
+ | Car (C) |
+ $pct{C}{M}% | $pct{C}{W}% | $pct{C}{O}% |
+
+
+ | Walk (W) |
+ $pct{W}{M}% | $pct{W}{W}% | $pct{W}{O}% |
+
+
+ | Bike (K) |
+ $pct{K}{M}% | $pct{K}{W}% | $pct{K}{O}% |
+
+
+ | Other commute (O) |
+ $pct{O}{M}% | $pct{O}{W}% | $pct{O}{O}% |
+
+
+
+$PAR
+Quick check: Are the outcomes equally likely?
+$BR
+A) Yes, because the table is smaller
+$BR
+B) No, because different outcomes have different percentages
+$BR
+C) Yes, because outcomes use letters
+$BR
+D) No, because a table cannot show probability
+$PAR
+Answer (A/B/C/D): \{ ans_rule(2) \}
+END_TEXT
+
+ANS( str_cmp("B") );
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Additive Rule for Outcomes");
+BEGIN_TEXT
+Additive Rule for Outcomes
+$PAR
+Example:
+$BR
+\(S=\lbrace o_1,o_2,o_3,o_4\rbrace\)
+$PAR
+\(E=\lbrace o_1,o_2\rbrace\)
+$PAR
+Only one outcome happens in one trial, so we add the probabilities of the outcomes inside the event:
+$BR
+\(P(E)=P(o_1)+P(o_2)\)
+$PAR
+
+In this problem, each cell of the table is one outcome.
+So the probability of an event is found by adding the percentages of the cells in that event,
+then dividing by 100.
+END_TEXT
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Outcome codes and the sample space");
+BEGIN_TEXT
+We label outcomes using a two-letter code.
+$PAR
+
+First letter (commute mode):
+$BR
+B = Bus, M = Metro, C = Car, W = Walk, K = Bike, O = Other commute
+$PAR
+
+Second letter (home region):
+$BR
+M = Montreal, W = West Island, O = Other region
+$PAR
+
+Examples:
+$BR
+BO means (Bus, Other region)
+$BR
+MW means (Metro, West Island)
+$BR
+OO means (Other commute, Other region)
+$PAR
+
+So the sample space looks like this:
+$BR
+S = { BM, BW, BO, MM, MW, ... , OO }
+$PAR
+
+Checkpoint: Which code represents "Car and Other region"?
+$BR
+A) OC
+$BR
+B) CW
+$BR
+C) CO
+$BR
+D) MC
+$PAR
+Answer (A/B/C/D): \{ ans_rule(2) \}
+END_TEXT
+
+ANS( str_cmp("C") );
+Section::End();
+
+# =======================================================
+# EVENT P (build + probability)
+# =======================================================
+Section::Begin("Event P — Public transport");
+BEGIN_TEXT
+Let P be the event: "The student uses public transport."
+$PAR
+For this problem, public transport means Bus or Metro.
+$PAR
+
+Step 1 (Build the event).
+Enter the outcomes in P using two-letter codes (comma-separated, order doesn't matter).
+$BR
+P = { \{ ans_rule(40) \} }
+$PAR
+
+Step 2 (Find the probability).
+Using the table, add the percentages for all outcomes you included in P, then divide by 100.
+$PAR
+Enter P(P) as a decimal (example: 40% would be 0.40):
+$BR
+P(P) = \{ ans_rule(10) \}
+END_TEXT
+
+ANS($cmp_eventP);
+
+Context("Numeric");
+ANS($cmp_prob_public);
+Context($ctxSet);
+
+Section::End();
+
+# =======================================================
+# EVENT A (build + probability)
+# =======================================================
+Section::Begin("Event A — Active transport");
+BEGIN_TEXT
+Let A be the event: "The student uses active transport."
+$PAR
+For this problem, active transport means Walk or Bike.
+$PAR
+
+Step 1 (Build the event).
+Enter the outcomes in A using two-letter codes (comma-separated, order doesn't matter).
+$BR
+A = { \{ ans_rule(40) \} }
+$PAR
+
+Step 2 (Find the probability).
+Using the table, add the percentages for all outcomes you included in A, then divide by 100.
+$PAR
+Enter P(A) as a decimal:
+$BR
+P(A) = \{ ans_rule(10) \}
+END_TEXT
+
+ANS($cmp_eventA);
+
+Context("Numeric");
+ANS($cmp_prob_active);
+Context($ctxSet);
+
+Section::End();
+
+# =======================================================
+# EVENT I (build + probability)
+# =======================================================
+Section::Begin("Event I — Lives on the island");
+BEGIN_TEXT
+Let I be the event: "The student lives on the island."
+$PAR
+For this problem, living on the island means the home region is Montreal or West Island.
+$PAR
+
+Step 1 (Build the event).
+Enter the outcomes in I using two-letter codes (comma-separated, order doesn't matter).
+$BR
+I = { \{ ans_rule(50) \} }
+$PAR
+
+Step 2 (Find the probability).
+Using the table, add the percentages for all outcomes you included in I, then divide by 100.
+$PAR
+Enter P(I) as a decimal:
+$BR
+P(I) = \{ ans_rule(10) \}
+END_TEXT
+
+ANS($cmp_eventI);
+
+Context("Numeric");
+ANS($cmp_prob_island);
+Context($ctxSet);
+
+Section::End();
+
+# ----------------------------------------------------------------
+# PILOT RATING (ACTIVE)
+# ----------------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_TEXT
+Rate the usefulness of this guided problem on a scale from 1 to 5.
+$PAR
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+$BR
+Note: Consider using the Email Instructor button below to suggest improvements.
+$PAR
+Rating:
+$BR
+\{ ans_rule(6) \}
+END_TEXT
+
+ Context("Numeric");
+ ANS($cmp_rating);
+ Context($ctxSet);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem5.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem5.pg
new file mode 100644
index 0000000000..c8f3f33d9c
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem5.pg
@@ -0,0 +1,333 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Sample Spaces & Events (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Equally Likely Outcomes)
+## Level(2)
+## KEYWORDS('probability','sample space','event','equally likely','two dice','additive rule')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "contextString.pl",
+ "scaffold.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Build the sample space table (HTML) for outcomes 11..66
+# =======================================================
+$table_html = '';
+$table_html .= '| Die 1 \\ Die 2 | ';
+for $j (1..6) { $table_html .= "$j | "; }
+$table_html .= '
';
+
+for $i (1..6) {
+ $table_html .= "| $i | ";
+ for $j (1..6) {
+ $code = "$i$j";
+ $table_html .= "$code | ";
+ }
+ $table_html .= "
";
+}
+$table_html .= "
";
+
+# =======================================================
+# String-context set entry for outcome codes like 46, 55, 66
+# =======================================================
+$ctxSet = Context("String");
+$ctxSet->operators->redefine(',', using => ',');
+
+@outcomes = ();
+for $i (1..6) {
+ for $j (1..6) {
+ push @outcomes, "$i$j";
+ }
+}
+%allowed = map { $_ => {} } @outcomes;
+$ctxSet->strings->add(%allowed);
+
+# Events (as outcome sets)
+@E1 = qw(46 55 64 56 65 66); # sum > 9
+@E2 = qw(14 41 25 52 36 63); # absolute difference = 3
+@E3 = qw(16 61 23 32); # product = 6
+@E4 = qw(11 22 33 44 55 66); # double
+
+$event1 = List(map { String($_) } @E1);
+$event2 = List(map { String($_) } @E2);
+$event3 = List(map { String($_) } @E3);
+$event4 = List(map { String($_) } @E4);
+
+$cmp_event1 = $event1->cmp(ignoreOrder => 1);
+$cmp_event2 = $event2->cmp(ignoreOrder => 1);
+$cmp_event3 = $event3->cmp(ignoreOrder => 1);
+$cmp_event4 = $event4->cmp(ignoreOrder => 1);
+
+# =======================================================
+# Numeric comparators (probabilities + rating)
+# =======================================================
+Context("Numeric");
+
+$p1 = 6/36; # 1/6
+$p2 = 6/36; # 1/6
+$p3 = 4/36; # 1/9
+$p4 = 6/36; # 1/6
+
+$cmp_p1 = Real($p1)->cmp(tolType => "absolute", tolerance => 0.001);
+$cmp_p2 = Real($p2)->cmp(tolType => "absolute", tolerance => 0.001);
+$cmp_p3 = Real($p3)->cmp(tolType => "absolute", tolerance => 0.001);
+$cmp_p4 = Real($p4)->cmp(tolType => "absolute", tolerance => 0.001);
+
+$cmp_rating = Real(1)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return ($v >= 1 && $v <= 5) ? 1 : 0;
+ }
+);
+
+# Restore set context for set-building blanks
+Context($ctxSet);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ hardcopy_is_open => "always",
+);
+
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_TEXT
+Two fair six-sided dice are rolled at the same time.
+We record the ordered pair (first die, second die).
+
+$PAR
+
+Quick check: Are the outcomes equally likely?
+$BR
+A) No, because the dice are identical
+$BR
+B) No, because there are 36 outcomes
+$BR
+C) Yes, because the dice are fair and each ordered pair has the same chance
+$BR
+D) Yes, but only for doubles
+$PAR
+Answer (A/B/C/D): \{ ans_rule(2) \}
+END_TEXT
+
+ANS( str_cmp("C") );
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Sample Space as a Table");
+BEGIN_TEXT
+We will write an outcome as a two-digit code.
+$BR
+For example, 54 means (first die = 5, second die = 4).
+$PAR
+
+Here is the sample space:
+$PAR
+$table_html
+$PAR
+
+How many outcomes are in the sample space?
+$BR
+\{ ans_rule(5) \}
+END_TEXT
+
+Context("Numeric");
+ANS( Real(36)->cmp );
+Context($ctxSet);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Additive Rule for Outcomes");
+BEGIN_TEXT
+Additive Rule for Outcomes
+$PAR
+If an event contains several outcomes, the probability of the event is found by adding the probabilities of the outcomes in that event.
+$PAR
+Because all 36 outcomes are equally likely here:
+$BR
+Probability of an event = (number of outcomes in the event) / 36
+END_TEXT
+Section::End();
+
+# =======================================================
+# Event 1: Sum > 9
+# =======================================================
+Section::Begin("Event 1 — Sum is over 9");
+BEGIN_TEXT
+Event 1: The sum of the two dice is greater than 9.
+$PAR
+
+Step 1 (Build the event).
+List all outcomes (two-digit codes) where the sum is greater than 9.
+Comma-separated, order doesn't matter. Do not type braces.
+$BR
+E1 = { \{ ans_rule(60) \} }
+$PAR
+
+Step 2 (Find the probability).
+Use the Additive Rule for Outcomes.
+Since outcomes are equally likely, count how many outcomes are in E1 and divide by 36.
+$PAR
+Enter P(E1) as a fraction or a decimal:
+$BR
+P(E1) = \{ ans_rule(12) \}
+END_TEXT
+
+ANS($cmp_event1);
+
+Context("Numeric");
+ANS($cmp_p1);
+Context($ctxSet);
+
+Section::End();
+
+# =======================================================
+# Event 2: |difference| = 3
+# =======================================================
+Section::Begin("Event 2 — Difference is 3");
+BEGIN_TEXT
+Event 2: The absolute difference between the dice is 3.
+(Example: 14 and 41 both have absolute difference 3.)
+$PAR
+
+Step 1 (Build the event).
+List all outcomes (two-digit codes) where the absolute difference is 3.
+Comma-separated, order doesn't matter. Do not type braces.
+$BR
+E2 = { \{ ans_rule(60) \} }
+$PAR
+
+Step 2 (Find the probability).
+Count how many outcomes are in E2 and divide by 36.
+$PAR
+Enter P(E2) as a fraction or a decimal:
+$BR
+P(E2) = \{ ans_rule(12) \}
+END_TEXT
+
+ANS($cmp_event2);
+
+Context("Numeric");
+ANS($cmp_p2);
+Context($ctxSet);
+
+Section::End();
+
+# =======================================================
+# Event 3: Product = 6
+# =======================================================
+Section::Begin("Event 3 — Product is 6");
+BEGIN_TEXT
+Event 3: The product of the two dice is 6.
+$PAR
+
+Step 1 (Build the event).
+List all outcomes (two-digit codes) where the product is 6.
+Comma-separated, order doesn't matter. Do not type braces.
+$BR
+E3 = { \{ ans_rule(40) \} }
+$PAR
+
+Step 2 (Find the probability).
+Count how many outcomes are in E3 and divide by 36.
+$PAR
+Enter P(E3) as a fraction or a decimal:
+$BR
+P(E3) = \{ ans_rule(12) \}
+END_TEXT
+
+ANS($cmp_event3);
+
+Context("Numeric");
+ANS($cmp_p3);
+Context($ctxSet);
+
+Section::End();
+
+# =======================================================
+# Event 4: Double
+# =======================================================
+Section::Begin("Event 4 — Double");
+BEGIN_TEXT
+Event 4: A double is rolled (both dice show the same number).
+$PAR
+
+Step 1 (Build the event).
+List all outcomes (two-digit codes) that are doubles.
+Comma-separated, order doesn't matter. Do not type braces.
+$BR
+E4 = { \{ ans_rule(40) \} }
+$PAR
+
+Step 2 (Find the probability).
+Count how many outcomes are in E4 and divide by 36.
+$PAR
+Enter P(E4) as a fraction or a decimal:
+$BR
+P(E4) = \{ ans_rule(12) \}
+END_TEXT
+
+ANS($cmp_event4);
+
+Context("Numeric");
+ANS($cmp_p4);
+Context($ctxSet);
+
+Section::End();
+
+# ----------------------------------------------------------------
+# PILOT RATING (ACTIVE)
+# ----------------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+
+ Section::Begin("Feedback");
+ BEGIN_TEXT
+Rate the usefulness of this guided problem on a scale from 1 to 5.
+$PAR
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+$BR
+Note: Consider using the Email Instructor button below to suggest improvements.
+$PAR
+Rating:
+$BR
+\{ ans_rule(6) \}
+END_TEXT
+
+ Context("Numeric");
+ ANS($cmp_rating);
+ Context($ctxSet);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem6.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem6.pg
new file mode 100644
index 0000000000..9258b1bc32
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem6.pg
@@ -0,0 +1,253 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Sample Spaces & Events (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Equally Likely Outcomes)
+## Level(2)
+## KEYWORDS('probability','sample space','event','equally likely','contingency table','additive rule')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "scaffold.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Days and sample space table (HTML)
+# =======================================================
+@days = ("Mon","Tue","Wed","Thu","Fri","Sat","Sun");
+
+$table_html = '';
+$table_html .= '| 1st \\ 2nd | ';
+for $d (@days) { $table_html .= "$d | "; }
+$table_html .= '
';
+
+for $r (@days) {
+ $table_html .= "| $r | ";
+ for $c (@days) {
+ $cell = "$r/$c";
+ $table_html .= "$cell | ";
+ }
+ $table_html .= "
";
+}
+$table_html .= "
";
+
+# =======================================================
+# Correct probabilities (as decimals)
+# =======================================================
+# Total outcomes: 7*7 = 49
+$p_E1 = 24/49; # at least one weekend day
+$p_E2 = 7/49; # same day twice
+$p_E3 = 20/49; # exactly one weekend day
+$p_E4 = 7/49; # second day immediately after first (with wrap-around)
+
+# =======================================================
+# Numeric comparators (probabilities + rating)
+# =======================================================
+Context("Numeric");
+
+$cmp_E1 = Real($p_E1)->cmp(tolType => "absolute", tolerance => 0.001);
+$cmp_E2 = Real($p_E2)->cmp(tolType => "absolute", tolerance => 0.001);
+$cmp_E3 = Real($p_E3)->cmp(tolType => "absolute", tolerance => 0.001);
+$cmp_E4 = Real($p_E4)->cmp(tolType => "absolute", tolerance => 0.001);
+
+$cmp_rating = Real(1)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return ($v >= 1 && $v <= 5) ? 1 : 0;
+ }
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ hardcopy_is_open => "always",
+);
+
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_TEXT
+We write the days of the week on 7 balls and put them inside a bag.
+We randomly draw one ball, replace it, and then randomly draw the second ball.
+$PAR
+We record the ordered outcome (day on the first ball / day on the second ball).
+$PAR
+
+Quick check: Are the outcomes equally likely?
+$BR
+A) No, because we are drawing from a bag
+$BR
+B) No, because some days are weekends
+$BR
+C) Yes, because we replace the ball, so each ordered pair has the same chance
+$BR
+D) Yes, but only if we do not replace
+$PAR
+Answer (A/B/C/D): \{ ans_rule(2) \}
+END_TEXT
+
+ANS( str_cmp("C") );
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Sample Space as a Table");
+BEGIN_TEXT
+We use short forms for the days:
+$BR
+Mon, Tue, Wed, Thu, Fri, Sat, Sun
+$PAR
+An outcome is written as first/second.
+For example, Sat/Mon means first draw Sat and second draw Mon.
+$PAR
+
+Here is the sample space:
+$PAR
+$table_html
+$PAR
+
+How many outcomes are in the sample space?
+$BR
+\{ ans_rule(5) \}
+END_TEXT
+
+ANS( Real(49)->cmp );
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Additive Rule for Outcomes");
+BEGIN_TEXT
+Additive Rule for Outcomes
+$PAR
+If an event contains several outcomes, the probability of the event is found by adding the probabilities of the outcomes in that event.
+$PAR
+Because all 49 outcomes are equally likely here:
+$BR
+Probability of an event = (number of outcomes in the event) / 49
+END_TEXT
+Section::End();
+
+# =======================================================
+# Event 1: At least one weekend day
+# =======================================================
+Section::Begin("Event 1 — At least one weekend day");
+BEGIN_TEXT
+Event 1: At least one of the two balls is a weekend day (Sat or Sun).
+$PAR
+
+Count hint:
+Count the number of outcomes in the table that contain Sat or Sun at least once,
+then divide by 49.
+$PAR
+
+Enter P(E1) as a fraction or a decimal:
+$BR
+P(E1) = \{ ans_rule(12) \}
+END_TEXT
+
+ANS($cmp_E1);
+Section::End();
+
+# =======================================================
+# Event 2: Same day twice
+# =======================================================
+Section::Begin("Event 2 — Same day twice");
+BEGIN_TEXT
+Event 2: Both balls show the same day (a double), like Mon/Mon.
+$PAR
+
+Enter P(E2) as a fraction or a decimal:
+$BR
+P(E2) = \{ ans_rule(12) \}
+END_TEXT
+
+ANS($cmp_E2);
+Section::End();
+
+# =======================================================
+# Event 3: Exactly one weekend day
+# =======================================================
+Section::Begin("Event 3 — Exactly one weekend day");
+BEGIN_TEXT
+Event 3: Exactly one of the two balls is a weekend day (Sat or Sun).
+$PAR
+
+Enter P(E3) as a fraction or a decimal:
+$BR
+P(E3) = \{ ans_rule(12) \}
+END_TEXT
+
+ANS($cmp_E3);
+Section::End();
+
+# =======================================================
+# Event 4: Immediately after in week order
+# =======================================================
+Section::Begin("Event 4 — Second day is immediately after the first");
+BEGIN_TEXT
+Event 4: The day on the second ball is immediately after the day on the first ball in week order.
+$PAR
+Use this week order (with wrap-around):
+$BR
+Mon -> Tue -> Wed -> Thu -> Fri -> Sat -> Sun -> Mon
+$PAR
+Examples that count: Tue/Wed, Sat/Sun, Sun/Mon
+$PAR
+
+Enter P(E4) as a fraction or a decimal:
+$BR
+P(E4) = \{ ans_rule(12) \}
+END_TEXT
+
+ANS($cmp_E4);
+Section::End();
+
+# ----------------------------------------------------------------
+# PILOT RATING (ACTIVE)
+# ----------------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+
+ Section::Begin("Feedback");
+ BEGIN_TEXT
+Rate the usefulness of this guided problem on a scale from 1 to 5.
+$PAR
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+$BR
+Note: Consider using the Email Instructor button below to suggest improvements.
+$PAR
+Rating:
+$BR
+\{ ans_rule(6) \}
+END_TEXT
+
+ Context("Numeric");
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem7.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem7.pg
new file mode 100644
index 0000000000..78321ce56e
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem7.pg
@@ -0,0 +1,190 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Sample Spaces & Events (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Introduction to Cards)
+## Level(2)
+## KEYWORDS('probability','sample space','event','equally likely','deck of cards')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "scaffold.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Numeric comparators (probabilities + rating)
+# =======================================================
+Context("Numeric");
+
+# Events:
+# E1: heart
+# E2: face card (J, Q, K)
+# E3: red card (hearts or diamonds)
+# E4: number card (2 through 10)
+
+$cmp_E1 = Real(1/4)->cmp(tolType => "absolute", tolerance => 0.001); # 13/52
+$cmp_E2 = Real(3/13)->cmp(tolType => "absolute", tolerance => 0.001); # 12/52
+$cmp_E3 = Real(1/2)->cmp(tolType => "absolute", tolerance => 0.001); # 26/52
+$cmp_E4 = Real(9/13)->cmp(tolType => "absolute", tolerance => 0.001); # 36/52
+
+$cmp_rating = Real(1)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return ($v >= 1 && $v <= 5) ? 1 : 0;
+ }
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ hardcopy_is_open => "always",
+);
+
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_TEXT
+A standard deck of cards is well-shuffled, and one card is drawn at random.
+$PAR
+
+Here is what you need to know about a standard deck:
+$BR
+- There are 52 cards total.
+$BR
+- There are 4 suits: Clubs, Diamonds, Hearts, Spades.
+$BR
+- Each suit has 13 ranks in this order:
+Ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King.
+$BR
+- A face card means either a Jack, a Queen, or a King.
+$PAR
+
+Color fact:
+$BR
+- Hearts and Diamonds are red.
+$BR
+- Clubs and Spades are black.
+$PAR
+
+Because the deck is well-shuffled, each individual card is equally likely.
+So any specific card has probability \(1/52\).
+END_TEXT
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Additive Rule for Outcomes");
+BEGIN_TEXT
+Additive Rule for Outcomes
+$PAR
+If an event contains several cards, the probability of the event is found by adding the probabilities of the cards in that event.
+$PAR
+Since all 52 cards are equally likely:
+$BR
+Probability of an event = (number of cards in the event) / 52
+END_TEXT
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Event 1 — The card is a heart");
+BEGIN_TEXT
+Event 1: The card drawn is a heart.
+$PAR
+Enter P(E1) as a fraction or a decimal:
+$BR
+P(E1) = \{ ans_rule(12) \}
+END_TEXT
+
+ANS($cmp_E1);
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Event 2 — The card is a face card");
+BEGIN_TEXT
+Event 2: The card drawn is a face card.
+(Reminder: face card means Jack, Queen, or King.)
+$PAR
+Enter P(E2) as a fraction or a decimal:
+$BR
+P(E2) = \{ ans_rule(12) \}
+END_TEXT
+
+ANS($cmp_E2);
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Event 3 — The card is red");
+BEGIN_TEXT
+Event 3: The card drawn is red.
+(Reminder: hearts and diamonds are red.)
+$PAR
+Enter P(E3) as a fraction or a decimal:
+$BR
+P(E3) = \{ ans_rule(12) \}
+END_TEXT
+
+ANS($cmp_E3);
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Event 4 — The card is a number card (2 through 10)");
+BEGIN_TEXT
+Event 4: The card drawn is a number card, meaning 2 through 10.
+(Ace is not included, and face cards are not included.)
+$PAR
+Enter P(E4) as a fraction or a decimal:
+$BR
+P(E4) = \{ ans_rule(12) \}
+END_TEXT
+
+ANS($cmp_E4);
+Section::End();
+
+# ----------------------------------------------------------------
+# PILOT RATING (ACTIVE)
+# ----------------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+
+ Section::Begin("Feedback");
+ BEGIN_TEXT
+Rate the usefulness of this guided problem on a scale from 1 to 5.
+$PAR
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+$BR
+Note: Consider using the Email Instructor button below to suggest improvements.
+$PAR
+Rating:
+$BR
+\{ ans_rule(6) \}
+END_TEXT
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem8.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem8.pg
new file mode 100644
index 0000000000..5ad3f8c725
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem8.pg
@@ -0,0 +1,213 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Complements (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Complements)
+## Level(2)
+## KEYWORDS('probability','event','complement','probability rule for complements','sample space')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "contextString.pl",
+ "scaffold.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Set-entry context for outcomes like BBB, BGB, GGG
+# =======================================================
+$ctxSet = Context("String");
+$ctxSet->operators->redefine(',', using => ',');
+
+$ctxSet->strings->add(
+ "BBB" => {}, "BBG" => {}, "BGB" => {}, "GBB" => {},
+ "BGG" => {}, "GBG" => {}, "GGB" => {}, "GGG" => {},
+);
+
+$correctS = List(
+ String("BBB"), String("BBG"), String("BGB"), String("GBB"),
+ String("BGG"), String("GBG"), String("GGB"), String("GGG")
+);
+$cmp_S = $correctS->cmp(ignoreOrder => 1);
+
+# A = "at least one girl"
+# A^c = "no girls" = {BBB}
+$correctAc = List( String("BBB") );
+$cmp_Ac_set = $correctAc->cmp(ignoreOrder => 1);
+
+# =======================================================
+# Numeric comparators
+# =======================================================
+Context("Numeric");
+
+$cmp_PAc = Real(1/8)->cmp(tolType => "absolute", tolerance => 0.001);
+$cmp_PA = Real(7/8)->cmp(tolType => "absolute", tolerance => 0.001);
+
+$cmp_rating = Real(1)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return ($v >= 1 && $v <= 5) ? 1 : 0;
+ }
+);
+
+# Use set context for set-building blanks
+Context($ctxSet);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ hardcopy_is_open => "always",
+);
+
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_TEXT
+A family has three children.
+Assume each child is equally likely to be a boy (B) or a girl (G),
+and the outcomes are equally likely.
+$PAR
+
+We record the outcome in order (oldest to youngest) using a three-letter code.
+For example, BBG means: boy, boy, girl.
+$PAR
+
+Let \(A\) be the event: "At least one girl."
+END_TEXT
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Construct the sample space");
+BEGIN_TEXT
+Enter the sample space \(S\) for the three children using codes like BBB, BBG, etc.
+$PAR
+Separate outcomes with commas. Order does not matter. Do not type braces. Use a tree diagram to find all possible outcomes.
+$PAR
+S = { \{ ans_rule(70) \} }
+END_TEXT
+
+ANS($cmp_S);
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Complement and the Probability Rule for Complements");
+BEGIN_TEXT
+Complement idea
+$PAR
+The complement of an event contains all outcomes in the sample space that are not in the event.
+We write the complement of \(A\) as \(A^c\).
+$PAR
+
+Why complements help here:
+The event "at least one girl" includes many outcomes.
+Its complement is much smaller and is easier to count.
+$PAR
+
+Probability Rule for Complements:
+$BR
+\(P(A)=1-P(A^c)\)
+END_TEXT
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Build the complement");
+BEGIN_TEXT
+Now build the complement \(A^c\).
+$PAR
+\(A^c\) means: "No girls."
+$PAR
+Enter \(A^c\) as a set of outcomes (comma-separated, order does not matter, do not type braces):
+$PAR
+\(A^c\) = { \{ ans_rule(30) \} }
+END_TEXT
+
+ANS($cmp_Ac_set);
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Probability of the complement");
+BEGIN_TEXT
+Find \(P(A^c)\).
+$PAR
+Hint: There are 8 equally likely outcomes in \(S\).
+So \(P(A^c)\) = (number of outcomes in \(A^c\)) / 8.
+$PAR
+Enter \(P(A^c)\) as a fraction or a decimal:
+$BR
+P(\(A^c\)) = \{ ans_rule(12) \}
+END_TEXT
+
+Context("Numeric");
+ANS($cmp_PAc);
+Context($ctxSet);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Probability of A");
+BEGIN_TEXT
+Finally, use the Probability Rule for Complements:
+$BR
+\(P(A)=1-P(A^c)\)
+$PAR
+Enter \(P(A)\) as a fraction or a decimal:
+$BR
+P(A) = \{ ans_rule(12) \}
+END_TEXT
+
+Context("Numeric");
+ANS($cmp_PA);
+Context($ctxSet);
+
+Section::End();
+
+# ----------------------------------------------------------------
+# PILOT RATING (ACTIVE)
+# ----------------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+
+ Section::Begin("Feedback");
+ BEGIN_TEXT
+Rate the usefulness of this guided problem on a scale from 1 to 5.
+$PAR
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+$BR
+Note: Consider using the Email Instructor button below to suggest improvements.
+$PAR
+Rating:
+$BR
+\{ ans_rule(6) \}
+END_TEXT
+
+ Context("Numeric");
+ ANS($cmp_rating);
+ Context($ctxSet);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem9.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem9.pg
new file mode 100644
index 0000000000..f2e5e54bba
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/BasicProbabilityConcepts_GuidedProblem9.pg
@@ -0,0 +1,363 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Union & Intersection (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Union and Intersection)
+## Level(2)
+## KEYWORDS('probability','event','intersection','union','two dice')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "contextString.pl",
+ "scaffold.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# IMAGES (place these files in your course html/images folder):
+# venn_intersection.jpg
+# venn_union.jpg
+# NOTE: On your server, image() throws "Unimplemented" in BEGIN_TEXT.
+# We output images using safe HTML
tags instead.
+# ----------------------------------------------------------------
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Sample space table (HTML) for outcomes 11..66
+# =======================================================
+my @nums = (1..6);
+
+# FIX #1: make table variable visible inside BEGIN_TEXT via \{ ... \}
+our $table_html = '';
+$table_html .= '| Die 1 / Die 2 | ';
+for my $j (@nums) { $table_html .= "$j | "; }
+$table_html .= '
';
+
+for my $i (@nums) {
+ $table_html .= "| $i | ";
+ for my $j (@nums) {
+ my $code = "$i$j";
+ $table_html .= "$code | ";
+ }
+ $table_html .= "
";
+}
+$table_html .= "
";
+
+# =======================================================
+# Set-entry context for outcomes like 46, 55, 66
+# =======================================================
+my $ctxSet = Context("String");
+$ctxSet->operators->redefine(',', using => ',');
+
+my %allowed = ();
+for my $i (@nums) {
+ for my $j (@nums) {
+ $allowed{"$i$j"} = {};
+ }
+}
+$ctxSet->strings->add(%allowed);
+
+# =======================================================
+# Events for this problem
+# A: sum is 7
+# B: at least one die is 5
+# =======================================================
+my @A = qw(16 25 34 43 52 61);
+my @B = qw(51 52 53 54 55 56 15 25 35 45 65);
+
+my @AiB = qw(25 52); # A ∩ B
+my @AuB = qw(51 52 53 54 55 56 15 25 35 45 65 16 34 43 61); # A ∪ B (15 outcomes)
+
+# -------------------------------------------------------
+# FIX #2: comparators for sets A and B (order doesn't matter)
+# -------------------------------------------------------
+my $cmp_A_set = List(map { String($_) } @A)->cmp(ignoreOrder => 1);
+my $cmp_B_set = List(map { String($_) } @B)->cmp(ignoreOrder => 1);
+
+my $cmp_AiB_set = List(map { String($_) } @AiB)->cmp(ignoreOrder => 1);
+my $cmp_AuB_set = List(map { String($_) } @AuB)->cmp(ignoreOrder => 1);
+
+# =======================================================
+# Numeric comparators
+# =======================================================
+Context("Numeric");
+
+my $cmp_nS = Real(36)->cmp();
+
+# FIX #2: probabilities for A and B
+my $cmp_PA = Real(1/6)->cmp( tolType => "absolute", tolerance => 0.001 ); # 6/36
+my $cmp_PB = Real(11/36)->cmp( tolType => "absolute", tolerance => 0.001 ); # 11/36
+
+my $cmp_PAiB = Real(1/18)->cmp( tolType => "absolute", tolerance => 0.001 ); # 2/36
+my $cmp_PAuB = Real(5/12)->cmp( tolType => "absolute", tolerance => 0.001 ); # 15/36
+
+# FIX #4: addition rule verification (RHS and difference)
+my $cmp_add_rhs = Real(5/12)->cmp( tolType => "absolute", tolerance => 0.001 ); # P(A)+P(B)-P(A∩B)
+my $cmp_zero = Real(0)->cmp( tolType => "absolute", tolerance => 0.001 );
+
+my $cmp_rating = Real(1)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return ($v >= 1 && $v <= 5) ? 1 : 0;
+ }
+);
+
+# Back to set context for set-entry blanks
+Context($ctxSet);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ hardcopy_is_open => "always",
+);
+
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+
+BEGIN_TEXT
+Two fair six-sided dice are rolled at the same time.
+We record the ordered pair (first die, second die) using a two-digit code.
+For example, 54 means (first die = 5, second die = 4).
+$PAR
+Here is the sample space:
+$PAR
+\{ $table_html \}
+$PAR
+How many outcomes are in the sample space?
+$BR
+\{ ans_rule(5) \}
+END_TEXT
+
+Context("Numeric");
+ANS($cmp_nS);
+Context($ctxSet);
+
+Section::End();
+
+# -------------------------------------------------------
+# FIX #2: add set entry blanks for A and B, and ask for P(A), P(B)
+# -------------------------------------------------------
+Section::Begin("Define the events");
+BEGIN_TEXT
+Define these two events:
+$PAR
+\(A\): The sum of the two dice is 7.
+$BR
+\(B\): At least one of the dice shows 5.
+$PAR
+
+Step 1 (List event \(A\)).
+Comma-separated, order doesn't matter. Do not type braces.
+$BR
+\(A\) = { \{ ans_rule(60) \} }
+$PAR
+
+Step 2 (Find P(\(A\))).
+Because all 36 outcomes are equally likely:
+$BR
+P(\(A\)) = (number of outcomes in \(A\)) / 36
+$BR
+Enter P(\(A\)) as a fraction or a decimal:
+$BR
+P(\(A\)) = \{ ans_rule(12) \}
+$PAR
+
+Step 3 (List event \(B\)).
+Comma-separated, order doesn't matter. Do not type braces.
+$BR
+\(B\) = { \{ ans_rule(80) \} }
+$PAR
+
+Step 4 (Find P(\(B\))).
+Because all 36 outcomes are equally likely:
+$BR
+P(\(B\)) = (number of outcomes in \(B\)) / 36
+$BR
+Enter P(\(B\)) as a fraction or a decimal:
+$BR
+P(\(B\)) = \{ ans_rule(12) \}
+END_TEXT
+
+# IMPORTANT: ANS order must match ans_rule order above
+Context($ctxSet);
+ANS($cmp_A_set);
+
+Context("Numeric");
+ANS($cmp_PA);
+
+Context($ctxSet);
+ANS($cmp_B_set);
+
+Context("Numeric");
+ANS($cmp_PB);
+
+Context($ctxSet);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Intersection");
+BEGIN_TEXT
+Intersection
+$PAR
+The intersection of \(A\) and \(B\), written \(A \cap B\), is the set of outcomes that are in both events.
+In words, it corresponds to combining the descriptions using and.
+$PAR
+\{ image("venn_intersection.jpg", width => 300) \}
+$PAR
+Step 1 (Build \(A \cap B\)).
+List all outcomes (two-digit codes) that satisfy:
+$BR
+"sum is 7" and "at least one die is 5".
+$PAR
+Comma-separated, order doesn't matter. Do not type braces.
+$BR
+\(A \cap B\) = { \{ ans_rule(40) \} }
+$PAR
+
+Step 2 (Probability of the intersection).
+Because the 36 outcomes are equally likely:
+$BR
+P(\(A \cap B\)) = (number of outcomes in \(A \cap B\)) / 36
+$PAR
+Enter P(\(A \cap B\)) as a fraction or a decimal:
+$BR
+P(\(A \cap B\)) = \{ ans_rule(12) \}
+END_TEXT
+
+Context($ctxSet);
+ANS($cmp_AiB_set);
+
+Context("Numeric");
+ANS($cmp_PAiB);
+Context($ctxSet);
+
+Section::End();
+
+# -------------------------------------------------------
+# FIX #3: Combine Union + Final Answer into one section
+# -------------------------------------------------------
+Section::Begin("Union (Final Answer)");
+BEGIN_TEXT
+Union
+$PAR
+The union of \(A\) and \(B\), written \(A \cup B\), is the set of outcomes that are in at least one of the events.
+In words, it corresponds to combining the descriptions using or (including “both”).
+$PAR
+\{ image("venn_union.jpg", width => 300) \}
+$PAR
+Step 1 (Build \(A \cup B\)).
+List all outcomes (two-digit codes) that satisfy:
+$BR
+"sum is 7" or "at least one die is 5" (or both).
+$PAR
+Comma-separated, order doesn't matter. Do not type braces.
+$BR
+\(A \cup B\) = { \{ ans_rule(80) \} }
+$PAR
+
+Step 2 (Final Answer: Probability of the union).
+Because the 36 outcomes are equally likely:
+$BR
+P(\(A \cup B\)) = (number of outcomes in \(A \cup B\)) / 36
+$PAR
+Enter P(\(A \cup B\)) as a fraction or a decimal:
+$BR
+P(\(A \cup B\)) = \{ ans_rule(12) \}
+END_TEXT
+
+Context($ctxSet);
+ANS($cmp_AuB_set);
+
+Context("Numeric");
+ANS($cmp_PAuB);
+
+Context($ctxSet);
+
+Section::End();
+
+# -------------------------------------------------------
+# FIX #4: Add additive (addition) rule verification section
+# -------------------------------------------------------
+Section::Begin("Addition Rule of Probability (Verify)");
+BEGIN_TEXT
+Addition Rule of Probability
+$PAR
+For any two events \(A\) and \(B\):
+$BR
+P(\(A \cup B\)) = P(\(A\)) + P(\(B\)) - P(\(A \cap B\))
+$PAR
+
+Step 1.
+Using this example, compute:
+$BR
+P(\(A\)) + P(\(B\)) - P(\(A \cap B\)) = \{ ans_rule(12) \}
+$PAR
+
+Step 2 (Verify).
+Now compute the difference:
+$BR
+P(\(A \cup B\)) - (P(\(A\)) - P(\(B\)) + P(\(A \cap B\))) = \{ ans_rule(12) \}
+$PAR
+If the rule checks out, that difference should be 0 (up to rounding).
+END_TEXT
+
+Context("Numeric");
+ANS($cmp_add_rhs);
+ANS($cmp_zero);
+
+Context($ctxSet);
+
+Section::End();
+
+# ----------------------------------------------------------------
+# PILOT RATING (ACTIVE)
+# ----------------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+
+ Section::Begin("Feedback");
+ BEGIN_TEXT
+Rate the usefulness of this guided problem on a scale from 1 to 5.
+$PAR
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+$BR
+Note: Consider using the Email Instructor button below to suggest improvements.
+$PAR
+Rating:
+$BR
+\{ ans_rule(6) \}
+END_TEXT
+
+ Context("Numeric");
+ ANS($cmp_rating);
+ Context($ctxSet);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/tree.jpg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/tree.jpg
new file mode 100644
index 0000000000..a21306c26e
Binary files /dev/null and b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/tree.jpg differ
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/venn_2.png b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/venn_2.png
new file mode 100644
index 0000000000..3f31118fb9
Binary files /dev/null and b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/venn_2.png differ
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/venn_3.png b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/venn_3.png
new file mode 100644
index 0000000000..0be86ad331
Binary files /dev/null and b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/venn_3.png differ
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/venn_intersection.jpg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/venn_intersection.jpg
new file mode 100644
index 0000000000..21ecabc86e
Binary files /dev/null and b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/venn_intersection.jpg differ
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/venn_mutually_exclusive.png b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/venn_mutually_exclusive.png
new file mode 100644
index 0000000000..f0c8b8d4d5
Binary files /dev/null and b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/venn_mutually_exclusive.png differ
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/venn_union.jpg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/venn_union.jpg
new file mode 100644
index 0000000000..dfeef3d126
Binary files /dev/null and b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BasicProbabilityConcepts/venn_union.jpg differ
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_GiudedProblem1.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_GiudedProblem1.pg
new file mode 100644
index 0000000000..c104cc4df4
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_GiudedProblem1.pg
@@ -0,0 +1,247 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Law of Total Probability (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Conditional Probability)
+## Level(2)
+## KEYWORDS('law of total probability','total probability','partition','conditional probability','weighted average')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data
+# =======================================================
+Context("Numeric");
+
+$P_B1 = 0.70; # Factory 1 share
+$P_B2 = 0.30; # Factory 2 share
+$P_A_given_B1 = 0.02; # defect rate from Factory 1
+$P_A_given_B2 = 0.06; # defect rate from Factory 2
+
+$P_A = ($P_A_given_B1) * ($P_B1) + ($P_A_given_B2) * ($P_B2);
+
+# Store values as MathObjects
+$val_pA = Real($P_A);
+$val_d1 = Real($P_A_given_B1);
+$val_w1 = Real($P_B1);
+$val_d2 = Real($P_A_given_B2);
+$val_w2 = Real($P_B2);
+
+# =======================================================
+# Concept checkpoint (MC): When do we use LTP?
+# =======================================================
+$rb_when_ltp = RadioButtons(
+ [
+ "When an event can happen through non-overlapping cases that cover all possibilities (a partition), and we know the conditional probability in each case.",
+ "When two events are independent.",
+ "When we want to reverse a conditional probability (switch the condition).",
+ "When we want to add conditional probabilities directly without any weights.",
+ "When an event depends on only one case and the other cases can be ignored.",
+ ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Guided flow (Scaffold)
+# =======================================================
+Scaffold::Begin();
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A warehouse receives light bulbs from **two factories**.
+
+- **70%** of the bulbs in the warehouse come from **Factory 1**.
+- **30%** of the bulbs in the warehouse come from **Factory 2**.
+- The defect rate is **2%** for bulbs from Factory 1.
+- The defect rate is **6%** for bulbs from Factory 2.
+
+If one bulb is selected at random from the warehouse, find the probability that the bulb is **defective**.
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Law of Total Probability");
+
+# --- Embed image (place venn2.png in SAME folder as this .pg file, or use a relative subfolder path) ---
+
+
+BEGIN_PGML
+Since the warehouse receives light bulbs from two distinct sources, this gives us a natural partitioning of the sample space (all light bulbs in the warehouse).
+
+Let [`B_1`] be the event “the selected bulb came from Factory 1,” and [`B_2`] be the event “the selected bulb came from Factory 2.”
+These two groups don’t overlap, and together they include every bulb in the warehouse.
+
+**Why [`\{B_1,B_2\}`] is a partition in this example:**
+- Every bulb comes from Factory 1 **or** Factory 2, so [`B_1 \cup B_2 = S`].
+- A bulb cannot come from both factories, so [`B_1 \cap B_2 = \varnothing`].
+
+Now let [`A`] be the event “the selected bulb is defective.”
+
+END_PGML
+
+BEGIN_TEXT
+$PAR
+
+\{ image("venn2.png", width => 520) \}
+
+$PAR
+END_TEXT
+
+BEGIN_PGML
+In the diagram, the defective set splits into two non-overlapping (mutually exclusive) pieces: [`A\cap B_1`] and [`A\cap B_2`]. So,
+[`` P(A)=P(A\cap B_1)+P(A\cap B_2). ``]
+
+Each piece is computed using conditional probability:
+[`` P(A\cap B_1)=P(A\mid B_1)P(B_1),\qquad P(A\cap B_2)=P(A\mid B_2)P(B_2). ``]
+
+Putting this together gives the **Law of Total Probability**:
+[`` P(A)=P(A\mid B_1)P(B_1)+P(A\mid B_2)P(B_2). ``]
+
+**Checkpoint (When do we use the Law of Total Probability?)**
+
+[@ $rb_when_ltp->buttons() @]*
+END_PGML
+
+ANS($rb_when_ltp->cmp);
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Compute the probability (using LTP)");
+BEGIN_PGML
+Before using the formula, extract the four probabilities from the problem statement.
+
+Probability that the bulb is defective given it comes from factory 1:
+[`P(A\mid B_1)=`] [__________]{$val_d1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_A_given_B2) < 0.0005 } => "That is the defect rate for Factory 2. Here we want the defect rate for Factory 1.",
+))}
+
+Probability that a randomly selected bulb comes from factory 1:
+[`P(B_1)=`] [__________]{$val_w1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B2) < 0.0005 } => "That is the fraction from Factory 2. Here we want the fraction from Factory 1.",
+))}
+
+Probability that the bulb is defective given it comes from factory 2:
+[`P(A\mid B_2)=`] [__________]{$val_d2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_A_given_B1) < 0.0005 } => "That is the defect rate for Factory 1. Here we want the defect rate for Factory 2.",
+))}
+
+Probability that a randomly selected bulb comes from factory 2:
+[`P(B_2)=`] [__________]{$val_w2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B1) < 0.0005 } => "That is the fraction from Factory 1. Here we want the fraction from Factory 2.",
+))}
+
+Now use the Law of Total Probability:
+[`` P(A)=P(A\mid B_1)P(B_1)+P(A\mid B_2)P(B_2). ``]
+
+Compute [`P(A)`]: [__________]{$val_pA->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { $_[0] < 0.02 } => "This is too small. The overall defect probability should be between 0.02 and 0.06.",
+ sub { $_[0] > 0.06 } => "This is too large. The overall defect probability should be between 0.02 and 0.06.",
+ sub { abs($_[0]-0.02) < 0.0005 || abs($_[0]-0.06) < 0.0005 } =>
+ "Careful: 0.02 and 0.06 are defect rates for a single factory. You still need to combine the factories using their proportions.",
+ sub { abs($_[0]-0.08) < 0.0005 } =>
+ "Looks like you added 0.02 and 0.06 directly. LTP uses a weighted sum: multiply each defect rate by the factory's fraction, then add.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Weighted average viewpoint (solve again)");
+BEGIN_PGML
+Another way to look at this problem is as a **weighted average**.
+
+If you have data values [`d_1, d_2, ..., d_n`] with weights [`w_1, w_2, ..., w_n`] (the weights must add to 1), then
+[`` \text{weighted average} = w_1d_1 + w_2d_2 + ... + w_nd_n, \qquad \text{where } w_1+w_2+...+w_n=1. ``]
+
+In this problem, think of:
+- the [`d`]'s as the **defect rates**
+- the [`w`]'s as the **fractions of bulbs** coming from each factory
+
+**Identify the pieces (use Factory 1 for the “1” subscript and Factory 2 for the “2” subscript):**
+
+[`d_1=`] [__________]{$val_d1->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0]-$P_A_given_B2) < 0.0005 } => "That is the defect rate for Factory 2. Here we want the defect rate for Factory 1.",
+))}
+[`w_1=`] [__________]{$val_w1->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0]-$P_B2) < 0.0005 } => "That is the fraction from Factory 2. Here we want the fraction from Factory 1.",
+))}
+
+[`d_2=`] [__________]{$val_d2->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0]-$P_A_given_B1) < 0.0005 } => "That is the defect rate for Factory 1. Here we want the defect rate for Factory 2.",
+))}
+[`w_2=`] [__________]{$val_w2->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0]-$P_B1) < 0.0005 } => "That is the fraction from Factory 1. Here we want the fraction from Factory 2.",
+))}
+
+Now use the weighted average idea to compute the probability a randomly selected bulb is defective.
+
+Final answer for [`P(A)`]:
+END_PGML
+
+BEGIN_TEXT
+$BR
+\{ NAMED_ANS_RULE("final", 15) \}
+END_TEXT
+
+NAMED_ANS("final", $val_pA->cmp);
+Section::End();
+
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning the Law of Total Probability?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1–5): [___]{Real(3)->cmp(checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return ($v == int($v) && $v >= 1 && $v <= 5);
+ })->withPostFilter(AnswerHints(
+ sub { $_[0] < 1 || $_[0] > 5 } => "Please enter an integer from 1 to 5.",
+ sub { $_[0] != int($_[0]) } => "Please enter a whole number (integer) from 1 to 5.",
+ ))}
+ END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_GiudedProblem2.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_GiudedProblem2.pg
new file mode 100644
index 0000000000..db371f1f82
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_GiudedProblem2.pg
@@ -0,0 +1,296 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Law of Total Probability (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Conditional Probability)
+## Level(2)
+## KEYWORDS('law of total probability','total probability','partition','conditional probability','weighted average','germination')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data
+# =======================================================
+Context("Numeric");
+
+$P_B1 = 0.40; # Supplier 1 share
+$P_B2 = 0.35; # Supplier 2 share
+$P_B3 = 0.25; # Supplier 3 share
+
+$P_A_given_B1 = 0.90; # germination rate from Supplier 1
+$P_A_given_B2 = 0.80; # germination rate from Supplier 2
+$P_A_given_B3 = 0.60; # germination rate from Supplier 3
+
+$P_A = ($P_A_given_B1)*($P_B1) + ($P_A_given_B2)*($P_B2) + ($P_A_given_B3)*($P_B3);
+
+# Store values as MathObjects
+$val_pA = Real($P_A);
+
+$val_d1 = Real($P_A_given_B1);
+$val_w1 = Real($P_B1);
+
+$val_d2 = Real($P_A_given_B2);
+$val_w2 = Real($P_B2);
+
+$val_d3 = Real($P_A_given_B3);
+$val_w3 = Real($P_B3);
+
+# Simple (unweighted) average for a common mistake hint
+$avg_simple = (0.90 + 0.80 + 0.60)/3;
+
+# =======================================================
+# Concept checkpoint (MC): When do we use LTP?
+# =======================================================
+$rb_when_ltp = RadioButtons(
+ [
+ "When an event can happen through non-overlapping cases that cover all possibilities (a partition), and we know the conditional probability in each case.",
+ "When two events are independent.",
+ "When we want to reverse a conditional probability (switch the condition).",
+ "When we want to add conditional probabilities directly without any weights.",
+ "When an event depends on only one case and the other cases can be ignored.",
+ ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Guided flow (Scaffold)
+# =======================================================
+Scaffold::Begin();
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A farmer buys a large batch of seeds from **three different suppliers** and **mixes them completely** in one container.
+
+- **40%** of the seeds come from **Supplier 1**.
+- **35%** of the seeds come from **Supplier 2**.
+- **25%** of the seeds come from **Supplier 3**.
+
+The germination rates (probability a seed germinates) are:
+
+- **90%** for seeds from Supplier 1
+- **80%** for seeds from Supplier 2
+- **60%** for seeds from Supplier 3
+
+If the farmer selects one seed at random from the mixed container, find the probability that the seed **germinates**.
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Law of Total Probability");
+
+BEGIN_PGML
+Since the farmer mixed seeds from three distinct sources, this gives us a natural partitioning of the sample space (all seeds in the container).
+
+Let [`B_1`] be the event “the selected seed came from Supplier 1,” [`B_2`] be the event “the selected seed came from Supplier 2,” and [`B_3`] be the event “the selected seed came from Supplier 3.”
+
+These three groups don’t overlap, and together they include every seed in the container.
+
+**Why [`\{B_1,B_2,B_3\}`] is a partition in this example:**
+- Every seed comes from Supplier 1, Supplier 2, **or** Supplier 3, so [`B_1 \cup B_2 \cup B_3 = S`].
+- A seed cannot come from two suppliers at the same time, so the groups are mutually exclusive, for example
+ [`B_1 \cap B_2 = \varnothing`], [`B_1 \cap B_3 = \varnothing`], and [`B_2 \cap B_3 = \varnothing`].
+
+Now let [`A`] be the event “the selected seed **germinates**.”
+END_PGML
+
+BEGIN_TEXT
+$PAR
+
+\{ image("venn3.png", width => 520) \}
+
+$PAR
+END_TEXT
+
+BEGIN_PGML
+In the diagram, the event [`A`] splits into three non-overlapping pieces: [`A\cap B_1`], [`A\cap B_2`], and [`A\cap B_3`]. So,
+[`` P(A)=P(A\cap B_1)+P(A\cap B_2)+P(A\cap B_3). ``]
+
+Each piece is computed using conditional probability:
+[`` P(A\cap B_1)=P(A\mid B_1)P(B_1),\quad P(A\cap B_2)=P(A\mid B_2)P(B_2),\quad P(A\cap B_3)=P(A\mid B_3)P(B_3). ``]
+
+Putting this together gives the **Law of Total Probability**:
+[`` P(A)=P(A\mid B_1)P(B_1)+P(A\mid B_2)P(B_2)+P(A\mid B_3)P(B_3). ``]
+
+**Checkpoint (When do we use the Law of Total Probability?)**
+
+[@ $rb_when_ltp->buttons() @]*
+END_PGML
+
+ANS($rb_when_ltp->cmp);
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Compute the probability (using LTP)");
+BEGIN_PGML
+Before using the formula, extract the six probabilities from the problem statement.
+
+Probability that the seed germinates given it comes from Supplier 1:
+[`P(A\mid B_1)=`] [__________]{$val_d1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_A_given_B2) < 0.0005 } => "That is the germination rate for Supplier 2. Here we want the germination rate for Supplier 1.",
+ sub { abs($_[0]-$P_A_given_B3) < 0.0005 } => "That is the germination rate for Supplier 3. Here we want the germination rate for Supplier 1.",
+))}
+
+Probability that a randomly selected seed comes from Supplier 1:
+[`P(B_1)=`] [__________]{$val_w1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B2) < 0.0005 } => "That is the fraction from Supplier 2. Here we want the fraction from Supplier 1.",
+ sub { abs($_[0]-$P_B3) < 0.0005 } => "That is the fraction from Supplier 3. Here we want the fraction from Supplier 1.",
+))}
+
+Probability that the seed germinates given it comes from Supplier 2:
+[`P(A\mid B_2)=`] [__________]{$val_d2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_A_given_B1) < 0.0005 } => "That is the germination rate for Supplier 1. Here we want the germination rate for Supplier 2.",
+ sub { abs($_[0]-$P_A_given_B3) < 0.0005 } => "That is the germination rate for Supplier 3. Here we want the germination rate for Supplier 2.",
+))}
+
+Probability that a randomly selected seed comes from Supplier 2:
+[`P(B_2)=`] [__________]{$val_w2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B1) < 0.0005 } => "That is the fraction from Supplier 1. Here we want the fraction from Supplier 2.",
+ sub { abs($_[0]-$P_B3) < 0.0005 } => "That is the fraction from Supplier 3. Here we want the fraction from Supplier 2.",
+))}
+
+Probability that the seed germinates given it comes from Supplier 3:
+[`P(A\mid B_3)=`] [__________]{$val_d3->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_A_given_B1) < 0.0005 } => "That is the germination rate for Supplier 1. Here we want the germination rate for Supplier 3.",
+ sub { abs($_[0]-$P_A_given_B2) < 0.0005 } => "That is the germination rate for Supplier 2. Here we want the germination rate for Supplier 3.",
+))}
+
+Probability that a randomly selected seed comes from Supplier 3:
+[`P(B_3)=`] [__________]{$val_w3->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B1) < 0.0005 } => "That is the fraction from Supplier 1. Here we want the fraction from Supplier 3.",
+ sub { abs($_[0]-$P_B2) < 0.0005 } => "That is the fraction from Supplier 2. Here we want the fraction from Supplier 3.",
+))}
+
+Now use the Law of Total Probability:
+[`` P(A)=P(A\mid B_1)P(B_1)+P(A\mid B_2)P(B_2)+P(A\mid B_3)P(B_3). ``]
+
+Compute [`P(A)`]: [__________]{$val_pA->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { $_[0] < 0.60 } => "This is too small. The overall germination probability should be between 0.60 and 0.90.",
+ sub { $_[0] > 0.90 } => "This is too large. The overall germination probability should be between 0.60 and 0.90.",
+ sub { abs($_[0]-0.90) < 0.0005 || abs($_[0]-0.80) < 0.0005 || abs($_[0]-0.60) < 0.0005 } =>
+ "Careful: 0.90, 0.80, and 0.60 are conditional germination rates for a single supplier. You still need to combine suppliers using their fractions.",
+ sub { abs($_[0]-$avg_simple) < 0.0008 } =>
+ "Looks like you used a simple average of the three rates. Here we need a weighted average using 0.40, 0.35, and 0.25 as weights.",
+ sub { abs($_[0]-(0.90+0.80+0.60)) < 0.0005 } =>
+ "Looks like you added the three rates directly. LTP uses a weighted sum: multiply each rate by its supplier fraction, then add.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Weighted average viewpoint (solve again)");
+BEGIN_PGML
+Another way to look at this problem is as a **weighted average**.
+
+If you have data values [`d_1, d_2, ..., d_n`] with weights [`w_1, w_2, ..., w_n`] (the weights must add to 1), then
+[`` \text{weighted average} = w_1d_1 + w_2d_2 + ... + w_nd_n, \qquad \text{where } w_1+w_2+...+w_n=1. ``]
+
+In this problem, think of:
+- the [`d`]'s as the **germination rates**
+- the [`w`]'s as the **fractions of seeds** coming from each supplier
+
+**Identify the pieces (use Supplier 1 for the “1” subscript, Supplier 2 for “2”, Supplier 3 for “3”):**
+
+[`d_1=`] [__________]{$val_d1->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0]-$P_A_given_B2) < 0.0005 } => "That is the germination rate for Supplier 2. Here we want Supplier 1.",
+ sub { abs($_[0]-$P_A_given_B3) < 0.0005 } => "That is the germination rate for Supplier 3. Here we want Supplier 1.",
+))}
+[`w_1=`] [__________]{$val_w1->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0]-$P_B2) < 0.0005 } => "That is the fraction from Supplier 2. Here we want Supplier 1.",
+ sub { abs($_[0]-$P_B3) < 0.0005 } => "That is the fraction from Supplier 3. Here we want Supplier 1.",
+))}
+
+[`d_2=`] [__________]{$val_d2->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0]-$P_A_given_B1) < 0.0005 } => "That is the germination rate for Supplier 1. Here we want Supplier 2.",
+ sub { abs($_[0]-$P_A_given_B3) < 0.0005 } => "That is the germination rate for Supplier 3. Here we want Supplier 2.",
+))}
+[`w_2=`] [__________]{$val_w2->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0]-$P_B1) < 0.0005 } => "That is the fraction from Supplier 1. Here we want Supplier 2.",
+ sub { abs($_[0]-$P_B3) < 0.0005 } => "That is the fraction from Supplier 3. Here we want Supplier 2.",
+))}
+
+[`d_3=`] [__________]{$val_d3->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0]-$P_A_given_B1) < 0.0005 } => "That is the germination rate for Supplier 1. Here we want Supplier 3.",
+ sub { abs($_[0]-$P_A_given_B2) < 0.0005 } => "That is the germination rate for Supplier 2. Here we want Supplier 3.",
+))}
+[`w_3=`] [__________]{$val_w3->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0]-$P_B1) < 0.0005 } => "That is the fraction from Supplier 1. Here we want Supplier 3.",
+ sub { abs($_[0]-$P_B2) < 0.0005 } => "That is the fraction from Supplier 2. Here we want Supplier 3.",
+))}
+
+Now use the weighted average idea to compute the probability that a randomly selected seed germinates.
+
+Final answer for [`P(A)`]:
+END_PGML
+
+BEGIN_TEXT
+$BR
+\{ NAMED_ANS_RULE("final", 15) \}
+END_TEXT
+
+NAMED_ANS("final", $val_pA->cmp);
+Section::End();
+
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning the Law of Total Probability?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1–5): [___]{Real(3)->cmp(checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return ($v == int($v) && $v >= 1 && $v <= 5);
+ })->withPostFilter(AnswerHints(
+ sub { $_[0] < 1 || $_[0] > 5 } => "Please enter an integer from 1 to 5.",
+ sub { $_[0] != int($_[0]) } => "Please enter a whole number (integer) from 1 to 5.",
+ ))}
+ END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_GiudedProblem3.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_GiudedProblem3.pg
new file mode 100644
index 0000000000..5d8902cf8e
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_GiudedProblem3.pg
@@ -0,0 +1,339 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Law of Total Probability (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Conditional Probability)
+## Level(2)
+## KEYWORDS('law of total probability','total probability','partition','conditional probability','weighted average','diagnostic test')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data
+# =======================================================
+Context("Numeric");
+
+# Partitions (age groups)
+$P_B1 = 0.20; # ages 0-17
+$P_B2 = 0.30; # ages 18-39
+$P_B3 = 0.35; # ages 40-64
+$P_B4 = 0.15; # ages 65+
+
+# Conditional probabilities (positive test rates by group)
+$P_A_given_B1 = 0.03;
+$P_A_given_B2 = 0.05;
+$P_A_given_B3 = 0.08;
+$P_A_given_B4 = 0.12;
+
+# Overall probability of a positive test
+$P_A = ($P_A_given_B1)*($P_B1) + ($P_A_given_B2)*($P_B2) + ($P_A_given_B3)*($P_B3) + ($P_A_given_B4)*($P_B4);
+
+# Store values as MathObjects
+$val_pA = Real($P_A);
+
+$val_d1 = Real($P_A_given_B1); $val_w1 = Real($P_B1);
+$val_d2 = Real($P_A_given_B2); $val_w2 = Real($P_B2);
+$val_d3 = Real($P_A_given_B3); $val_w3 = Real($P_B3);
+$val_d4 = Real($P_A_given_B4); $val_w4 = Real($P_B4);
+
+# Common mistake: simple average of the four rates
+$avg_simple = ($P_A_given_B1 + $P_A_given_B2 + $P_A_given_B3 + $P_A_given_B4)/4;
+
+# =======================================================
+# Concept checkpoint (MC): When do we use LTP?
+# =======================================================
+$rb_when_ltp = RadioButtons(
+ [
+ "When an event can happen through non-overlapping cases that cover all possibilities (a partition), and we know the conditional probability in each case.",
+ "When two events are independent.",
+ "When we want to reverse a conditional probability (switch the condition).",
+ "When we want to add conditional probabilities directly without any weights.",
+ "When an event depends on only one case and the other cases can be ignored.",
+ ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Guided flow (Scaffold)
+# =======================================================
+Scaffold::Begin();
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A clinic serves patients from **four age groups**:
+
+- **20%** are ages **0-17**
+- **30%** are ages **18-39**
+- **35%** are ages **40-64**
+- **15%** are ages **65+**
+
+The probability that a patient tests **positive** depends on the age group:
+
+- **3%** for ages **0-17**
+- **5%** for ages **18-39**
+- **8%** for ages **40-64**
+- **12%** for ages **65+**
+
+If one patient is selected at random from the clinic, find the probability that the test result is **positive**.
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Law of Total Probability (general case)");
+
+BEGIN_PGML
+Since the clinic sees patients from several distinct age groups, this gives us a natural partitioning of the sample space (all patients).
+
+Let [`A`] be the event “the test result is positive.”
+
+For the general case, suppose we have a partition [`B_1, B_2, B_3, ..., B_n`] of the sample space. That means:
+- every outcome belongs to exactly one of these groups
+- together they cover all possibilities
+
+In this problem, we have [`n=4`] age groups, so the groups are [`B_1, B_2, B_3, B_4`].
+END_PGML
+
+BEGIN_TEXT
+$PAR
+\{ image("vennn.png", width => 520) \}
+$PAR
+END_TEXT
+
+BEGIN_PGML
+Because the groups form a partition, the event [`A`] can be split into non-overlapping pieces:
+[`A\cap B_1, A\cap B_2, ..., A\cap B_n`].
+
+So the probability adds:
+[`` P(A)=P(A\cap B_1)+P(A\cap B_2)+\cdots+P(A\cap B_n). ``]
+
+Each piece is computed using conditional probability:
+[`` P(A\cap B_i)=P(A\mid B_i)\,P(B_i). ``]
+
+Putting this together gives the **Law of Total Probability**:
+[`` P(A)=\sum_{i=1}^{n} P(A\mid B_i)\,P(B_i). ``]
+
+For this problem (4 groups), that becomes:
+[`` P(A)=P(A\mid B_1)P(B_1)+P(A\mid B_2)P(B_2)+P(A\mid B_3)P(B_3)+P(A\mid B_4)P(B_4). ``]
+
+**Checkpoint (When do we use the Law of Total Probability?)**
+
+[@ $rb_when_ltp->buttons() @]*
+END_PGML
+
+ANS($rb_when_ltp->cmp);
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Compute the probability (using LTP)");
+BEGIN_PGML
+Before using the formula, extract the probabilities from the problem statement.
+
+Probability of a positive test given age group 0-17:
+[`P(A\mid B_1)=`] [__________]{$val_d1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_A_given_B2) < 0.0005 } => "That is the positive-test rate for age group 18-39. Here we want 0-17.",
+ sub { abs($_[0]-$P_A_given_B3) < 0.0005 } => "That is the positive-test rate for age group 40-64. Here we want 0-17.",
+ sub { abs($_[0]-$P_A_given_B4) < 0.0005 } => "That is the positive-test rate for age group 65+. Here we want 0-17.",
+))}
+
+Probability a randomly selected patient is in age group 0-17:
+[`P(B_1)=`] [__________]{$val_w1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B2) < 0.0005 } => "That is the fraction for age group 18-39. Here we want 0-17.",
+ sub { abs($_[0]-$P_B3) < 0.0005 } => "That is the fraction for age group 40-64. Here we want 0-17.",
+ sub { abs($_[0]-$P_B4) < 0.0005 } => "That is the fraction for age group 65+. Here we want 0-17.",
+))}
+
+Probability of a positive test given age group 18-39:
+[`P(A\mid B_2)=`] [__________]{$val_d2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_A_given_B1) < 0.0005 } => "That is the positive-test rate for age group 0-17. Here we want 18-39.",
+ sub { abs($_[0]-$P_A_given_B3) < 0.0005 } => "That is the positive-test rate for age group 40-64. Here we want 18-39.",
+ sub { abs($_[0]-$P_A_given_B4) < 0.0005 } => "That is the positive-test rate for age group 65+. Here we want 18-39.",
+))}
+
+Probability a randomly selected patient is in age group 18-39:
+[`P(B_2)=`] [__________]{$val_w2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B1) < 0.0005 } => "That is the fraction for age group 0-17. Here we want 18-39.",
+ sub { abs($_[0]-$P_B3) < 0.0005 } => "That is the fraction for age group 40-64. Here we want 18-39.",
+ sub { abs($_[0]-$P_B4) < 0.0005 } => "That is the fraction for age group 65+. Here we want 18-39.",
+))}
+
+Probability of a positive test given age group 40-64:
+[`P(A\mid B_3)=`] [__________]{$val_d3->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_A_given_B1) < 0.0005 } => "That is the positive-test rate for age group 0-17. Here we want 40-64.",
+ sub { abs($_[0]-$P_A_given_B2) < 0.0005 } => "That is the positive-test rate for age group 18-39. Here we want 40-64.",
+ sub { abs($_[0]-$P_A_given_B4) < 0.0005 } => "That is the positive-test rate for age group 65+. Here we want 40-64.",
+))}
+
+Probability a randomly selected patient is in age group 40-64:
+[`P(B_3)=`] [__________]{$val_w3->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B1) < 0.0005 } => "That is the fraction for age group 0-17. Here we want 40-64.",
+ sub { abs($_[0]-$P_B2) < 0.0005 } => "That is the fraction for age group 18-39. Here we want 40-64.",
+ sub { abs($_[0]-$P_B4) < 0.0005 } => "That is the fraction for age group 65+. Here we want 40-64.",
+))}
+
+Probability of a positive test given age group 65+:
+[`P(A\mid B_4)=`] [__________]{$val_d4->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_A_given_B1) < 0.0005 } => "That is the positive-test rate for age group 0-17. Here we want 65+.",
+ sub { abs($_[0]-$P_A_given_B2) < 0.0005 } => "That is the positive-test rate for age group 18-39. Here we want 65+.",
+ sub { abs($_[0]-$P_A_given_B3) < 0.0005 } => "That is the positive-test rate for age group 40-64. Here we want 65+.",
+))}
+
+Probability a randomly selected patient is in age group 65+:
+[`P(B_4)=`] [__________]{$val_w4->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B1) < 0.0005 } => "That is the fraction for age group 0-17. Here we want 65+.",
+ sub { abs($_[0]-$P_B2) < 0.0005 } => "That is the fraction for age group 18-39. Here we want 65+.",
+ sub { abs($_[0]-$P_B3) < 0.0005 } => "That is the fraction for age group 40-64. Here we want 65+.",
+))}
+
+Now use the Law of Total Probability:
+[`` P(A)=P(A\mid B_1)P(B_1)+P(A\mid B_2)P(B_2)+P(A\mid B_3)P(B_3)+P(A\mid B_4)P(B_4). ``]
+
+Compute [`P(A)`]: [__________]{$val_pA->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { $_[0] < 0.03 } => "This is too small. The overall probability should be between 0.03 and 0.12.",
+ sub { $_[0] > 0.12 } => "This is too large. The overall probability should be between 0.03 and 0.12.",
+ sub { abs($_[0]-$P_A_given_B1) < 0.0005 || abs($_[0]-$P_A_given_B2) < 0.0005 || abs($_[0]-$P_A_given_B3) < 0.0005 || abs($_[0]-$P_A_given_B4) < 0.0005 } =>
+ "Careful: those are conditional probabilities for a single group. You still need a weighted sum using the group proportions.",
+ sub { abs($_[0]-$avg_simple) < 0.0008 } =>
+ "Looks like you used a simple average of the four rates. Here we need a weighted average using 0.20, 0.30, 0.35, and 0.15 as weights.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Weighted average viewpoint (solve again)");
+BEGIN_PGML
+Another way to look at this problem is as a **weighted average**.
+
+If you have data values [`d_1, d_2, ..., d_n`] with weights [`w_1, w_2, ..., w_n`] (the weights must add to 1), then
+[`` \text{weighted average} = w_1d_1 + w_2d_2 + ... + w_nd_n, \qquad \text{where } w_1+w_2+...+w_n=1. ``]
+
+In this problem, think of:
+- the [`d`]'s as the positive-test rates
+- the [`w`]'s as the fractions of patients in each age group
+
+**Identify the pieces (use age groups 0-17, 18-39, 40-64, 65+ as 1, 2, 3, 4):**
+
+[`d_1=`] [__________]{$val_d1->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0]-$P_A_given_B2) < 0.0005 } => "That rate belongs to age group 18-39. Here we want 0-17.",
+ sub { abs($_[0]-$P_A_given_B3) < 0.0005 } => "That rate belongs to age group 40-64. Here we want 0-17.",
+ sub { abs($_[0]-$P_A_given_B4) < 0.0005 } => "That rate belongs to age group 65+. Here we want 0-17.",
+))}
+[`w_1=`] [__________]{$val_w1->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0]-$P_B2) < 0.0005 } => "That fraction belongs to age group 18-39. Here we want 0-17.",
+ sub { abs($_[0]-$P_B3) < 0.0005 } => "That fraction belongs to age group 40-64. Here we want 0-17.",
+ sub { abs($_[0]-$P_B4) < 0.0005 } => "That fraction belongs to age group 65+. Here we want 0-17.",
+))}
+
+[`d_2=`] [__________]{$val_d2->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0]-$P_A_given_B1) < 0.0005 } => "That rate belongs to age group 0-17. Here we want 18-39.",
+ sub { abs($_[0]-$P_A_given_B3) < 0.0005 } => "That rate belongs to age group 40-64. Here we want 18-39.",
+ sub { abs($_[0]-$P_A_given_B4) < 0.0005 } => "That rate belongs to age group 65+. Here we want 18-39.",
+))}
+[`w_2=`] [__________]{$val_w2->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0]-$P_B1) < 0.0005 } => "That fraction belongs to age group 0-17. Here we want 18-39.",
+ sub { abs($_[0]-$P_B3) < 0.0005 } => "That fraction belongs to age group 40-64. Here we want 18-39.",
+ sub { abs($_[0]-$P_B4) < 0.0005 } => "That fraction belongs to age group 65+. Here we want 18-39.",
+))}
+
+[`d_3=`] [__________]{$val_d3->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0]-$P_A_given_B1) < 0.0005 } => "That rate belongs to age group 0-17. Here we want 40-64.",
+ sub { abs($_[0]-$P_A_given_B2) < 0.0005 } => "That rate belongs to age group 18-39. Here we want 40-64.",
+ sub { abs($_[0]-$P_A_given_B4) < 0.0005 } => "That rate belongs to age group 65+. Here we want 40-64.",
+))}
+[`w_3=`] [__________]{$val_w3->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0]-$P_B1) < 0.0005 } => "That fraction belongs to age group 0-17. Here we want 40-64.",
+ sub { abs($_[0]-$P_B2) < 0.0005 } => "That fraction belongs to age group 18-39. Here we want 40-64.",
+ sub { abs($_[0]-$P_B4) < 0.0005 } => "That fraction belongs to age group 65+. Here we want 40-64.",
+))}
+
+[`d_4=`] [__________]{$val_d4->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0]-$P_A_given_B1) < 0.0005 } => "That rate belongs to age group 0-17. Here we want 65+.",
+ sub { abs($_[0]-$P_A_given_B2) < 0.0005 } => "That rate belongs to age group 18-39. Here we want 65+.",
+ sub { abs($_[0]-$P_A_given_B3) < 0.0005 } => "That rate belongs to age group 40-64. Here we want 65+.",
+))}
+[`w_4=`] [__________]{$val_w4->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0]-$P_B1) < 0.0005 } => "That fraction belongs to age group 0-17. Here we want 65+.",
+ sub { abs($_[0]-$P_B2) < 0.0005 } => "That fraction belongs to age group 18-39. Here we want 65+.",
+ sub { abs($_[0]-$P_B3) < 0.0005 } => "That fraction belongs to age group 40-64. Here we want 65+.",
+))}
+
+Now use the weighted average idea to compute the probability that a randomly selected patient tests positive.
+
+Final answer for [`P(A)`]:
+END_PGML
+
+BEGIN_TEXT
+$BR
+\{ NAMED_ANS_RULE("final", 15) \}
+END_TEXT
+
+NAMED_ANS("final", $val_pA->cmp);
+Section::End();
+
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning the Law of Total Probability?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1–5): [___]{Real(3)->cmp(checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return ($v == int($v) && $v >= 1 && $v <= 5);
+ })->withPostFilter(AnswerHints(
+ sub { $_[0] < 1 || $_[0] > 5 } => "Please enter an integer from 1 to 5.",
+ sub { $_[0] != int($_[0]) } => "Please enter a whole number (integer) from 1 to 5.",
+ ))}
+ END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_GiudedProblem4.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_GiudedProblem4.pg
new file mode 100644
index 0000000000..9eb6451859
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_GiudedProblem4.pg
@@ -0,0 +1,318 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Bayes' Theorem (Guided / Scaffolded) — Warehouse Bulbs (2 Factories)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Conditional Probability)
+## Level(2)
+## KEYWORDS('Bayes theorem','Bayes','law of total probability','partition','conditional probability','defective bulbs')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data
+# =======================================================
+Context("Numeric");
+
+$P_B1 = 0.70; # Factory 1 share
+$P_B2 = 0.30; # Factory 2 share
+$P_A_given_B1 = 0.02; # defect rate from Factory 1
+$P_A_given_B2 = 0.06; # defect rate from Factory 2
+
+# P(A) via LTP
+$P_A = ($P_A_given_B1)*($P_B1) + ($P_A_given_B2)*($P_B2);
+
+# Bayes: P(B2|A)
+$P_B2_given_A = ($P_A_given_B2 * $P_B2) / $P_A;
+$P_B1_given_A = 1 - $P_B2_given_A;
+
+# 1000-bulb intuition numbers (expected counts)
+$N_total = 1000;
+$N_B1 = $N_total * $P_B1; # 700
+$N_B2 = $N_total * $P_B2; # 300
+$N_A_B1 = $N_B1 * $P_A_given_B1; # 14
+$N_A_B2 = $N_B2 * $P_A_given_B2; # 18
+$N_A = $N_A_B1 + $N_A_B2; # 32
+
+# Store values as MathObjects
+$val_pA = Real($P_A);
+$val_B2_givenA = Real($P_B2_given_A);
+$val_B1_givenA = Real($P_B1_given_A);
+
+$val_d1 = Real($P_A_given_B1);
+$val_w1 = Real($P_B1);
+$val_d2 = Real($P_A_given_B2);
+$val_w2 = Real($P_B2);
+
+$val_N_A_B1 = Real($N_A_B1);
+$val_N_A_B2 = Real($N_A_B2);
+$val_N_A = Real($N_A);
+
+# =======================================================
+# Concept checkpoints (MC)
+# =======================================================
+$rb_when_bayes = RadioButtons(
+ [
+ 'When we know probabilities like \(P(A\mid B_i)\) and want a probability like \(P(B_i\mid A)\) (reverse the conditioning), using cases \(B_1,B_2,\ldots\) that cover all possibilities.',
+ 'When two events are independent.',
+ 'When we want to add probabilities of disjoint events (no conditioning).',
+ 'When we already know \(P(B_i\mid A)\) and want \(P(A\mid B_i)\).',
+ 'When we want to compute \(P(A\cap B)\) by adding \(P(A)\) and \(P(B)\).',
+ ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+$rb_need_ltp = RadioButtons(
+ [
+ 'Because Bayes’ Theorem needs \(P(A)\) in the denominator, and we compute \(P(A)\) by combining the cases using the Law of Total Probability.',
+ 'Because Bayes’ Theorem only works if the events are independent.',
+ 'Because \(P(A)=P(B_1)+P(B_2)\) always.',
+ 'Because \(P(A\mid B_1)=P(A\mid B_2)\) must be true first.',
+ 'Because we must always compute \(P(B_1\mid A)\) before \(P(B_2\mid A)\).',
+ ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Guided flow (Scaffold)
+# =======================================================
+Scaffold::Begin();
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A warehouse receives light bulbs from **two factories**.
+
+- **70%** of the bulbs in the warehouse come from **Factory 1** and **2%** of Factory 1 bulbs are defective.
+- **30%** of the bulbs in the warehouse come from **Factory 2** and **6%** of Factory 2 bulbs are defective.
+
+A bulb is selected at random **and it is found to be defective**.
+
+Find the probability that the bulb came from **Factory 2**.
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Bayes' Theorem (setup)");
+
+BEGIN_PGML
+Let [`A`] be the event “the bulb is defective.”
+Let [`B_1`] be the event “the bulb came from Factory 1,” and [`B_2`] be the event “the bulb came from Factory 2.”
+
+We are told the bulb is defective (event [`A`] happened), and we want [`P(B_2\mid A)`].
+END_PGML
+
+BEGIN_TEXT
+$PAR
+
+\{ image("venn2.png", width => 520) \}
+
+$PAR
+END_TEXT
+
+BEGIN_PGML
+From the definition of conditional probability:
+[`` P(B_2\mid A)=\dfrac{P(A\cap B_2)}{P(A)}. ``]
+
+Also,
+[`` P(A\cap B_2)=P(A\mid B_2)\,P(B_2). ``]
+
+So Bayes’ Theorem (for this problem) is:
+[`` P(B_2\mid A)=\dfrac{P(A\mid B_2)\,P(B_2)}{P(A)}. ``]
+
+**Checkpoint (When do we use Bayes’ Theorem?)**
+
+[@ $rb_when_bayes->buttons() @]*
+END_PGML
+
+ANS($rb_when_bayes->cmp);
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Find P(A) using the Law of Total Probability");
+
+BEGIN_PGML
+To use Bayes’ Theorem we need [`P(A)`] in the denominator.
+
+**Checkpoint (Why do we use the Law of Total Probability here?)**
+
+[@ $rb_need_ltp->buttons() @]*
+END_PGML
+ANS($rb_need_ltp->cmp);
+
+BEGIN_PGML
+Now extract the four probabilities from the problem statement.
+
+Probability the bulb is defective given it comes from Factory 1:
+[`P(A\mid B_1)=`] [__________]{$val_d1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_A_given_B2) < 0.0005 } => "That is the defect rate for Factory 2. Here we want the defect rate for Factory 1.",
+))}
+
+Probability a randomly selected bulb comes from Factory 1:
+[`P(B_1)=`] [__________]{$val_w1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B2) < 0.0005 } => "That is the fraction from Factory 2. Here we want the fraction from Factory 1.",
+))}
+
+Probability the bulb is defective given it comes from Factory 2:
+[`P(A\mid B_2)=`] [__________]{$val_d2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_A_given_B1) < 0.0005 } => "That is the defect rate for Factory 1. Here we want the defect rate for Factory 2.",
+))}
+
+Probability a randomly selected bulb comes from Factory 2:
+[`P(B_2)=`] [__________]{$val_w2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B1) < 0.0005 } => "That is the fraction from Factory 1. Here we want the fraction from Factory 2.",
+))}
+
+Now use the Law of Total Probability:
+[`` P(A)=P(A\mid B_1)P(B_1)+P(A\mid B_2)P(B_2). ``]
+
+Compute [`P(A)`]: [__________]{$val_pA->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { $_[0] < 0.02 } => "This is too small. P(A) should be between 0.02 and 0.06.",
+ sub { $_[0] > 0.06 } => "This is too large. P(A) should be between 0.02 and 0.06.",
+ sub { abs($_[0]-0.02) < 0.0005 || abs($_[0]-0.06) < 0.0005 } =>
+ "Careful: 0.02 and 0.06 are conditional defect rates for a single factory. You must use the weighted sum.",
+ sub { abs($_[0]-0.08) < 0.0005 } =>
+ "Looks like you added 0.02 and 0.06 directly. Multiply each defect rate by its factory fraction, then add.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Use Bayes' Theorem to find P(B2 | A)");
+
+BEGIN_PGML
+Now apply Bayes’ Theorem:
+[`` P(B_2\mid A)=\dfrac{P(A\mid B_2)\,P(B_2)}{P(A)}. ``]
+
+Compute [`P(B_2\mid A)`]: [__________]{$val_B2_givenA->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B2) < 0.001 } =>
+ "That is P(B_2) (the overall factory-2 fraction). Here we want P(B_2|A), given that the bulb is defective.",
+ sub { abs($_[0]-$P_A_given_B2) < 0.001 } =>
+ "That is P(A|B_2) (defect rate from Factory 2). Here we want P(B_2|A). Use Bayes: divide by P(A).",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Fast way to find P(B1 | A)");
+
+BEGIN_PGML
+Hint: The defective bulb must either come from Factory 1 or Factory 2.
+
+We already know [`P(B_2\mid A)`].
+So there is a fast way to find [`P(B_1\mid A)`].
+
+Compute [`P(B_1\mid A)`]: [__________]{$val_B1_givenA->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B1) < 0.001 } =>
+ "That is P(B_1) (the overall factory-1 fraction). Here we want P(B_1|A), given that the bulb is defective.",
+ sub { abs($_[0]-$P_B2_given_A) < 0.001 } =>
+ "That looks like P(B_2|A). For P(B_1|A), use 1 - P(B_2|A).",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("An intuitive way of understanding the Bayes' Theorem");
+
+BEGIN_PGML
+An intuitive way of understanding Bayes’ Theorem is to pretend we have **1000 bulbs**.
+
+From the problem statement:
+- about [`700`] bulbs come from Factory 1 and about [`300`] bulbs come from Factory 2.
+- among the Factory 1 bulbs, about [`2%`] are defective.
+- among the Factory 2 bulbs, about [`6%`] are defective.
+
+Now compute the **expected** number of defective bulbs from each factory (out of 1000 total).
+
+Defective from Factory 1 (out of 1000): [__________]{$val_N_A_B1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-$N_A_B2) < 0.5 } => "That looks like the Factory 2 defective count. Here we want Factory 1.",
+))}
+
+Defective from Factory 2 (out of 1000): [__________]{$val_N_A_B2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-$N_A_B1) < 0.5 } => "That looks like the Factory 1 defective count. Here we want Factory 2.",
+))}
+
+Total defective (out of 1000): [__________]{$val_N_A->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-$N_A_B1) < 0.5 || abs($_[0]-$N_A_B2) < 0.5 } =>
+ "That is only one piece. Total defective is defective from Factory 1 plus defective from Factory 2.",
+))}
+
+Now, among the defective bulbs, the fraction that came from Factory 2 is:
+[`` P(B_2\mid A)=\dfrac{\text{defective from Factory 2}}{\text{total defective}}. ``]
+
+Compute [`P(B_2\mid A)`] using the 1000-bulb table idea: [__________]{$val_B2_givenA->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B2) < 0.001 } =>
+ "That is P(B_2), not P(B_2|A). Use (defective from Factory 2)/(total defective).",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning Bayes’ Theorem?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1–5): [___]{Real(3)->cmp(checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return ($v == int($v) && $v >= 1 && $v <= 5);
+ })->withPostFilter(AnswerHints(
+ sub { $_[0] < 1 || $_[0] > 5 } => "Please enter an integer from 1 to 5.",
+ sub { $_[0] != int($_[0]) } => "Please enter a whole number (integer) from 1 to 5.",
+ ))}
+ END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_GiudedProblem5.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_GiudedProblem5.pg
new file mode 100644
index 0000000000..d79baf1b62
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_GiudedProblem5.pg
@@ -0,0 +1,368 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Bayes' Theorem (Guided / Scaffolded) — Mixed Seeds (3 Suppliers)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Conditional Probability)
+## Level(2)
+## KEYWORDS('Bayes theorem','Bayes','law of total probability','total probability','partition','conditional probability','seeds','germination')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data
+# =======================================================
+Context("Numeric");
+
+# Shares (3 suppliers) -- same percentages
+$P_B1 = 0.50; # Supplier 1 share
+$P_B2 = 0.30; # Supplier 2 share
+$P_B3 = 0.20; # Supplier 3 share
+
+# Germination rates
+$P_A_given_B1 = 0.90;
+$P_A_given_B2 = 0.80;
+$P_A_given_B3 = 0.60;
+
+# P(A) via Law of Total Probability
+$P_A = ($P_A_given_B1)*($P_B1) + ($P_A_given_B2)*($P_B2) + ($P_A_given_B3)*($P_B3);
+
+# Bayes posteriors
+$P_B1_given_A = ($P_A_given_B1 * $P_B1) / $P_A;
+$P_B2_given_A = ($P_A_given_B2 * $P_B2) / $P_A;
+$P_B3_given_A = ($P_A_given_B3 * $P_B3) / $P_A;
+
+# 1000-seed intuition numbers (expected counts)
+$N_total = 1000;
+
+$N_B1 = $N_total * $P_B1; # 500
+$N_B2 = $N_total * $P_B2; # 300
+$N_B3 = $N_total * $P_B3; # 200
+
+$N_A_B1 = $N_B1 * $P_A_given_B1; # 450
+$N_A_B2 = $N_B2 * $P_A_given_B2; # 240
+$N_A_B3 = $N_B3 * $P_A_given_B3; # 120
+$N_A = $N_A_B1 + $N_A_B2 + $N_A_B3; # 810
+
+# Store values as MathObjects
+$val_pA = Real($P_A);
+
+$val_d1 = Real($P_A_given_B1); $val_w1 = Real($P_B1);
+$val_d2 = Real($P_A_given_B2); $val_w2 = Real($P_B2);
+$val_d3 = Real($P_A_given_B3); $val_w3 = Real($P_B3);
+
+$val_B1_givenA = Real($P_B1_given_A);
+$val_B2_givenA = Real($P_B2_given_A);
+$val_B3_givenA = Real($P_B3_given_A);
+
+$val_N_A_B1 = Real($N_A_B1);
+$val_N_A_B2 = Real($N_A_B2);
+$val_N_A_B3 = Real($N_A_B3);
+$val_N_A = Real($N_A);
+
+# =======================================================
+# Concept checkpoints (MC)
+# =======================================================
+$rb_when_bayes = RadioButtons(
+ [
+ 'When we know probabilities like \(P(A\mid B_i)\) and want a probability like \(P(B_i\mid A)\) (reverse the conditioning), using cases \(B_1,B_2,B_3,\ldots\) that cover all possibilities.',
+ 'When two events are independent.',
+ 'When we want to add probabilities of disjoint events (no conditioning).',
+ 'When we already know \(P(B_i\mid A)\) and want \(P(A\mid B_i)\).',
+ 'When we want to compute \(P(A\cap B)\) by adding \(P(A)\) and \(P(B)\).',
+ ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+$rb_need_ltp = RadioButtons(
+ [
+ 'Because Bayes Theorem needs \(P(A)\) in the denominator, and we compute \(P(A)\) by combining the cases using the Law of Total Probability.',
+ 'Because Bayes Theorem only works if the events are independent.',
+ 'Because \(P(A)=P(B_1)+P(B_2)+P(B_3)\) always.',
+ 'Because \(P(A\mid B_1)=P(A\mid B_2)=P(A\mid B_3)\) must be true first.',
+ 'Because we must always compute \(P(B_1\mid A)\) before \(P(B_2\mid A)\).',
+ ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Guided flow (Scaffold)
+# =======================================================
+Scaffold::Begin();
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A farmer buys seed from **three suppliers** and mixes all the seed together.
+
+- **50%** of the mixed seed came from **Supplier 1** and its germination rate is **90%**.
+- **30%** of the mixed seed came from **Supplier 2** and its germination rate is **80%**.
+- **20%** of the mixed seed came from **Supplier 3** and its germination rate is **60%**.
+
+One seed is chosen at random from the mixture and it **germinates**.
+
+Find the probability that the seed came from **Supplier 2**.
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Bayes Theorem (setup)");
+
+BEGIN_PGML
+Let [`A`] be the event "the seed germinates."
+Let [`B_1`] be the event "the seed came from Supplier 1," [`B_2`] from Supplier 2, and [`B_3`] from Supplier 3.
+
+We are told the seed germinated (event [`A`] happened), and we want [`P(B_2\mid A)`].
+END_PGML
+
+BEGIN_TEXT
+$PAR
+
+\{ image("venn3.png", width => 520) \}
+
+$PAR
+END_TEXT
+
+BEGIN_PGML
+From the definition of conditional probability:
+[`` P(B_2\mid A)=\dfrac{P(A\cap B_2)}{P(A)}. ``]
+
+Also,
+[`` P(A\cap B_2)=P(A\mid B_2)\,P(B_2). ``]
+
+So Bayes Theorem (for this problem) is:
+[`` P(B_2\mid A)=\dfrac{P(A\mid B_2)\,P(B_2)}{P(A)}. ``]
+
+**Checkpoint (When do we use Bayes Theorem?)**
+
+[@ $rb_when_bayes->buttons() @]*
+END_PGML
+ANS($rb_when_bayes->cmp);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Find P(A) using the Law of Total Probability");
+
+BEGIN_PGML
+To use Bayes Theorem we need [`P(A)`] in the denominator.
+
+**Checkpoint (Why do we use the Law of Total Probability here?)**
+
+[@ $rb_need_ltp->buttons() @]*
+END_PGML
+ANS($rb_need_ltp->cmp);
+
+BEGIN_PGML
+Now extract the probabilities from the problem statement.
+
+Germination probability given Supplier 1:
+[`P(A\mid B_1)=`] [__________]{$val_d1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_A_given_B2) < 0.0005 } => "That is the germination rate for Supplier 2. Here we want Supplier 1.",
+ sub { abs($_[0]-$P_A_given_B3) < 0.0005 } => "That is the germination rate for Supplier 3. Here we want Supplier 1.",
+))}
+
+Supplier 1 share:
+[`P(B_1)=`] [__________]{$val_w1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B2) < 0.0005 } => "That is the share for Supplier 2. Here we want Supplier 1.",
+ sub { abs($_[0]-$P_B3) < 0.0005 } => "That is the share for Supplier 3. Here we want Supplier 1.",
+))}
+
+Germination probability given Supplier 2:
+[`P(A\mid B_2)=`] [__________]{$val_d2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_A_given_B1) < 0.0005 } => "That is the germination rate for Supplier 1. Here we want Supplier 2.",
+ sub { abs($_[0]-$P_A_given_B3) < 0.0005 } => "That is the germination rate for Supplier 3. Here we want Supplier 2.",
+))}
+
+Supplier 2 share:
+[`P(B_2)=`] [__________]{$val_w2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B1) < 0.0005 } => "That is the share for Supplier 1. Here we want Supplier 2.",
+ sub { abs($_[0]-$P_B3) < 0.0005 } => "That is the share for Supplier 3. Here we want Supplier 2.",
+))}
+
+Germination probability given Supplier 3:
+[`P(A\mid B_3)=`] [__________]{$val_d3->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_A_given_B1) < 0.0005 } => "That is the germination rate for Supplier 1. Here we want Supplier 3.",
+ sub { abs($_[0]-$P_A_given_B2) < 0.0005 } => "That is the germination rate for Supplier 2. Here we want Supplier 3.",
+))}
+
+Supplier 3 share:
+[`P(B_3)=`] [__________]{$val_w3->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B1) < 0.0005 } => "That is the share for Supplier 1. Here we want Supplier 3.",
+ sub { abs($_[0]-$P_B2) < 0.0005 } => "That is the share for Supplier 2. Here we want Supplier 3.",
+))}
+
+Now use the Law of Total Probability:
+[`` P(A)=P(A\mid B_1)P(B_1)+P(A\mid B_2)P(B_2)+P(A\mid B_3)P(B_3). ``]
+
+Compute [`P(A)`]: [__________]{$val_pA->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_A_given_B1) < 0.0005 || abs($_[0]-$P_A_given_B2) < 0.0005 || abs($_[0]-$P_A_given_B3) < 0.0005 } =>
+ "Careful: those are conditional probabilities for a single supplier. You still need a weighted sum using the supplier shares.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Use Bayes Theorem");
+
+BEGIN_PGML
+Now apply Bayes Theorem:
+[`` P(B_i\mid A)=\dfrac{P(A\mid B_i)\,P(B_i)}{P(A)}. ``]
+
+Compute all three conditional probabilities.
+
+[`P(B_1\mid A)=`] [__________]{$val_B1_givenA->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B1) < 0.001 } => "That is P(B_1). Here we want P(B_1|A), given the seed germinated.",
+ sub { abs($_[0]-$P_A_given_B1) < 0.001 } => "That is P(A|B_1). Use Bayes: multiply by P(B_1) and divide by P(A).",
+))}
+
+[`P(B_2\mid A)=`] [__________]{$val_B2_givenA->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B2) < 0.001 } => "That is P(B_2). Here we want P(B_2|A), given the seed germinated.",
+ sub { abs($_[0]-$P_A_given_B2) < 0.001 } => "That is P(A|B_2). Use Bayes: multiply by P(B_2) and divide by P(A).",
+))}
+
+[`P(B_3\mid A)=`] [__________]{$val_B3_givenA->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B3) < 0.001 } => "That is P(B_3). Here we want P(B_3|A), given the seed germinated.",
+ sub { abs($_[0]-$P_A_given_B3) < 0.001 } => "That is P(A|B_3). Use Bayes: multiply by P(B_3) and divide by P(A).",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Fast check using complement");
+
+BEGIN_PGML
+Because the seed must come from exactly one supplier, the events [`B_1, B_2, B_3`] are mutually exclusive and cover all possibilities.
+
+So (given that the seed germinated),
+[`` P(B_1\mid A)+P(B_2\mid A)+P(B_3\mid A)=1. ``]
+
+A fast way to get [`P(B_3\mid A)`] is:
+[`` P(B_3\mid A)=1-P(B_1\mid A)-P(B_2\mid A). ``]
+
+Compute [`P(B_3\mid A)`] using this fast method (it should match your Bayes result):
+[__________]{$val_B3_givenA->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B3) < 0.001 } => "That is P(B_3). Here we want P(B_3|A). Use 1 - P(B_1|A) - P(B_2|A).",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("An intuitive way of understanding the Bayes Theorem");
+
+BEGIN_PGML
+An intuitive way of understanding Bayes Theorem is to pretend we have **1000 seeds**.
+
+From the problem statement:
+- about [`500`] seeds came from Supplier 1, [`300`] from Supplier 2, and [`200`] from Supplier 3.
+- germination rates are [`90%`], [`80%`], and [`60%`].
+
+Compute the expected number of germinated seeds from each supplier (out of 1000 total).
+
+Germinated from Supplier 1: [__________]{$val_N_A_B1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-$N_A_B2) < 0.5 } => "That looks like Supplier 2's germinated count. Here we want Supplier 1.",
+ sub { abs($_[0]-$N_A_B3) < 0.5 } => "That looks like Supplier 3's germinated count. Here we want Supplier 1.",
+))}
+
+Germinated from Supplier 2: [__________]{$val_N_A_B2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-$N_A_B1) < 0.5 } => "That looks like Supplier 1's germinated count. Here we want Supplier 2.",
+ sub { abs($_[0]-$N_A_B3) < 0.5 } => "That looks like Supplier 3's germinated count. Here we want Supplier 2.",
+))}
+
+Germinated from Supplier 3: [__________]{$val_N_A_B3->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-$N_A_B1) < 0.5 } => "That looks like Supplier 1's germinated count. Here we want Supplier 3.",
+ sub { abs($_[0]-$N_A_B2) < 0.5 } => "That looks like Supplier 2's germinated count. Here we want Supplier 3.",
+))}
+
+Total germinated: [__________]{$val_N_A->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-$N_A_B1) < 0.5 || abs($_[0]-$N_A_B2) < 0.5 || abs($_[0]-$N_A_B3) < 0.5 } =>
+ "That is only one piece. Total germinated is the sum of the three germinated counts.",
+))}
+
+Now, among the germinated seeds, the fraction that came from Supplier 2 is:
+[`` P(B_2\mid A)=\dfrac{\text{germinated from Supplier 2}}{\text{total germinated}}. ``]
+
+Compute [`P(B_2\mid A)`] using the 1000-seed table idea: [__________]{$val_B2_givenA->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B2) < 0.001 } => "That is P(B_2), not P(B_2|A). Use (germinated from Supplier 2)/(total germinated).",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning Bayes Theorem?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{Real(3)->cmp(checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return ($v == int($v) && $v >= 1 && $v <= 5);
+ })->withPostFilter(AnswerHints(
+ sub { $_[0] < 1 || $_[0] > 5 } => "Please enter an integer from 1 to 5.",
+ sub { $_[0] != int($_[0]) } => "Please enter a whole number (integer) from 1 to 5.",
+ ))}
+ END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_GiudedProblem6.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_GiudedProblem6.pg
new file mode 100644
index 0000000000..41ba5c4f0b
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_GiudedProblem6.pg
@@ -0,0 +1,428 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Bayes Theorem (Guided / Scaffolded) — Clinic Positive Test (4 Age Groups)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Conditional Probability)
+## Level(2)
+## KEYWORDS('Bayes theorem','Bayes','law of total probability','total probability','partition','conditional probability','diagnostic test')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# Library Browser (safe detection)
+# ----------------------------------------------------------------
+$inLibraryBrowser = 0;
+if (defined($envir{probContext}) && ref($envir{probContext}) eq 'HASH' && $envir{probContext}{inLibraryBrowser}) {
+ $inLibraryBrowser = 1;
+}
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data
+# =======================================================
+Context("Numeric");
+
+# Partitions (age groups)
+$P_B1 = 0.20; # ages 0-17
+$P_B2 = 0.30; # ages 18-39
+$P_B3 = 0.35; # ages 40-64
+$P_B4 = 0.15; # ages 65+
+
+# Conditional probabilities (positive test rates by group)
+$P_A_given_B1 = 0.03;
+$P_A_given_B2 = 0.05;
+$P_A_given_B3 = 0.08;
+$P_A_given_B4 = 0.12;
+
+# P(A) via Law of Total Probability
+$P_A = ($P_A_given_B1)*($P_B1) + ($P_A_given_B2)*($P_B2) + ($P_A_given_B3)*($P_B3) + ($P_A_given_B4)*($P_B4);
+
+# Bayes posteriors
+$P_B1_given_A = ($P_A_given_B1 * $P_B1) / $P_A;
+$P_B2_given_A = ($P_A_given_B2 * $P_B2) / $P_A;
+$P_B3_given_A = ($P_A_given_B3 * $P_B3) / $P_A;
+$P_B4_given_A = ($P_A_given_B4 * $P_B4) / $P_A;
+
+# 1000-patient intuition numbers (expected counts)
+$N_total = 1000;
+
+$N_B1 = $N_total * $P_B1; # 200
+$N_B2 = $N_total * $P_B2; # 300
+$N_B3 = $N_total * $P_B3; # 350
+$N_B4 = $N_total * $P_B4; # 150
+
+$N_A_B1 = $N_B1 * $P_A_given_B1; # 6
+$N_A_B2 = $N_B2 * $P_A_given_B2; # 15
+$N_A_B3 = $N_B3 * $P_A_given_B3; # 28
+$N_A_B4 = $N_B4 * $P_A_given_B4; # 18
+$N_A = $N_A_B1 + $N_A_B2 + $N_A_B3 + $N_A_B4;
+
+# Store values as MathObjects
+$val_pA = Real($P_A);
+
+$val_d1 = Real($P_A_given_B1); $val_w1 = Real($P_B1);
+$val_d2 = Real($P_A_given_B2); $val_w2 = Real($P_B2);
+$val_d3 = Real($P_A_given_B3); $val_w3 = Real($P_B3);
+$val_d4 = Real($P_A_given_B4); $val_w4 = Real($P_B4);
+
+$val_B1_givenA = Real($P_B1_given_A);
+$val_B2_givenA = Real($P_B2_given_A);
+$val_B3_givenA = Real($P_B3_given_A);
+$val_B4_givenA = Real($P_B4_given_A);
+
+$val_N_A_B1 = Real($N_A_B1);
+$val_N_A_B2 = Real($N_A_B2);
+$val_N_A_B3 = Real($N_A_B3);
+$val_N_A_B4 = Real($N_A_B4);
+$val_N_A = Real($N_A);
+
+# =======================================================
+# Concept checkpoints (MC)
+# =======================================================
+$rb_when_bayes = RadioButtons(
+ [
+ 'When we know probabilities like \(P(A\mid B_i)\) and want a probability like \(P(B_i\mid A)\) (reverse the conditioning), using cases \(B_1,B_2,\ldots\) that cover all possibilities.',
+ 'When two events are independent.',
+ 'When we want to add probabilities of disjoint events (no conditioning).',
+ 'When we already know \(P(B_i\mid A)\) and want \(P(A\mid B_i)\).',
+ 'When we want to compute \(P(A\cap B)\) by adding \(P(A)\) and \(P(B)\).',
+ ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+$rb_need_ltp = RadioButtons(
+ [
+ 'Because Bayes Theorem needs \(P(A)\) in the denominator, and we compute \(P(A)\) by combining the cases using the Law of Total Probability.',
+ 'Because Bayes Theorem only works if the events are independent.',
+ 'Because \(P(A)=P(B_1)+P(B_2)+P(B_3)+P(B_4)\) always.',
+ 'Because \(P(A\mid B_1)=P(A\mid B_2)=P(A\mid B_3)=P(A\mid B_4)\) must be true first.',
+ 'Because we must always compute \(P(B_1\mid A)\) before the others.',
+ ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Guided flow (Scaffold)
+# =======================================================
+Scaffold::Begin();
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A clinic serves patients from **four age groups**:
+
+- **20%** are ages **0-17**
+- **30%** are ages **18-39**
+- **35%** are ages **40-64**
+- **15%** are ages **65+**
+
+The probability that a patient tests **positive** for a certain disease depends on the age group:
+
+- **3%** for ages **0-17**
+- **5%** for ages **18-39**
+- **8%** for ages **40-64**
+- **12%** for ages **65+**
+
+From those whose test result is **positive**, a patient is selected at random.
+
+Find the probability that the patient is in the **65+** age group.
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Bayes Theorem (general setup)");
+
+BEGIN_PGML
+Let [`A`] be the event "the test result is positive."
+
+For the general case, suppose the sample space is partitioned into
+[`B_1, B_2, B_3, \ldots, B_n`].
+
+In this problem we have [`n=4`] groups:
+[`B_1`]=ages 0-17, [`B_2`]=ages 18-39, [`B_3`]=ages 40-64, [`B_4`]=ages 65+.
+
+We are told [`A`] happened (positive test), and we want [`P(B_4\mid A)`].
+END_PGML
+
+BEGIN_TEXT
+$PAR
+
+\{ image("vennn.png", width => 520) \}
+
+$PAR
+END_TEXT
+
+BEGIN_PGML
+From the definition of conditional probability:
+[`` P(B_k\mid A)=\dfrac{P(A\cap B_k)}{P(A)}. ``]
+
+Also,
+[`` P(A\cap B_k)=P(A\mid B_k)\,P(B_k). ``]
+
+So Bayes Theorem (general case) can be written as:
+[`` P(B_k\mid A)=\dfrac{P(A\mid B_k)\,P(B_k)}{P(A)}. ``]
+
+**Checkpoint (When do we use Bayes Theorem?)**
+
+[@ $rb_when_bayes->buttons() @]*
+END_PGML
+ANS($rb_when_bayes->cmp);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Find P(A) using the Law of Total Probability");
+
+BEGIN_PGML
+To use Bayes Theorem we need [`P(A)`] in the denominator.
+
+**Checkpoint (Why do we use the Law of Total Probability here?)**
+
+[@ $rb_need_ltp->buttons() @]*
+END_PGML
+ANS($rb_need_ltp->cmp);
+
+BEGIN_PGML
+Now extract the needed probabilities from the problem statement.
+
+[`P(A\mid B_1)=`] [__________]{$val_d1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_A_given_B2) < 0.0005 } => "That rate is for ages 18-39. Here we want ages 0-17.",
+ sub { abs($_[0]-$P_A_given_B3) < 0.0005 } => "That rate is for ages 40-64. Here we want ages 0-17.",
+ sub { abs($_[0]-$P_A_given_B4) < 0.0005 } => "That rate is for ages 65+. Here we want ages 0-17.",
+))}
+
+[`P(B_1)=`] [__________]{$val_w1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B2) < 0.0005 } => "That fraction is for ages 18-39. Here we want ages 0-17.",
+ sub { abs($_[0]-$P_B3) < 0.0005 } => "That fraction is for ages 40-64. Here we want ages 0-17.",
+ sub { abs($_[0]-$P_B4) < 0.0005 } => "That fraction is for ages 65+. Here we want ages 0-17.",
+))}
+
+[`P(A\mid B_2)=`] [__________]{$val_d2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_A_given_B1) < 0.0005 } => "That rate is for ages 0-17. Here we want ages 18-39.",
+ sub { abs($_[0]-$P_A_given_B3) < 0.0005 } => "That rate is for ages 40-64. Here we want ages 18-39.",
+ sub { abs($_[0]-$P_A_given_B4) < 0.0005 } => "That rate is for ages 65+. Here we want ages 18-39.",
+))}
+
+[`P(B_2)=`] [__________]{$val_w2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B1) < 0.0005 } => "That fraction is for ages 0-17. Here we want ages 18-39.",
+ sub { abs($_[0]-$P_B3) < 0.0005 } => "That fraction is for ages 40-64. Here we want ages 18-39.",
+ sub { abs($_[0]-$P_B4) < 0.0005 } => "That fraction is for ages 65+. Here we want ages 18-39.",
+))}
+
+[`P(A\mid B_3)=`] [__________]{$val_d3->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_A_given_B1) < 0.0005 } => "That rate is for ages 0-17. Here we want ages 40-64.",
+ sub { abs($_[0]-$P_A_given_B2) < 0.0005 } => "That rate is for ages 18-39. Here we want ages 40-64.",
+ sub { abs($_[0]-$P_A_given_B4) < 0.0005 } => "That rate is for ages 65+. Here we want ages 40-64.",
+))}
+
+[`P(B_3)=`] [__________]{$val_w3->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B1) < 0.0005 } => "That fraction is for ages 0-17. Here we want ages 40-64.",
+ sub { abs($_[0]-$P_B2) < 0.0005 } => "That fraction is for ages 18-39. Here we want ages 40-64.",
+ sub { abs($_[0]-$P_B4) < 0.0005 } => "That fraction is for ages 65+. Here we want ages 40-64.",
+))}
+
+[`P(A\mid B_4)=`] [__________]{$val_d4->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_A_given_B1) < 0.0005 } => "That rate is for ages 0-17. Here we want ages 65+.",
+ sub { abs($_[0]-$P_A_given_B2) < 0.0005 } => "That rate is for ages 18-39. Here we want ages 65+.",
+ sub { abs($_[0]-$P_A_given_B3) < 0.0005 } => "That rate is for ages 40-64. Here we want ages 65+.",
+))}
+
+[`P(B_4)=`] [__________]{$val_w4->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B1) < 0.0005 } => "That fraction is for ages 0-17. Here we want ages 65+.",
+ sub { abs($_[0]-$P_B2) < 0.0005 } => "That fraction is for ages 18-39. Here we want ages 65+.",
+ sub { abs($_[0]-$P_B3) < 0.0005 } => "That fraction is for ages 40-64. Here we want ages 65+.",
+))}
+
+Now use the Law of Total Probability:
+[`` P(A)=\sum_{i=1}^{4} P(A\mid B_i)\,P(B_i). ``]
+
+Compute [`P(A)`]: [__________]{$val_pA->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_A_given_B1) < 0.0005 || abs($_[0]-$P_A_given_B2) < 0.0005 || abs($_[0]-$P_A_given_B3) < 0.0005 || abs($_[0]-$P_A_given_B4) < 0.0005 } =>
+ "Careful: those are conditional probabilities for one group. P(A) is a weighted sum using the group proportions.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Use Bayes Theorem");
+
+BEGIN_PGML
+Now apply Bayes Theorem:
+[`` P(B_i\mid A)=\dfrac{P(A\mid B_i)\,P(B_i)}{P(A)}. ``]
+
+Compute the four conditional probabilities.
+
+[`P(B_1\mid A)=`] [__________]{$val_B1_givenA->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B1) < 0.001 } => "That is P(B_1). Here we want P(B_1|A). Use Bayes and divide by P(A).",
+))}
+
+[`P(B_2\mid A)=`] [__________]{$val_B2_givenA->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B2) < 0.001 } => "That is P(B_2). Here we want P(B_2|A). Use Bayes and divide by P(A).",
+))}
+
+[`P(B_3\mid A)=`] [__________]{$val_B3_givenA->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B3) < 0.001 } => "That is P(B_3). Here we want P(B_3|A). Use Bayes and divide by P(A).",
+))}
+
+[`P(B_4\mid A)=`] [__________]{$val_B4_givenA->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B4) < 0.001 } => "That is P(B_4). Here we want P(B_4|A). Use Bayes and divide by P(A).",
+ sub { abs($_[0]-$P_A_given_B4) < 0.001 } => "That is P(A|B_4). Here we want P(B_4|A). Use Bayes: multiply by P(B_4), then divide by P(A).",
+))}
+
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Fast check using the sum to 1");
+
+BEGIN_PGML
+Because the patient must be in exactly one age group, the events [`B_1,B_2,B_3,B_4`] cover all possibilities and do not overlap.
+
+So (given that the test is positive),
+[`` P(B_1\mid A)+P(B_2\mid A)+P(B_3\mid A)+P(B_4\mid A)=1. ``]
+
+A fast check for the 65+ group is:
+[`` P(B_4\mid A)=1-P(B_1\mid A)-P(B_2\mid A)-P(B_3\mid A). ``]
+
+Compute [`P(B_4\mid A)`] using this fast method (it should match your Bayes result):
+[__________]{$val_B4_givenA->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B4) < 0.001 } => "That is P(B_4). Here we want P(B_4|A). Use 1 minus the other three conditional probabilities.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("An intuitive way of understanding Bayes Theorem");
+
+BEGIN_PGML
+An intuitive way of understanding Bayes Theorem is to pretend we have **1000 patients**.
+
+From the problem statement:
+- about [`200`] are ages 0-17, [`300`] are ages 18-39, [`350`] are ages 40-64, and [`150`] are ages 65+.
+- positive-test rates are [`3%`], [`5%`], [`8%`], and [`12%`].
+
+Compute the expected number of positive tests from each age group (out of 1000 total).
+
+Positive tests from ages 0-17: [__________]{$val_N_A_B1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-$N_A_B2) < 0.5 } => "That looks like the 18-39 count. Here we want 0-17.",
+ sub { abs($_[0]-$N_A_B3) < 0.5 } => "That looks like the 40-64 count. Here we want 0-17.",
+ sub { abs($_[0]-$N_A_B4) < 0.5 } => "That looks like the 65+ count. Here we want 0-17.",
+))}
+
+Positive tests from ages 18-39: [__________]{$val_N_A_B2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-$N_A_B1) < 0.5 } => "That looks like the 0-17 count. Here we want 18-39.",
+ sub { abs($_[0]-$N_A_B3) < 0.5 } => "That looks like the 40-64 count. Here we want 18-39.",
+ sub { abs($_[0]-$N_A_B4) < 0.5 } => "That looks like the 65+ count. Here we want 18-39.",
+))}
+
+Positive tests from ages 40-64: [__________]{$val_N_A_B3->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-$N_A_B1) < 0.5 } => "That looks like the 0-17 count. Here we want 40-64.",
+ sub { abs($_[0]-$N_A_B2) < 0.5 } => "That looks like the 18-39 count. Here we want 40-64.",
+ sub { abs($_[0]-$N_A_B4) < 0.5 } => "That looks like the 65+ count. Here we want 40-64.",
+))}
+
+Positive tests from ages 65+: [__________]{$val_N_A_B4->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-$N_A_B1) < 0.5 } => "That looks like the 0-17 count. Here we want 65+.",
+ sub { abs($_[0]-$N_A_B2) < 0.5 } => "That looks like the 18-39 count. Here we want 65+.",
+ sub { abs($_[0]-$N_A_B3) < 0.5 } => "That looks like the 40-64 count. Here we want 65+.",
+))}
+
+Total positive tests: [__________]{$val_N_A->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-$N_A_B1) < 0.5 || abs($_[0]-$N_A_B2) < 0.5 || abs($_[0]-$N_A_B3) < 0.5 || abs($_[0]-$N_A_B4) < 0.5 } =>
+ "That is only one piece. Total positives is the sum of the four counts.",
+))}
+
+Now, among the positive tests, the fraction that came from the 65+ group is:
+[`` P(B_4\mid A)=\dfrac{\text{positive tests from 65+}}{\text{total positive tests}}. ``]
+
+Compute [`P(B_4\mid A)`] using the 1000-patient table idea: [__________]{$val_B4_givenA->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_B4) < 0.001 } => "That is P(B_4), not P(B_4|A). Use (positive from 65+)/(total positive).",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning Bayes Theorem?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{Real(3)->cmp(checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return ($v == int($v) && $v >= 1 && $v <= 5);
+ })->withPostFilter(AnswerHints(
+ sub { $_[0] < 1 || $_[0] > 5 } => "Please enter an integer from 1 to 5.",
+ sub { $_[0] != int($_[0]) } => "Please enter a whole number (integer) from 1 to 5.",
+ ))}
+ END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_GiudedProblem7.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_GiudedProblem7.pg
new file mode 100644
index 0000000000..d58a787e34
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_GiudedProblem7.pg
@@ -0,0 +1,247 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Bayes Theorem (Guided / Scaffolded) — Medical Diagnosis
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Conditional Probability)
+## Level(2)
+## KEYWORDS('Bayes theorem','Bayes','law of total probability','total probability','conditional probability','medical test','sensitivity','specificity')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# Library Browser (safe detection)
+# ----------------------------------------------------------------
+$inLibraryBrowser = 0;
+if (defined($envir{probContext}) && ref($envir{probContext}) eq 'HASH' && $envir{probContext}{inLibraryBrowser}) {
+ $inLibraryBrowser = 1;
+}
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data
+# =======================================================
+Context("Numeric");
+
+$P_D = 0.01; # prevalence
+$P_notD = 1 - $P_D;
+
+$P_pos_given_D = 0.90; # sensitivity
+$P_pos_given_notD = 0.02; # false positive rate
+
+$P_neg_given_D = 1 - $P_pos_given_D; # false negative rate
+$P_neg_given_notD = 1 - $P_pos_given_notD; # specificity
+
+# Law of Total Probability for overall positive rate
+$P_pos = ($P_pos_given_D)*($P_D) + ($P_pos_given_notD)*($P_notD);
+
+# Bayes posterior after one positive
+$P_D_given_pos = ($P_pos_given_D * $P_D) / $P_pos;
+
+# Two independent clinics (two positives)
+$P_pospos_given_D = ($P_pos_given_D)*($P_pos_given_D);
+$P_pospos_given_notD = ($P_pos_given_notD)*($P_pos_given_notD);
+$P_pospos = ($P_pospos_given_D)*($P_D) + ($P_pospos_given_notD)*($P_notD);
+$P_D_given_pospos = ($P_pospos_given_D * $P_D) / $P_pospos;
+
+# Store values as MathObjects
+$val_PD = Real($P_D);
+$val_PnotD = Real($P_notD);
+
+$val_sens = Real($P_pos_given_D);
+$val_fnr = Real($P_neg_given_D);
+$val_spec = Real($P_neg_given_notD);
+$val_fpr = Real($P_pos_given_notD);
+
+$val_Ppos = Real($P_pos);
+$val_P_D_given_p = Real($P_D_given_pos);
+
+# For the MC (two clinics)
+$val_P_D_given_pp = Real($P_D_given_pospos);
+
+# =======================================================
+# Concept checkpoint (MC): two independent clinics
+# =======================================================
+$rb_two_clinics = RadioButtons(
+ [
+ "about 0.08",
+ "about 0.95",
+ "about 0.31",
+ "about 0.02",
+ "about 0.50",
+ ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Guided flow (Scaffold)
+# =======================================================
+Scaffold::Begin();
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+Medical Diagnosis: Suppose a certain medical test for a particular disease is known to detect the disease correctly **90%** of the time when a person actually has it. The disease is rare, occurring in only **1%** of the population. We also know that the test has a false positive rate of **2%**. If a person tests positive for the disease, what is the probability that they actually have it?
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Key rates: Sensitivity, false negative, specificity, false positive");
+BEGIN_PGML
+Now we will introduce notation.
+
+Let [`D`] mean "the person has the disease" and [`D^c`] mean "the person does not have the disease."
+Let [`+`] mean "test is positive" and [`-`] mean "test is negative."
+
+Here are the key definitions:
+
+- **Sensitivity (true positive rate):** [`P(+\mid D)`]
+- **False negative rate:** [`P(-\mid D)`]
+- **Specificity (true negative rate):** [`P(-\mid D^c)`]
+- **False positive rate:** [`P(+\mid D^c)`]
+
+**Identify each value from the problem data.**
+
+Sensitivity = [`P(+\mid D)=`] [__________]{$val_sens->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_neg_given_D) < 0.0005 } => "That is P(-|D), the false negative rate. Sensitivity is P(+|D).",
+))}
+
+False negative rate = [`P(-\mid D)=`] [__________]{$val_fnr->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_pos_given_D) < 0.0005 } => "That is P(+|D), the sensitivity. False negative rate is 1 - sensitivity.",
+))}
+
+Specificity = [`P(-\mid D^c)=`] [__________]{$val_spec->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_pos_given_notD) < 0.0005 } => "That is P(+|D^c), the false positive rate. Specificity is P(-|D^c).",
+))}
+
+False positive rate = [`P(+\mid D^c)=`] [__________]{$val_fpr->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_neg_given_notD) < 0.0005 } => "That is P(-|D^c), the specificity. False positive rate is P(+|D^c).",
+))}
+
+Also identify the base rates:
+
+[`P(D)=`] [__________]{$val_PD->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_notD) < 0.0005 } => "That is P(D^c). Here we want P(D).",
+))}
+
+[`P(D^c)=`] [__________]{$val_PnotD->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_D) < 0.0005 } => "That is P(D). Here we want P(D^c)=1-P(D).",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Find the overall positive probability using the Law of Total Probability");
+BEGIN_PGML
+To use Bayes Theorem we need the overall probability of a positive test, [`P(+)`].
+
+A positive test can happen in two non-overlapping cases:
+- the person has the disease, or
+- the person does not have the disease
+
+So we use the Law of Total Probability:
+[`` P(+)=P(+\mid D)P(D)+P(+\mid D^c)P(D^c). ``]
+
+Compute [`P(+)`]: [__________]{$val_Ppos->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "This is greater than 1, so it cannot be a probability. Make sure you are using decimals like 0.02, not 2%.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_pos_given_D*$P_D) < 0.0005 } => "That is only the disease piece P(+|D)P(D). You must also add the no-disease piece.",
+ sub { abs($_[0]-$P_pos_given_notD*$P_notD) < 0.0005 } => "That is only the no-disease piece P(+|D^c)P(D^c). You must also add the disease piece.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Bayes Theorem (compute the answer)");
+BEGIN_PGML
+We want the probability the person actually has the disease **given** that the test is positive.
+
+Bayes Theorem:
+[`` P(D\mid +)=\dfrac{P(+\mid D)\,P(D)}{P(+)}. ``]
+
+Here [`P(+)`] is the value you computed in the previous step.
+
+Compute [`P(D\mid +)`]: [__________]{$val_P_D_given_p->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_D) < 0.0005 } => "That is the base rate P(D)=0.01. After a positive test, the probability should be larger than 0.01.",
+ sub { abs($_[0]-$P_pos_given_D) < 0.0005 } => "That is P(+|D), the sensitivity. Here we want P(D|+). Use Bayes: divide by P(+).",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Two independent clinics (prediction question)");
+BEGIN_PGML
+Now suppose the person takes the **same type of test at two independent clinics**, and both tests come back **positive**.
+
+Assume the test results are independent given whether the person has the disease or not.
+
+**Guess:** What would the probability be that the person actually has the disease now?
+
+[@ $rb_two_clinics->buttons() @]*
+END_PGML
+ANS($rb_two_clinics->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] ne "" } => "If you compute it, you would use Bayes again with P(++|D)=(0.90)(0.90) and P(++|D^c)=(0.02)(0.02).",
+)));
+Section::End();
+
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning Bayes Theorem?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{Real(3)->cmp(checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return ($v == int($v) && $v >= 1 && $v <= 5);
+ })->withPostFilter(AnswerHints(
+ sub { $_[0] < 1 || $_[0] > 5 } => "Please enter an integer from 1 to 5.",
+ sub { $_[0] != int($v) } => "Please enter a whole number (integer) from 1 to 5.",
+ ))}
+ END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_GiudedProblem8.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_GiudedProblem8.pg
new file mode 100644
index 0000000000..af1042fc29
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_GiudedProblem8.pg
@@ -0,0 +1,253 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Bayes Theorem (Guided / Scaffolded) — Breast Cancer (Canada)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Conditional Probability)
+## Level(2)
+## KEYWORDS('Bayes theorem','Bayes','law of total probability','total probability','conditional probability','medical test','sensitivity','specificity','breast cancer')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# Library Browser (safe detection)
+# ----------------------------------------------------------------
+$inLibraryBrowser = 0;
+if (defined($envir{probContext}) && ref($envir{probContext}) eq 'HASH' && $envir{probContext}{inLibraryBrowser}) {
+ $inLibraryBrowser = 1;
+}
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data
+# =======================================================
+Context("Numeric");
+
+# Prevalence (0.35% per year)
+$P_C = 0.0035; # P(C)
+$P_notC = 1 - $P_C; # P(C^c)
+
+# Given data:
+# false negative = 11% among those with cancer => P(-|C) = 0.11
+# false positive = 7% among those without cancer => P(+|C^c) = 0.07
+$P_neg_given_C = 0.11; # false negative rate
+$P_pos_given_C = 1 - $P_neg_given_C; # sensitivity
+
+$P_pos_given_notC = 0.07; # false positive rate
+$P_neg_given_notC = 1 - $P_pos_given_notC; # specificity
+
+# Overall positive rate via LTP
+$P_pos = ($P_pos_given_C)*($P_C) + ($P_pos_given_notC)*($P_notC);
+
+# Bayes posterior after one positive
+$P_C_given_pos = ($P_pos_given_C * $P_C) / $P_pos;
+
+# Two independent clinics (two positives)
+$P_pospos_given_C = ($P_pos_given_C)*($P_pos_given_C);
+$P_pospos_given_notC = ($P_pos_given_notC)*($P_pos_given_notC);
+$P_pospos = ($P_pospos_given_C)*($P_C) + ($P_pospos_given_notC)*($P_notC);
+$P_C_given_pospos = ($P_pospos_given_C * $P_C) / $P_pospos;
+
+# Store values as MathObjects
+$val_PC = Real($P_C);
+$val_PnotC = Real($P_notC);
+
+$val_sens = Real($P_pos_given_C);
+$val_fnr = Real($P_neg_given_C);
+$val_spec = Real($P_neg_given_notC);
+$val_fpr = Real($P_pos_given_notC);
+
+$val_Ppos = Real($P_pos);
+$val_C_given_pos = Real($P_C_given_pos);
+
+$val_C_given_pp = Real($P_C_given_pospos);
+
+# =======================================================
+# Concept checkpoint (MC): two independent clinics
+# =======================================================
+$rb_two_clinics = RadioButtons(
+ [
+ "about 0.07",
+ "about 0.89",
+ "about 0.50",
+ "about 0.36",
+ "about 0.04",
+ ],
+ 3,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Guided flow (Scaffold)
+# =======================================================
+Scaffold::Begin();
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+Breast Cancer in Canada: In Canada, about **0.35%** of women over 40 will develop breast cancer in any given year. A common screening test for cancer is the mammogram, but this test is not perfect. In about **11%** of patients with breast cancer, the test gives a false negative: it indicates a woman does not have breast cancer when she does have breast cancer. Similarly, the test gives a false positive in **7%** of patients who do not have breast cancer: it indicates these patients have breast cancer when they actually do not. If we tested a random woman over 40 for breast cancer using a mammogram and the test came back
+positive, what is the probability that the patient actually has breast cancer?
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Key rates: Sensitivity, false negative, specificity, false positive");
+BEGIN_PGML
+Now we will introduce notation.
+
+Let [`C`] mean "the woman has breast cancer" and [`C^c`] mean "the woman does not have breast cancer."
+Let [`+`] mean "mammogram is positive" and [`-`] mean "mammogram is negative."
+
+Definitions:
+
+- **Sensitivity (true positive rate):** [`P(+\mid C)`]
+- **False negative rate:** [`P(-\mid C)`]
+- **Specificity (true negative rate):** [`P(-\mid C^c)`]
+- **False positive rate:** [`P(+\mid C^c)`]
+
+
+**Identify each value from the problem data (enter decimals).**
+
+Sensitivity = [`P(+\mid C)=`] [__________]{$val_sens->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "Use a decimal (for example 0.07), not a percent (like 7).",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_neg_given_C) < 0.0005 } => "That is P(-|C), the false negative rate. Sensitivity is P(+|C)=1-P(-|C).",
+))}
+
+False negative rate = [`P(-\mid C)=`] [__________]{$val_fnr->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "Use a decimal (for example 0.11), not a percent (like 11).",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_pos_given_C) < 0.0005 } => "That is P(+|C), the sensitivity. False negative rate is P(-|C).",
+))}
+
+Specificity = [`P(-\mid C^c)=`] [__________]{$val_spec->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "Use a decimal (for example 0.93), not a percent (like 93).",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_pos_given_notC) < 0.0005 } => "That is P(+|C^c), the false positive rate. Specificity is 1 - false positive rate.",
+))}
+
+False positive rate = [`P(+\mid C^c)=`] [__________]{$val_fpr->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "Use a decimal (for example 0.07), not a percent (like 7).",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_neg_given_notC) < 0.0005 } => "That is P(-|C^c), the specificity. False positive rate is P(+|C^c).",
+))}
+
+Base rates:
+
+[`P(C)=`] [__________]{$val_PC->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "Use a decimal (for example 0.0035), not a percent (like 0.35).",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_notC) < 0.0005 } => "That is P(C^c). Here we want P(C).",
+))}
+
+[`P(C^c)=`] [__________]{$val_PnotC->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "Use a decimal between 0 and 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_C) < 0.0005 } => "That is P(C). Here we want P(C^c)=1-P(C).",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Find the overall positive probability using the Law of Total Probability");
+BEGIN_PGML
+To use Bayes Theorem we need the overall probability of a positive test, [`P(+)`].
+
+A positive test can happen in two non-overlapping cases:
+- the woman has breast cancer
+- the woman does not have breast cancer
+
+So we use the Law of Total Probability:
+[`` P(+)=P(+\mid C)P(C)+P(+\mid C^c)P(C^c). ``]
+
+Compute [`P(+)`]: [__________]{$val_Ppos->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "This is greater than 1, so it cannot be a probability. Make sure you are using decimals like 0.07, not 7%.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_pos_given_C*$P_C) < 0.0005 } => "That is only the cancer piece P(+|C)P(C). You must also add the no-cancer piece.",
+ sub { abs($_[0]-$P_pos_given_notC*$P_notC) < 0.0005 } => "That is only the no-cancer piece P(+|C^c)P(C^c). You must also add the cancer piece.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Bayes Theorem (compute the answer)");
+BEGIN_PGML
+We want the probability the woman actually has breast cancer **given** that the test is positive.
+
+Bayes Theorem:
+[`` P(C\mid +)=\dfrac{P(+\mid C)\,P(C)}{P(+)}. ``]
+
+Here [`P(+)`] is the value you computed in the previous step.
+
+Compute [`P(C\mid +)`]: [__________]{$val_C_given_pos->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_C) < 0.0005 } => "That is the base rate P(C)=0.0035. After a positive test, the probability should be larger than 0.0035.",
+ sub { abs($_[0]-$P_pos_given_C) < 0.0005 } => "That is P(+|C), the sensitivity. Here we want P(C|+). Use Bayes: divide by P(+).",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Two independent clinics (prediction question)");
+BEGIN_PGML
+Now suppose the woman takes the **same type of mammogram at two independent clinics**, and both tests come back **positive**.
+
+Assume the test results are independent given whether she has breast cancer or not.
+
+**Guess:** What would the probability be that she actually has breast cancer now?
+
+[@ $rb_two_clinics->buttons() @]*
+END_PGML
+ANS($rb_two_clinics->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] ne "" } => "If you compute it, you would use Bayes again with P(++|C)=(P(+|C))(P(+|C)) and P(++|C^c)=(P(+|C^c))(P(+|C^c)).",
+)));
+Section::End();
+
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning Bayes Theorem?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{Real(3)->cmp(checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return ($v == int($v) && $v >= 1 && $v <= 5);
+ })->withPostFilter(AnswerHints(
+ sub { $_[0] < 1 || $_[0] > 5 } => "Please enter an integer from 1 to 5.",
+ sub { $_[0] != int($_[0]) } => "Please enter a whole number (integer) from 1 to 5.",
+ ))}
+ END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_MontyHallParadox.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_MontyHallParadox.pg
new file mode 100644
index 0000000000..b499f19793
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/BayesTheorem_LawOfTotalProbability_MontyHallParadox.pg
@@ -0,0 +1,292 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Monty Hall Paradox (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Conditional Probability)
+## Level(2)
+## KEYWORDS('Monty Hall','Monty Hall paradox','conditional probability','law of total probability','game show')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data (Numeric)
+# =======================================================
+Context("Numeric");
+
+$P_A = 1/3; # A: car is behind initial choice
+$P_Ac = 1 - $P_A;
+
+$P_W1_given_A = 1; # stay and win, given A
+$P_W1_given_Ac = 0; # stay and win, given not A
+
+$P_W2_given_A = 0; # switch and win, given A
+$P_W2_given_Ac = 1; # switch and win, given not A
+
+$P_W1 = ($P_W1_given_A)*($P_A) + ($P_W1_given_Ac)*($P_Ac);
+$P_W2 = ($P_W2_given_A)*($P_A) + ($P_W2_given_Ac)*($P_Ac);
+
+$val_PA = Real($P_A);
+$val_PAc = Real($P_Ac);
+
+$val_W1A = Real($P_W1_given_A);
+$val_W1Ac = Real($P_W1_given_Ac);
+$val_PW1 = Real($P_W1);
+
+$val_W2A = Real($P_W2_given_A);
+$val_W2Ac = Real($P_W2_given_Ac);
+$val_PW2 = Real($P_W2);
+
+# =======================================================
+# Step 2 (Prediction) — correct answer is YES
+# =======================================================
+$rb_pred_switch = RadioButtons(
+ [
+ "Yes. Switch to Door 2.",
+ "No. Stay with Door 1.",
+ ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Decision checkpoint (graded) — correct is SWITCH
+# =======================================================
+$rb_best = RadioButtons(
+ [
+ "Stay",
+ "Switch",
+ ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Challenge MC (host unaware) — correct is option C
+# =======================================================
+$rb_challenge = RadioButtons(
+ [
+ "Always switch; the chance becomes 1 because Monty opened a goat door.",
+ "Never switch; staying becomes 2/3 automatically.",
+ 'It makes no difference; in this situation both choices give probability \(1/2\).',
+ "Switching is worse; it becomes 1/3.",
+ "Ask the goat which door has the car.",
+ ],
+ 2,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Guided flow (Scaffold)
+# =======================================================
+Scaffold::Begin();
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+There are three doors: Door 1, Door 2, and Door 3.
+
+Behind one door is a car. Behind the other two doors are goats.
+
+You pick one door. The host (Monty) knows where the car is. He then opens one of the other two doors and always reveals a goat. After that, Monty gives you the option to stay with your original door or switch to the only other unopened door.
+
+Your goal is to maximize your chance of winning the car.
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Prediction");
+
+BEGIN_PGML
+Imagine you are the contestant and you initially pick Door 1. Monty opens Door 3 and reveals a goat. He then allows you to switch to Door 2, if you like.
+END_PGML
+
+BEGIN_TEXT
+$PAR
+
+\{ image("MontyHall.png", width => 700) \}
+
+$PAR
+END_TEXT
+
+BEGIN_PGML
+Given the goal is maximizing the chance of winning the car, should you switch to Door 2?
+
+Before answering consider these facts:
+
+1) The host knows where the car is.
+
+2) The host always opens a door the contestant did not pick.
+
+3) The host always reveals a goat.
+
+4) The host always offers the option to switch
+
+[@ $rb_pred_switch->buttons() @]*
+END_PGML
+ANS($rb_pred_switch->cmp);
+
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Total Probability Analysis: Stay");
+BEGIN_PGML
+Now we analyze the probability of winning if you do NOT switch.
+
+Let [`A`] = "the car is behind your initial choice."
+Let [`W_1`] = "you win the car using the strategy of staying."
+
+We will use the Law of Total Probability:
+[`` P(W_1)=P(W_1\mid A)P(A) + P(W_1\mid A^c)P(A^c). ``]
+
+Fill the pieces.
+
+[`P(A)=`] [__________]{$val_PA->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-2/3) < 0.0008 } => "Careful: P(A) is the probability your FIRST pick is correct (before Monty opens a door).",
+))}
+
+[`P(A^c)=`] [__________]{$val_PAc->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-$P_A) < 0.0008 } => "That looks like P(A). Here we want P(A^c)=1-P(A).",
+))}
+
+If you stay:
+- When [`A`] happens, you win for sure.
+- When [`A^c`] happens, you lose for sure.
+
+[`P(W_1\mid A)=`] [__________]{$val_W1A->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]) < 0.0008 } => "If the car is already behind your chosen door, staying wins.",
+))}
+
+[`P(W_1\mid A^c)=`] [__________]{$val_W1Ac->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-1) < 0.0008 } => "If the car is NOT behind your chosen door, staying cannot win.",
+))}
+
+Now compute:
+
+[`P(W_1)=`] [__________]{$val_PW1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { $_[0] > 0.5 } => "This is too large for staying. Re-check your conditionals.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Total Probability Analysis: Switch");
+BEGIN_PGML
+Now we analyze the probability of winning if you switch.
+
+Let [`W_2`] = "you win the car using the strategy of switching."
+
+Again:
+[`` P(W_2)=P(W_2\mid A)P(A) + P(W_2\mid A^c)P(A^c). ``]
+
+If you switch:
+- When [`A`] happens, switching makes you lose.
+- When [`A^c`] happens, switching makes you win.
+
+[`P(W_2\mid A)=`] [__________]{$val_W2A->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]-1) < 0.0008 } => "If your first pick is correct, switching throws away the correct door.",
+))}
+
+[`P(W_2\mid A^c)=`] [__________]{$val_W2Ac->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { abs($_[0]) < 0.0008 } => "If your first pick is wrong, switching moves you to the only remaining possible car door.",
+))}
+
+Now compute:
+
+[`P(W_2)=`] [__________]{$val_PW2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "A probability cannot be greater than 1.",
+ sub { $_[0] < 0 } => "A probability cannot be negative.",
+ sub { $_[0] < 0.5 } => "This is too small for switching. Re-check your conditionals.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Decision");
+BEGIN_PGML
+Based on your computed values for [`P(W_1)`] and [`P(W_2)`], which strategy maximizes your chance of winning the car?
+
+[@ $rb_best->buttons() @]*
+END_PGML
+ANS($rb_best->cmp);
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Challenge: host unaware (prediction)");
+BEGIN_PGML
+Challenge: What if the host is unaware of what is behind each door?
+He randomly opens one of the two doors you did not pick. Suppose the door he opens shows a goat.
+
+Under these circumstances, is switching:
+- better,
+- worse, or
+- does it make no difference?
+
+[@ $rb_challenge->buttons() @]*
+END_PGML
+ANS($rb_challenge->cmp);
+Section::End();
+
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning the Monty Hall Paradox?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{Real(3)->cmp(checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return ($v == int($v) && $v >= 1 && $v <= 5);
+ })->withPostFilter(AnswerHints(
+ sub { $_[0] < 1 || $_[0] > 5 } => "Please enter an integer from 1 to 5.",
+ sub { $_[0] != int($_[0]) } => "Please enter a whole number (integer) from 1 to 5.",
+ ))}
+ END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/MontyHall.png b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/MontyHall.png
new file mode 100644
index 0000000000..8b8b9e695e
Binary files /dev/null and b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/MontyHall.png differ
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/venn2.png b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/venn2.png
new file mode 100644
index 0000000000..c44808a779
Binary files /dev/null and b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/venn2.png differ
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/venn3.png b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/venn3.png
new file mode 100644
index 0000000000..d612e310dc
Binary files /dev/null and b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/venn3.png differ
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/vennn.png b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/vennn.png
new file mode 100644
index 0000000000..7710a5b746
Binary files /dev/null and b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/BayesTheorem/vennn.png differ
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem1.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem1.pg
new file mode 100644
index 0000000000..5c710b9dc7
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem1.pg
@@ -0,0 +1,212 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Probability via Counting: 4-Digit PIN with No Repeated Digits (Guided / Scaffolded)
+## ENDDESCRIPTION
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data
+# =======================================================
+Context("Numeric");
+
+$n = 10;
+$r = 4;
+$S_total = $n**$r; # 10^4
+$E_fav = 10 * 9 * 8 * 7; # P(10,4)
+$prob = $E_fav / $S_total;
+
+$val10 = Real(10);
+$valS = Real($S_total);
+
+$valE1 = Real(10);
+$valE2 = Real(9);
+$valE3 = Real(8);
+$valE4 = Real(7);
+
+$valEfav = Real($E_fav);
+$valProb = Real($prob);
+
+# =======================================================
+# Evaluators
+# =======================================================
+$cmp_d1 = $val10->cmp->withPostFilter(
+ AnswerHints(
+ sub { $_[0] == 9 } =>
+ "A PIN can start with 0, so the first digit has 10 choices."
+ )
+);
+$cmp_d2 = $val10->cmp;
+$cmp_d3 = $val10->cmp;
+$cmp_d4 = $val10->cmp;
+
+$cmp_S = $valS->cmp->withPostFilter(
+ AnswerHints(
+ sub { abs($_[0] - 1000) < 0.5 } =>
+ "It looks like you used 10^3. A 4-digit PIN has 4 positions.",
+ sub { abs($_[0] - $E_fav) < 0.5 } =>
+ "That counts only no-repeat PINs. The sample space includes all possible PINs.",
+ )
+);
+
+$cmp_E1 = $valE1->cmp;
+$cmp_E2 = $valE2->cmp->withPostFilter(
+ AnswerHints(
+ sub { $_[0] == 10 } =>
+ "No repeats means you cannot reuse the first digit."
+ )
+);
+$cmp_E3 = $valE3->cmp;
+$cmp_E4 = $valE4->cmp;
+
+$cmp_Efav = $valEfav->cmp->withPostFilter(
+ AnswerHints(
+ sub { abs($_[0] - 34) < 0.5 } =>
+ "It looks like you added instead of multiplying.",
+ sub { abs($_[0] - 210) < 0.5 } =>
+ "210 is C(10,4). A PIN is ordered, so use P(10,4).",
+ )
+);
+
+$cmp_prob = $valProb->cmp->withPostFilter(
+ AnswerHints(
+ sub { $_[0] > 1 } => "Probabilities cannot be greater than 1.",
+ )
+);
+
+# Step 2 MC
+$rb_why_counting = RadioButtons(
+ [
+ "Because all possible PINs have the same probability \(1/\#(S)\).",
+ "Because we are only using 10 digits.",
+ "Because the number of favorable outcomes is less than the total.",
+ "Because PIN codes are always calculated this way.",
+ ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# Step 4 MC
+$rb_reason = RadioButtons(
+ [
+ "Because a PIN is an ordered code and we are not allowing repeated digits.",
+ "Because order does not matter when choosing digits for a PIN.",
+ "Because we must divide by 4! to remove overcounting.",
+ ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ my $v = eval { $student->value }; # safe extraction
+
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ansHash->{score} = 1;
+ $ansHash->{ans_message} = "Thanks!";
+ } else {
+ $ansHash->{score} = 0;
+ $ansHash->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+
+ return $ansHash->{score};
+ }
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin();
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A **4-digit PIN** is generated at random (digits 0 through 9 are allowed in each position).
+
+What is the probability that there is **no repeated digit**?
+END_PGML
+Section::End();
+
+Section::Begin("Equally likely outcomes");
+BEGIN_PGML
+All outcomes in the sample space of this experiment are **equally likely**.
+So if [`` E ``] is the event "no repeated digit", then: [`` P(E)=\frac{\#(E)}{\#(S)} ``].
+
+**Checkpoint:** Why can [`` P(E) ``] be calculated by simply counting and dividing here?
+
+[@ $rb_why_counting->buttons() @]*
+END_PGML
+ANS($rb_why_counting->cmp);
+Section::End();
+
+Section::Begin("Count the sample space");
+BEGIN_PGML
+How many options do we have for each digit if there is no limitation?
+
+Digit 1: [__]{$cmp_d1} Digit 2: [__]{$cmp_d2} Digit 3: [__]{$cmp_d3} Digit 4: [__]{$cmp_d4}
+
+Total outcomes [`` \#(S) = ``] [__________]{$cmp_S}
+END_PGML
+Section::End();
+
+Section::Begin("Count favorable outcomes");
+BEGIN_PGML
+Count PINs with **no repeated digit**. How many options do we have for each digit if **no repetition** is allowed?
+
+Digit 1: [__]{$cmp_E1} Digit 2: [__]{$cmp_E2} Digit 3: [__]{$cmp_E3} Digit 4: [__]{$cmp_E4}
+
+Favorable outcomes [`` \#(E) = ``] [__________]{$cmp_Efav}
+
+Why should we use [`` P(10,4) ``] in this case?
+
+[@ $rb_reason->buttons() @]*
+END_PGML
+ANS($rb_reason->cmp);
+Section::End();
+
+Section::Begin("Final Answer");
+BEGIN_PGML
+Using [`` P(E)=\frac{\#(E)}{\#(S)} ``]:
+
+[`` P(E) = ``] [____________________]{$cmp_prob}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating 1–5)
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning combinations?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem10.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem10.pg
new file mode 100644
index 0000000000..4cc45d3289
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem10.pg
@@ -0,0 +1,209 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Restaurant Collision (Complement Rule) (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Counting Methods)
+## Level(2)
+## KEYWORDS('birthday problem','complement rule','counting','permutations','probability','restaurants')
+## Static(1)
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Context & Data
+# =======================================================
+Context("Numeric");
+Context()->flags->set(implicitMultiplication => 1);
+
+$n = 30;
+$m = 300;
+
+# Stable product expression for P(A^c) to avoid gigantic intermediate numbers
+$pAc_expr = join('*', map { '(' . ($m-$_) . '/' . $m . ')' } 0..($n-1)); # (300/300)(299/300)...(271/300)
+$pA_expr = "1-($pAc_expr)";
+
+$pAc = Compute($pAc_expr);
+$pA = Compute($pA_expr);
+
+# =======================================================
+# Comparators
+# =======================================================
+$cmp_pAc = $pAc->cmp;
+$cmp_pA = $pA->cmp;
+
+# Rating Check
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = eval { $student->value };
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ansHash->{score} = 1;
+ $ansHash->{ans_message} = "Thanks!";
+ } else {
+ $ansHash->{score} = 0;
+ $ansHash->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+ return $ansHash->{score};
+ }
+);
+
+# =======================================================
+# RadioButtons
+# =======================================================
+$rb_comp = RadioButtons(
+ [
+ 'Exactly 2 people meet',
+ 'At least 2 people meet',
+ 'All 30 people choose different restaurants',
+ 'All 30 people choose the same restaurant'
+ ],
+ 2, # complement event is "All 30 people choose different restaurants"
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+$rb_formula = RadioButtons(
+ [
+ 'P(A) = 1 + P(complement of A)',
+ 'P(A) = P(complement of A)',
+ 'P(A) = 1 - P(complement of A)',
+ 'P(A) = 1 / P(complement of A)'
+ ],
+ 2, # correct is "P(A) = 1 - P(complement of A)"
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin();
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+In a small community, 30 people who all know each other decide to eat out tonight. Each one randomly chooses one out of the 300 restaurants in town.
+
+**Question:** What is the probability that at least two of them meet?
+
+Assume:
+- each person chooses uniformly from the 300 restaurants
+- choices are independent
+
+Hint: Find the probability of the complement event.
+END_PGML
+Section::End();
+
+Section::Begin("Identify the complement event");
+BEGIN_PGML
+Let event **A** be: “At least 2 of the 30 people meet” (meaning at least two people choose the same restaurant).
+
+**Checkpoint:** Which event is the complement of event A?
+
+[_]{$rb_comp}
+END_PGML
+Section::End();
+
+Section::Begin("Use the complement rule");
+BEGIN_PGML
+In this problem finding the probability of the complement event (All 30 people choose different restaurants) is easier.
+
+**Checkpoint:** Which formula can used to find [`` P(A) ``] once we have [`` P(\text{complement of }A) ``]?
+
+[_]{$rb_formula}
+END_PGML
+Section::End();
+
+Section::Begin("Count the complement event");
+BEGIN_PGML
+We should use:
+[`` P(\text{complement of }A)=\dfrac{\text{number of ways 30 people can choose different restaurants}}{\text{number of all possibilities regarding restaurant choices of 30 people}}. ``]
+
+**Numerator (two ways to understand it):**
+
+**Way 1 (direct counting):**
+Person 1 has [`` 300 ``] choices.
+Person 2 must avoid that restaurant: [`` 299 ``] choices.
+Then [`` 298 ``], then [`` 297 ``], and so on, down to [`` 271 ``].
+So the numerator is:
+[`` (300)(299)\cdots(271) ``]
+
+**Way 2 (permutations idea):**
+This is like first picking [`` 30 ``] restaurants out of [`` 300 ``] and then assigning them to the [`` 30 ``] people (multiply by [`` 30! ``]).
+That count is equal to:
+[`` P(300,30) ``]
+and:
+[`` P(300,30)=(300)(299)\cdots(271) ``]
+
+**Denominator:**
+Each of the [`` 30 ``] people can choose any of the [`` 300 ``] restaurants, independently.
+So the denominator is:
+[`` 300^{30} ``]
+END_PGML
+Section::End();
+
+Section::Begin("Compute P(complement of A) and P(A)");
+BEGIN_PGML
+Let [`` A^c ``] be the complement event.
+
+
+**1)** Compute [`` P(A^c) ``]:
+[_]{$cmp_pAc}{35}
+
+**2)** Compute [`` P(A) ``]:
+[_]{$cmp_pA}{35}
+END_PGML
+Section::End();
+
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning combinations?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+BEGIN_PGML_SOLUTION
+The probability is:
+
+**1.** Let [`` A ``] be the event “at least two people meet.”
+Then [`` A^c ``] is “all 30 people choose different restaurants.”
+
+**2.** Count outcomes.
+
+- Total outcomes: [`` 300^{30} ``]
+- Favorable outcomes for [`` A^c ``]: [`` (300)(299)\cdots(271) ``]
+
+So,
+[`` P(A^c)=\dfrac{(300)(299)\cdots(271)}{300^{30}}. ``]
+
+**3.** Use the complement rule:
+[`` P(A)=1-P(A^c)=1-\dfrac{(300)(299)\cdots(271)}{300^{30}}. ``]
+
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem2.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem2.pg
new file mode 100644
index 0000000000..e77994d87c
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem2.pg
@@ -0,0 +1,184 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Probability via Counting: Lotto 6/49 Jackpot (Guided / Scaffolded)
+## ENDDESCRIPTION
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data
+# =======================================================
+Context("Numeric");
+
+# Lotto 6/49: choose 6 numbers from 49 (order does not matter)
+$n = 49;
+$r = 6;
+
+# helper: nCr without huge factorials
+sub nCr {
+ my ($n,$r) = @_;
+ return 0 if ($r < 0 || $r > $n);
+ $r = $n - $r if ($r > $n - $r);
+ my $prod = 1;
+ for (my $k = 1; $k <= $r; $k++) {
+ $prod = $prod * ($n - $r + $k) / $k;
+ }
+ return int($prod + 0.5);
+}
+
+# Sample space size: C(49,6)
+$S_total = nCr($n,$r);
+
+# Common wrong counts (for hints)
+$S_perm = 1;
+for (my $i = 0; $i < $r; $i++) { $S_perm *= ($n - $i); }
+$S_pow = $n**$r;
+
+# Favorable outcomes for ONE ticket
+$E_fav = 1;
+
+# Probability
+$prob = $E_fav / $S_total;
+
+# =======================================================
+# Values
+# =======================================================
+$valS = Real($S_total);
+$valEfav = Real($E_fav);
+$valProb = Real($prob);
+
+# =======================================================
+# Evaluators
+# =======================================================
+$cmp_S = $valS->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0]-$S_perm) < 0.5 } => "That is \(P(49,6)\). For Lotto 6/49, the order does NOT matter, so use \(C(49,6)\).",
+ sub { abs($_[0]-$S_pow) < 0.5 } => "That is \(49^6\). In Lotto, balls are drawn without replacement and order does not matter.",
+));
+
+$cmp_Efav = $valEfav->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0]-720) < 0.5 } => "A single ticket is ONE specific set of 6 numbers.",
+ sub { abs($_[0]-6) < 0.5 } => "One ticket is one outcome, not 6.",
+));
+
+$cmp_prob = $valProb->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "Probabilities cannot be greater than 1.",
+));
+
+# Step 2 checkpoint
+$rb_method = RadioButtons(
+ [
+ "Use \(49^6\) because each draw has 49 choices.",
+ "Use \(P(49,6)\) because the balls are drawn one after another.",
+ "Use \(C(49,6)\) because only the set of 6 numbers matters (order does not matter).",
+ ],
+ 2,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ my $v = eval { $student->value }; # safe extraction
+
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ansHash->{score} = 1;
+ $ansHash->{ans_message} = "Thanks!";
+ } else {
+ $ansHash->{score} = 0;
+ $ansHash->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+
+ return $ansHash->{score};
+ }
+);
+
+# =======================================================
+# Guided flow (Scaffold)
+# =======================================================
+Scaffold::Begin();
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+In **Lotto 6/49**, six numbers are drawn at random from a set of 49 numbers (balls labeled 1 to 49). The 6 balls are drawn **without replacement**.
+
+You buy **one ticket** by choosing **6 distinct numbers**. You hit the **jackpot** if your numbers match the draws perfectly. **Order does not matter.**
+
+Find the probability of hitting the jackpot with a single ticket.
+END_PGML
+Section::End();
+
+Section::Begin("Equally likely outcomes");
+BEGIN_PGML
+All 6-number sets are **equally likely**. If [`` E ``] is the event "hit the jackpot", then:
+[`` P(E)=\frac{\#(E)}{\#(S)} ``].
+
+**Checkpoint:** Which counting method should we use for [`` \#(S) ``] here?
+
+[@ $rb_method->buttons() @]*
+END_PGML
+ANS($rb_method->cmp);
+Section::End();
+
+Section::Begin("Count the sample space");
+BEGIN_PGML
+The sample space consists of all possible sets of 6 numbers from 49, where **order does not matter**.
+
+The number of all possible outcomes:
+
+[`` \#(S) = ``] [________________]{$cmp_S}
+END_PGML
+Section::End();
+
+Section::Begin("Count favorable outcomes");
+BEGIN_PGML
+How many outcomes (6-number sets) from the sample space match your specific ticket exactly?
+
+[`` \#(E) = ``] [____]{$cmp_Efav}
+END_PGML
+Section::End();
+
+Section::Begin("Final Answer");
+BEGIN_PGML
+Using [`` P(E)=\frac{\#(E)}{\#(S)} ``]:
+
+[`` P(E) = ``] [____________________]{$cmp_prob}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating 1–5)
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning combinations?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem3.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem3.pg
new file mode 100644
index 0000000000..c6196f90e5
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem3.pg
@@ -0,0 +1,204 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Probability via Counting: Lotto 6/49 Second Prize (Guided / Scaffolded)
+## ENDDESCRIPTION
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data & Calculations
+# =======================================================
+Context("Numeric");
+Context()->flags->set(implicitMultiplication => 1);
+
+sub nCr {
+ my ($n,$r) = @_;
+ return 0 if ($r < 0 || $r > $n);
+ $r = $n - $r if ($r > $n - $r);
+ my $prod = 1;
+ for (my $k = 1; $k <= $r; $k++) {
+ $prod = $prod * ($n - $r + $k) / $k;
+ }
+ return int($prod + 0.5);
+}
+
+# Values for the problem
+$S_total = nCr(49,6);
+$win_5_of_6 = nCr(6,5); # 6
+$lose_1_of_43 = nCr(43,1); # 43
+$E_fav = $win_5_of_6 * $lose_1_of_43; # 258
+$prob = $E_fav / $S_total;
+
+# MathObjects
+$valS = Real($S_total);
+$valW = Real($win_5_of_6);
+$valL = Real($lose_1_of_43);
+$valE = Real($E_fav);
+$valP = Real($prob);
+
+# =======================================================
+# Evaluators & MC
+# =======================================================
+
+# MC for Equally Likely Section (4 choices => labels ABCD)
+$rb_why_counting = RadioButtons(
+ [
+ "Because all possible tickets have the same probability \(1/\#(S)\).",
+ "Because there are 49 balls in the machine.",
+ "Because we are choosing more than one number.",
+ "Because the prize depends on how many people play.",
+ ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# MC checkpoint for Multiplication Principle (5 choices => labels ABCDE)
+$rb_mult_principle = RadioButtons(
+ [
+ "We add the number of ways from Stage 1 and Stage 2.",
+ "We use the multiplication Principle.",
+ "We subtract the Stage 2 count from the Stage 1 count.",
+ "We divide Stage 1 by Stage 2 because order does not matter.",
+ "We multiply by 49 because there are 49 balls.",
+ ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# Hint for Sample Space
+$cmp_S = $valS->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] == 10068347520 } => "That looks like P(49,6). Does the order of the numbers drawn matter in Lotto 6/49?",
+));
+
+# Hint for Favorable Stages
+$cmp_W = $valW->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] == 30 } => "It looks like you used P(6,5). Does the order of the 5 winning numbers matter?",
+));
+
+$cmp_L = $valL->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] == 49 } => "You need to pick a non-winning number. How many balls are NOT winning numbers?",
+));
+
+$cmp_E = $valE->cmp;
+
+$cmp_P = $valP->cmp(
+ tolType => "absolute",
+ tol => 1e-12,
+);
+
+# =======================================================
+# Rating (1–5)
+# =======================================================
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = eval { $student->value };
+
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ansHash->{score} = 1;
+ $ansHash->{ans_message} = "Thanks!";
+ } else {
+ $ansHash->{score} = 0;
+ $ansHash->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+ return $ansHash->{score};
+ }
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin();
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+In **Lotto 6/49**, a player wins the **second prize** if exactly **five** of the six numbers on their ticket match the six winning numbers drawn (order does not matter).
+
+What is the probability that you win the second prize if you purchased a single ticket?
+END_PGML
+Section::End();
+
+Section::Begin("Equally likely outcomes");
+BEGIN_PGML
+All outcomes in the sample space of this experiment are **equally likely**.
+So if [`` E ``] is the event "win second prize", then: [`` P(E)=\frac{\#(E)}{\#(S)} ``].
+
+**Checkpoint:** Why can [`` P(E) ``] be calculated by simply counting and dividing here?
+
+[_]{$rb_why_counting}
+END_PGML
+Section::End();
+
+Section::Begin("Count the sample space");
+BEGIN_PGML
+How many possible ways can 6 numbers be drawn from 49 balls, if the order of the balls does not matter?
+
+[`` \#(S) = ``] [________________]{$cmp_S}
+END_PGML
+Section::End();
+
+Section::Begin("Count Favorable Outcomes");
+BEGIN_PGML
+You can think of building a second-prize winning ticket as a **two-stage process**.
+
+**Stage 1:** First, you need to pick **5 winning numbers** out of the 6 winning numbers available.
+How many ways can you do that?
+[____]{$cmp_W}
+
+**Stage 2:** Then, you need to pick **1 non-winning number** out of the remaining non-winning numbers.
+How many ways can you do that?
+[____]{$cmp_L}
+
+**Checkpoint:** Now that we have the number of ways each stage can be done, how do we calculate the total number of ways a second-prize winning ticket can be created?
+
+[_]{$rb_mult_principle}
+
+**Total Favorable Outcomes:** [`` \#(E) = ``] [__________]{$cmp_E}
+END_PGML
+Section::End();
+
+Section::Begin("Final Answer");
+BEGIN_PGML
+Using the outcomes calculated above:
+
+[`` P(E) = ``] [____________________]{$cmp_P}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating 1–5)
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning combinations?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem4.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem4.pg
new file mode 100644
index 0000000000..9d824d7c06
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem4.pg
@@ -0,0 +1,239 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Probability via Counting: Team of 5 with 3 Girls and 2 Boys (Guided / Scaffolded)
+## ENDDESCRIPTION
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data & Calculations
+# =======================================================
+Context("Numeric");
+Context()->flags->set(implicitMultiplication => 1);
+
+# Class composition
+$G = 12; # girls
+$B = 9; # boys
+$n = 5; # team size
+
+# helper: nCr without huge factorials
+sub nCr {
+ my ($n,$r) = @_;
+ return 0 if ($r < 0 || $r > $n);
+ $r = $n - $r if ($r > $n - $r);
+ my $prod = 1;
+ for (my $k = 1; $k <= $r; $k++) {
+ $prod = $prod * ($n - $r + $k) / $k;
+ }
+ return int($prod + 0.5);
+}
+
+# Sample space: choose 5 from 21
+$S_total = nCr($G + $B, $n);
+
+# Favorable: choose 3 girls AND 2 boys
+$E_g = nCr($G, 3);
+$E_b = nCr($B, 2);
+$E_fav = $E_g * $E_b;
+
+# Probability
+$prob = $E_fav / $S_total;
+
+# MathObjects
+$valS = Real($S_total);
+$valG = Real($E_g);
+$valB = Real($E_b);
+$valE = Real($E_fav);
+$valP = Real($prob);
+
+# =======================================================
+# Evaluators & MC
+# =======================================================
+
+# MC for Equally Likely Section
+$rb_why_counting = RadioButtons(
+ [
+ "Because every team of 5 students is equally likely, so we can count outcomes and divide.",
+ "Because there are more girls than boys.",
+ "Because the team has 5 students.",
+ "Because probability always uses combinations.",
+ ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# MC for choosing method in sample space
+$rb_method_S = RadioButtons(
+ [
+ "Use \(21^5\) because there are 21 students and 5 spots.",
+ "Use \(P(21,5)\) because a team is ordered.",
+ "Use \(C(21,5)\) because a team is just a set (order does not matter).",
+ ],
+ 2,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# MC for Multiplication Principle checkpoint
+$rb_mult_principle = RadioButtons(
+ [
+ "We add the number of ways to choose the girls and the boys.",
+ "We use the multiplication Principle: (ways to choose 3 girls) times (ways to choose 2 boys).",
+ "We divide because we are using two groups.",
+ "We multiply by 5! because there are 5 students.",
+ "We subtract because boys and girls overlap.",
+ ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# Answer evaluators (with a few common-mistake hints)
+
+$cmp_S = $valS->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (21**5)) < 0.5 } =>
+ "That looks like \(21^5\). That would treat the team as ordered and allow repeats, which is not correct.",
+ sub { abs($_[0] - (21*20*19*18*17)) < 0.5 } =>
+ "That looks like \(P(21,5)\). A team is not ordered, so use a combination.",
+));
+
+$cmp_G = $valG->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (12*11*10)) < 0.5 } =>
+ "That looks like \(P(12,3)\). Choosing 3 girls for a team is not ordered, so use \(C(12,3)\).",
+));
+
+$cmp_B = $valB->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (9*8)) < 0.5 } =>
+ "That looks like \(P(9,2)\). Choosing 2 boys for a team is not ordered, so use \(C(9,2)\).",
+));
+
+$cmp_E = $valE->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - ($E_g + $E_b)) < 0.5 } =>
+ "It looks like you added. Here we need a two-stage count, so multiply the stage counts.",
+));
+
+$cmp_P = $valP->cmp(
+ tolType => "absolute",
+ tol => 1e-12,
+)->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "Probabilities cannot be greater than 1.",
+));
+
+# Rating (1–5) -- fixed (no setMessage warnings)
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = eval { $student->value };
+
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ansHash->{score} = 1;
+ $ansHash->{ans_message} = "Thanks!";
+ } else {
+ $ansHash->{score} = 0;
+ $ansHash->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+ return $ansHash->{score};
+ }
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin();
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+In a class of **9 boys** and **12 girls**, a team of **5 students** is chosen at random.
+
+What is the probability that the team consists of **3 girls** and **2 boys**?
+END_PGML
+Section::End();
+
+Section::Begin("Equally likely outcomes");
+BEGIN_PGML
+All possible teams of 5 students are **equally likely**.
+
+So if [`` E ``] is the event "3 girls and 2 boys", then: [`` P(E)=\frac{\#(E)}{\#(S)} ``].
+
+**Checkpoint:** Why can [`` P(E) ``] be calculated by simply counting and dividing here?
+
+[_]{$rb_why_counting}
+END_PGML
+Section::End();
+
+Section::Begin("Count the sample space");
+BEGIN_PGML
+The sample space consists of all possible teams of 5 students chosen from 21 students, where **order does not matter**.
+
+**Checkpoint:** Which counting method should we use for [`` \#(S) ``]?
+
+[_]{$rb_method_S}
+
+Now compute the sample space size:
+
+[`` \#(S) = ``] [________________]{$cmp_S}
+END_PGML
+Section::End();
+
+Section::Begin("Count Favorable Outcomes");
+BEGIN_PGML
+A favorable team has **3 girls** and **2 boys**. Think of this as a **two-stage process**.
+
+**Stage 1:** Choose **3 girls** from the 12 girls.
+[`` \#(\text{Stage 1}) = ``] [____]{$cmp_G}
+
+**Stage 2:** Choose **2 boys** from the 9 boys.
+[`` \#(\text{Stage 2}) = ``] [____]{$cmp_B}
+
+**Checkpoint:** Now that we have the number of ways each stage can be done, how do we calculate the total number of ways a favorable team can be created?
+
+[_]{$rb_mult_principle}
+
+**Total Favorable Outcomes:** [`` \#(E) = ``] [__________]{$cmp_E}
+END_PGML
+Section::End();
+
+Section::Begin("Final Answer");
+BEGIN_PGML
+Using the counts above:
+
+[`` P(E) = ``] [____________________]{$cmp_P}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating 1–5)
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning combinations?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem5.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem5.pg
new file mode 100644
index 0000000000..a7326b9f3a
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem5.pg
@@ -0,0 +1,280 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Probability via Counting: 10-Card Hand with Exactly 2 Aces and 2 Kings (Guided / Scaffolded)
+## ENDDESCRIPTION
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data & Calculations
+# =======================================================
+Context("Numeric");
+Context()->flags->set(implicitMultiplication => 1);
+
+# Standard deck
+$N = 52;
+$hand = 10;
+
+# Key groups
+$A = 4; # aces
+$K = 4; # kings
+$O = 52 - 4 - 4; # other cards (not ace, not king) = 44
+
+# helper: nCr without huge factorials
+sub nCr {
+ my ($n,$r) = @_;
+ return 0 if ($r < 0 || $r > $n);
+ $r = $n - $r if ($r > $n - $r);
+ my $prod = 1;
+ for (my $k = 1; $k <= $r; $k++) {
+ $prod = $prod * ($n - $r + $k) / $k;
+ }
+ return int($prod + 0.5);
+}
+
+# Sample space: all 10-card hands from 52
+$S_total = nCr($N, $hand);
+
+# Favorable: exactly 2 aces, exactly 2 kings, remaining 6 are "other"
+$ways_A = nCr($A, 2);
+$ways_K = nCr($K, 2);
+$ways_O = nCr($O, 6);
+
+$E_fav = $ways_A * $ways_K * $ways_O;
+
+$prob = $E_fav / $S_total;
+
+# MathObjects
+$valS = Real($S_total);
+$valA = Real($ways_A);
+$valK = Real($ways_K);
+$valO = Real($ways_O);
+$valE = Real($E_fav);
+$valP = Real($prob);
+
+# =======================================================
+# MC checkpoints
+# =======================================================
+
+$rb_why_counting = RadioButtons(
+ [
+ "Because every 10-card hand is equally likely, so we can count outcomes and divide.",
+ "Because there are 52 cards in the deck.",
+ "Because aces and kings are special cards.",
+ "Because probabilities always use combinations.",
+ ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+$rb_method_S = RadioButtons(
+ [
+ "Use \(52^{10}\) because each draw has 52 choices.",
+ "Use \(P(52,10)\) because cards are drawn one after another.",
+ "Use \(C(52,10)\) because a hand is a set of cards (order does not matter).",
+ ],
+ 2,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+$rb_mult_principle = RadioButtons(
+ [
+ "We add the counts for aces, kings, and other cards.",
+ "We use the multiplication Principle: multiply the number of ways for each stage.",
+ "We divide because we are using three categories.",
+ "We multiply by 10! because there are 10 cards.",
+ "We subtract because aces and kings overlap.",
+ ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Evaluators (with a few common-mistake hints)
+# =======================================================
+
+# Common wrong counts for sample space (for hints)
+$S_perm = 1;
+for (my $i = 0; $i < $hand; $i++) { $S_perm *= ($N - $i); } # P(52,10)
+$S_pow = $N**$hand; # 52^10
+
+$cmp_S = $valS->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - $S_perm) < 0.5 } =>
+ "That looks like \(P(52,10)\). A hand is not ordered, so use \(C(52,10)\).",
+ sub { abs($_[0] - $S_pow) < 0.5 } =>
+ "That looks like \(52^{10}\). Cards are drawn without replacement and order does not matter for a hand.",
+));
+
+$cmp_A = $valA->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 12) < 0.5 } =>
+ "12 is \(P(4,2)\). Choosing 2 aces is not ordered, so use \(C(4,2)\).",
+));
+
+$cmp_K = $valK->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 12) < 0.5 } =>
+ "12 is \(P(4,2)\). Choosing 2 kings is not ordered, so use \(C(4,2)\).",
+));
+
+$cmp_O = $valO->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - nCr($O,4)) < 0.5 } =>
+ "Careful: after choosing 2 aces and 2 kings, there are 6 remaining cards to choose (not 4).",
+ sub { abs($_[0] - nCr($O,8)) < 0.5 } =>
+ "Careful: after choosing 2 aces and 2 kings, there are 6 remaining cards to choose (not 8).",
+));
+
+$cmp_E = $valE->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - ($ways_A + $ways_K + $ways_O)) < 0.5 } =>
+ "It looks like you added. This is a multi-stage count, so multiply the stage counts.",
+));
+
+$cmp_P = $valP->cmp(
+ tolType => "absolute",
+ tol => 1e-12,
+)->withPostFilter(AnswerHints(
+ sub { $_[0] > 1 } => "Probabilities cannot be greater than 1.",
+));
+
+# Rating (1–5) -- fixed (no setMessage warnings)
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = eval { $student->value };
+
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ansHash->{score} = 1;
+ $ansHash->{ans_message} = "Thanks!";
+ } else {
+ $ansHash->{score} = 0;
+ $ansHash->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+ return $ansHash->{score};
+ }
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin();
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+If you draw **10 cards at random** (without replacement) from a standard deck, what is the probability that your 10-card hand contains **exactly 2 aces** and **exactly 2 kings**?
+
+
+Here is what you need to know about a standard deck:
+
+- There are **52 cards** total.
+
+- There are **4 suits**: Clubs, Diamonds, Hearts, Spades.
+
+- Each suit has **13 ranks** in this order:
+Ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King.
+
+- A **face card** means either a **Jack**, a **Queen**, or a **King**.
+
+
+Color fact:
+
+- **Hearts** and **Diamonds** are **red**.
+
+- **Clubs** and **Spades** are **black**.
+
+END_PGML
+Section::End();
+
+Section::Begin("Equally likely outcomes");
+BEGIN_PGML
+All 10-card hands are **equally likely**.
+
+So if [`` E ``] is the event "exactly 2 aces and exactly 2 kings", then:
+[`` P(E)=\frac{\#(E)}{\#(S)} ``].
+
+**Checkpoint:** Why can we use counting and dividing here?
+
+[_]{$rb_why_counting}
+END_PGML
+Section::End();
+
+Section::Begin("Count the sample space");
+BEGIN_PGML
+The sample space is all possible 10-card hands chosen from 52 cards, where **order does not matter**.
+
+**Checkpoint:** Which counting method should we use for [`` \#(S) ``]?
+
+[_]{$rb_method_S}
+
+Now compute the sample space size:
+
+[`` \#(S) = ``] [________________]{$cmp_S}
+END_PGML
+Section::End();
+
+Section::Begin("Count Favorable Outcomes");
+BEGIN_PGML
+A favorable hand has **exactly 2 aces**, **exactly 2 kings**, and the remaining **6 cards** must be **neither aces nor kings**.
+
+Think of this as a **three-stage process**:
+
+**Stage 1:** Choose 2 of the 4 aces.
+[`` \#(\text{Stage 1}) = ``] [____]{$cmp_A}
+
+**Stage 2:** Choose 2 of the 4 kings.
+[`` \#(\text{Stage 2}) = ``] [____]{$cmp_K}
+
+**Stage 3:** Choose the remaining 6 cards from the 44 non-ace, non-king cards.
+[`` \#(\text{Stage 3}) = ``] [__________]{$cmp_O}
+
+**Checkpoint:** Once we have the number of ways for each stage, how do we combine them to get [`` \#(E) ``]?
+
+[_]{$rb_mult_principle}
+
+**Total Favorable Outcomes:** [`` \#(E) = ``] [____________________]{$cmp_E}
+END_PGML
+Section::End();
+
+Section::Begin("Final Answer");
+BEGIN_PGML
+Using [`` P(E)=\frac{\#(E)}{\#(S)} ``]:
+
+[`` P(E) = ``] [____________________]{$cmp_P}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating 1–5)
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning combinations?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem6.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem6.pg
new file mode 100644
index 0000000000..cfb3791613
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem6.pg
@@ -0,0 +1,224 @@
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Context & Data
+# =======================================================
+Context("Numeric");
+Context()->flags->set(implicitMultiplication => 1);
+
+# Use Compute for better handling of formula inputs vs raw numbers
+$space_n = Compute("2^7");
+
+$num1 = Compute("5^5");
+$den1 = Compute("6^7");
+$num2 = Compute("5^5");
+$den2 = Compute("6^7");
+
+$prob_one = Compute("(1/6)^2*(5/6)^5");
+$count = Compute("21");
+$final = Compute("21*(1/6)^2*(5/6)^5");
+
+$hint_indep = "Hint: P(FFSFFFS) = P(F)P(F)P(S)P(F)P(F)P(F)P(S). Use 1/6 for P(S) and 5/6 for P(F).";
+
+# =======================================================
+# Comparators
+# =======================================================
+$cmp_space = $space_n->cmp->withPostFilter(AnswerHints(
+ $space_n => "Correct! (2^7)",
+ sub {
+ my ($correct, $student, $ansHash) = @_;
+ return ($ansHash->{score} // 0) < 1;
+ } => "Hint: Each roll becomes either S or F. That's 2 choices per roll."
+));
+
+$cmp_num_1 = $num1->cmp;
+$cmp_den_1 = $den1->cmp;
+$cmp_num_2 = $num2->cmp;
+$cmp_den_2 = $den2->cmp;
+$cmp_prob_one = $prob_one->cmp;
+$cmp_count = $count->cmp;
+$cmp_final = $final->cmp;
+
+# Rating Check
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = eval { $student->value };
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ansHash->{score} = 1;
+ $ansHash->{ans_message} = "Thanks!";
+ } else {
+ $ansHash->{score} = 0;
+ $ansHash->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+ return $ansHash->{score};
+ }
+);
+
+# =======================================================
+# RadioButtons
+# =======================================================
+$rb_inE = RadioButtons(
+ ['SSFFFSF','FFSFFFF','SFFFFFS','FFFFFSF'],
+ 2, # Correct is SFSFFFF (Index 2)
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+$rb_equal = RadioButtons(
+ [ 'Yes, the likelyhood is the same, regardless of the number of successes', 'No, the likelyhood depends on the number of successes' ],
+ 1, # Correct is "No" (Index 1)
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin();
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A fair die is rolled 7 times.
+
+**Question:** What is the probability of rolling the number 6 **exactly twice**?
+END_PGML
+Section::End();
+
+Section::Begin("Turn into Success and Failure Experiment");
+BEGIN_PGML
+We will turn this into an experiment where each trial consist of 7 independent rolls of a fair die. Each roll can either be a **Success** or a **Failure**.
+
+- Let **S (Success)** mean: “the roll is 6”
+- Let **F (Failure)** mean: “the roll is not 6”
+
+Then each outcome becomes a 7-letter string made of S’s and F’s, such as:
+
+- `FFSFFFS` or `SFSFFFF` (these have exactly 2 successes)
+- `SSFFFSF` or `FFSFFFF` (these do **not** have exactly 2 successes)
+
+Let event **E** be: “exactly 2 successes out of 7 rolls.”
+
+**Checkpoint:** Which outcome belongs to event E (exactly 2 successes)?
+[_]{$rb_inE}
+END_PGML
+Section::End();
+
+Section::Begin("How many S/F outcomes exist?");
+BEGIN_PGML
+What is the total number of outcomes regardless of the number of successes. That is the total number of outcomes in the sample space?
+
+**Enter the number of S/F outcomes in the sample space:** [_]{$cmp_space}{10}
+END_PGML
+Section::End();
+
+Section::Begin("Are these S/F outcomes equally likely?");
+BEGIN_PGML
+**Checkpoint:** Are these [`2^7`] outcomes equally likely? For example are **FFSFFFS** and **SSFFFSF** equally likely?
+[_]{$rb_equal}
+END_PGML
+Section::End();
+
+# -----------------------
+Section::Begin("Additive rule for outcomes");
+BEGIN_PGML
+Because the S/F outcomes are **not** equally likely, we cannot just do:
+
+- “number of favorable outcomes divided by total outcomes.”
+
+Instead we use the **additive rule for outcomes**:
+
+- The probability of an event equals the sum of the probabilities of the outcomes in that event.
+
+So here:
+- Event E = “all S/F strings with exactly 2 S’s”
+- We need to add the probabilities of those favorable strings.
+END_PGML
+Section::End();
+
+
+Section::Begin("Use independence to compute two outcome probabilities");
+BEGIN_PGML
+The 7 die rolls are independent, so the probability of a specific S/F string is the product of the roll probabilities.
+
+- \(P(S)=1/6\)
+- \(P(F)=5/6\)
+
+**1)** Compute [` P(FFSFFFS) `] (exactly two successes).
+Numerator: [_]{$cmp_num_1}{10} / Denominator: [_]{$cmp_den_1}{10}
+
+**2)** Compute [` P(SFSFFFF) `] (exactly two successes).
+Numerator: [_]{$cmp_num_2}{10} / Denominator: [_]{$cmp_den_2}{10}
+
+**Note:** [@ $hint_indep @]
+END_PGML
+Section::End();
+
+Section::Begin("Same probability for any 2S–5F string");
+BEGIN_PGML
+Any outcome with exactly **2 successes** and **5 failures** has the **same** probability. Enter this probability in the form [`(P(S))^2`] times [`(P(F))^5`]:
+
+**Enter this probability as a single expression:** [_]{$cmp_prob_one}{20}
+END_PGML
+Section::End();
+
+Section::Begin("Count favorable outcomes using the MISSISSIPPI idea");
+BEGIN_PGML
+Event E consists of all permutations of `SSFFFFF`. We know that all these permutations have the same probability. So we just need to use the `MISSISSIPPI` idea to figure out how many of all outcomes in the sample space consist exactly 2 S's and 5 F's.
+
+**Enter the number of favorable outcomes in E:** [_]{$cmp_count}{10}
+END_PGML
+Section::End();
+
+Section::Begin("Final Answer");
+BEGIN_PGML
+At this point we know that there are 21 events in Event (E=“exactly 2 successes out of 7 rolls.”). Each one have the same probability [`p=(1/6)^2(5/6)^5`]. Using **additive rule for outcomes** what is the probability of getting exactly 2 successes out of 7 rolls?
+**Final Answer:** [_]{$cmp_final}{30}
+END_PGML
+Section::End();
+
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning combinations?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+BEGIN_PGML_SOLUTION
+The probability is:
+
+**1.** Use the binomial model with \(n=7\) and \(p=1/6\):
+\\(
+P(E)=\\binom{7}{2}\\left(\\dfrac{1}{6}\\right)^2\\left(\\dfrac{5}{6}\\right)^5
+\\).
+
+**2.** Simplify:
+\\(
+P(E)=21\\left(\\dfrac{5^5}{6^7}\\right)
+\\).
+
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem7.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem7.pg
new file mode 100644
index 0000000000..8e710725d5
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem7.pg
@@ -0,0 +1,224 @@
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Context & Data
+# =======================================================
+Context("Numeric");
+Context()->flags->set(implicitMultiplication => 1);
+
+# Use Compute for better handling of formula inputs vs raw numbers
+$space_n = Compute("2^10");
+
+$num1 = Compute("4^7");
+$den1 = Compute("5^10");
+$num2 = Compute("4^7");
+$den2 = Compute("5^10");
+
+$prob_one = Compute("(1/5)^3*(4/5)^7");
+$count = Compute("120");
+$final = Compute("120*(1/5)^3*(4/5)^7");
+
+$hint_indep = "Hint: P(FFSFFSFFSF) = P(F)P(F)P(S)P(F)P(F)P(S)P(F)P(F)P(S)P(F). Use 1/5 for P(S) and 4/5 for P(F).";
+
+# =======================================================
+# Comparators
+# =======================================================
+$cmp_space = $space_n->cmp->withPostFilter(AnswerHints(
+ $space_n => "Correct! (2^10)",
+ sub {
+ my ($correct, $student, $ansHash) = @_;
+ return ($ansHash->{score} // 0) < 1;
+ } => "Hint: Each question becomes either S or F. That's 2 choices per question."
+));
+
+$cmp_num_1 = $num1->cmp;
+$cmp_den_1 = $den1->cmp;
+$cmp_num_2 = $num2->cmp;
+$cmp_den_2 = $den2->cmp;
+$cmp_prob_one = $prob_one->cmp;
+$cmp_count = $count->cmp;
+$cmp_final = $final->cmp;
+
+# Rating Check
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = eval { $student->value };
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ansHash->{score} = 1;
+ $ansHash->{ans_message} = "Thanks!";
+ } else {
+ $ansHash->{score} = 0;
+ $ansHash->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+ return $ansHash->{score};
+ }
+);
+
+# =======================================================
+# RadioButtons
+# =======================================================
+$rb_inE = RadioButtons(
+ ['SSFFFSFFSF','FFFFFSFFFF','SFFFFSFFSF','SFSFFFFSSF'],
+ 2, # Correct is FFSFFSFFSF (Index 2)
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+$rb_equal = RadioButtons(
+ [ 'Yes, the likelyhood is the same, regardless of the number of successes', 'No, the likelyhood depends on the number of successes' ],
+ 1, # Correct is "No" (Index 1)
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin();
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A multiple-choice quiz contains 10 questions with five possible answers each.
+
+**Question:** Evaluate the probability of purely randomly guessing the answers and getting exactly 3 questions correct.
+END_PGML
+Section::End();
+
+Section::Begin("Turn into Success and Failure Experiment");
+BEGIN_PGML
+We will turn this into an experiment where each trial consist of 10 independent questions. Each question can either be a **Success** or a **Failure**.
+
+- Let **S (Success)** mean: “your guess is correct”
+- Let **F (Failure)** mean: “your guess is not correct”
+
+Then each outcome becomes a 10-letter string made of S’s and F’s, such as:
+
+- `FFSFFSFFSF` or `SFFSFFFFSF` (these have exactly 3 successes)
+- `SSFFFSFFSF` or `FFFFFSFFFF` (these do **not** have exactly 3 successes)
+
+Let event **E** be: “exactly 3 successes out of 10 questions.”
+
+**Checkpoint:** Which outcome belongs to event E (exactly 3 successes)?
+[_]{$rb_inE}
+END_PGML
+Section::End();
+
+Section::Begin("How many S/F outcomes exist?");
+BEGIN_PGML
+What is the total number of outcomes in the sample space regardless of the number successes. Outcomes such as **FFSFFSFFSF** or **SSFFFSFFSF**?
+
+**Enter the number of S/F outcomes in the sample space:** [_]{$cmp_space}{10}
+END_PGML
+Section::End();
+
+Section::Begin("Are these S/F outcomes equally likely?");
+BEGIN_PGML
+**Checkpoint:** Are these [`2^{10}`] outcomes equally likely? For example are **FFSFFSFFSF** and **SSFFFSFFSF** equally likely?
+[_]{$rb_equal}
+END_PGML
+Section::End();
+
+# -----------------------
+Section::Begin("Additive rule for outcomes");
+BEGIN_PGML
+Because the S/F outcomes are **not** equally likely, we cannot just do:
+
+- “number of favorable outcomes divided by total outcomes.”
+
+Instead we use the **additive rule for outcomes**:
+
+- The probability of an event equals the sum of the probabilities of the outcomes in that event.
+
+So here:
+- Event E = “all S/F strings with exactly 3 S’s”
+- We need to add the probabilities of those favorable strings.
+END_PGML
+Section::End();
+
+
+Section::Begin("Use independence to compute two outcome probabilities");
+BEGIN_PGML
+The 10 questions are independent, so the probability of a specific S/F string is the product of the question probabilities.
+
+- \(P(S)=1/5\)
+- \(P(F)=4/5\)
+
+**1)** Compute [` P(FFSFFSFFSF) `] (exactly 3 successes).
+Numerator: [_]{$cmp_num_1}{10} / Denominator: [_]{$cmp_den_1}{10}
+
+**2)** Compute [` P(SFFSFFFFSF) `] (exactly 3 successes).
+Numerator: [_]{$cmp_num_2}{10} / Denominator: [_]{$cmp_den_2}{10}
+
+**Note:** [@ $hint_indep @]
+END_PGML
+Section::End();
+
+Section::Begin("Same probability for any 3S–7F string");
+BEGIN_PGML
+Any outcome with exactly **3 successes** and **7 failures** has the **same** probability. Enter this probability in the form [`(P(S))^3`] times [`(P(F))^7`]:
+
+**Enter this probability as a single expression:** [_]{$cmp_prob_one}{20}
+END_PGML
+Section::End();
+
+Section::Begin("Count favorable outcomes using the MISSISSIPPI idea");
+BEGIN_PGML
+Event E consists of all permutations of `SSSFFFFFFF`. We know that all these permutations have the same probability. So we just need to use the `MISSISSIPPI` idea to figure out how many of all outcomes in the sample space consist exactly 3 S's and 7 F's.
+
+**Enter the number of favorable outcomes in E:** [_]{$cmp_count}{10}
+END_PGML
+Section::End();
+
+Section::Begin("Final Answer");
+BEGIN_PGML
+At this point we know that there are 120 events in Event (E=“exactly 3 successes out of 10 questions.”). Each one have the same probability [`p=(1/5)^3(4/5)^7`]. Using **additive rule for outcomes** what is the probability of getting exactly 3 successes out of 10 questions?
+**Final Answer:** [_]{$cmp_final}{30}
+END_PGML
+Section::End();
+
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning combinations?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+BEGIN_PGML_SOLUTION
+The probability is:
+
+**1.** Use the binomial model with \(n=10\) and \(p=1/5\):
+\\(
+P(E)=\\binom{10}{3}\\left(\\dfrac{1}{5}\\right)^3\\left(\\dfrac{4}{5}\\right)^7
+\\).
+
+**2.** Simplify:
+\\(
+P(E)=120\\left(\\dfrac{4^7}{5^{10}}\\right)
+\\).
+
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem8.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem8.pg
new file mode 100644
index 0000000000..e40bd0b205
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem8.pg
@@ -0,0 +1,223 @@
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Context & Data
+# =======================================================
+Context("Numeric");
+Context()->flags->set(implicitMultiplication => 1);
+
+# Use Compute for better handling of formula inputs vs raw numbers
+$space_n = Compute("2^5");
+
+$num1 = Compute("19^4");
+$den1 = Compute("20^5");
+$num2 = Compute("19^4");
+$den2 = Compute("20^5");
+
+$prob_one = Compute("(19/20)^4*(1/20)^1");
+$count = Compute("5");
+$final = Compute("5*(19/20)^4*(1/20)^1");
+
+$hint_indep = "Hint: P(SSSSF) = P(S)P(S)P(S)P(S)P(F). Use 0.95 for P(S) and 0.05 for P(F).";
+
+# =======================================================
+# Comparators
+# =======================================================
+$cmp_space = $space_n->cmp->withPostFilter(AnswerHints(
+ $space_n => "Correct! (2^5)",
+ sub {
+ my ($correct, $student, $ansHash) = @_;
+ return ($ansHash->{score} // 0) < 1;
+ } => "Hint: Each email becomes either S or F. That's 2 choices per email."
+));
+
+$cmp_num_1 = $num1->cmp;
+$cmp_den_1 = $den1->cmp;
+$cmp_num_2 = $num2->cmp;
+$cmp_den_2 = $den2->cmp;
+$cmp_prob_one = $prob_one->cmp;
+$cmp_count = $count->cmp;
+$cmp_final = $final->cmp;
+
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = eval { $student->value };
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ansHash->{score} = 1;
+ $ansHash->{ans_message} = "Thanks!";
+ } else {
+ $ansHash->{score} = 0;
+ $ansHash->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+ return $ansHash->{score};
+ }
+);
+
+# =======================================================
+# RadioButtons
+# =======================================================
+$rb_inE = RadioButtons(
+ ['SSFSS','SSSFF','FFFFS','SFFFF'],
+ 0, # Correct is SSSSF (Index 0)
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+$rb_equal = RadioButtons(
+ [ 'Yes, the likelyhood is the same, regardless of the number of successes', 'No, the likelyhood depends on the number of successes' ],
+ 1, # Correct is "No" (Index 1)
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin();
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+An email spam filter correctly flags spam with probability 0.95. You receive 5 spam emails.
+
+**Question:** What is the probability the filter flags exactly 4 of them?
+END_PGML
+Section::End();
+
+Section::Begin("Turn into Success and Failure Experiment");
+BEGIN_PGML
+We will turn this into an experiment where each trial consist of 5 independent emails. Each email can either be a **Success** or a **Failure**.
+
+- Let **S (Success)** mean: “the filter flags the email”
+- Let **F (Failure)** mean: “the filter does not flag the email”
+
+Then each outcome becomes a 5-letter string made of S’s and F’s, such as:
+
+- `SSSSF` or `FSSSS` (these have exactly 4 successes)
+- `SSSFF` or `FFFFS` (these do **not** have exactly 4 successes)
+
+Let event **E** be: “exactly 4 successes out of 5 emails.”
+
+**Checkpoint:** Which outcome belongs to event E (exactly 4 successes)?
+[_]{$rb_inE}
+END_PGML
+Section::End();
+
+Section::Begin("How many S/F outcomes exist?");
+BEGIN_PGML
+What is the total number of outcomes in the sample space regardless of the number of successes. Outcomes such as **SSSSF** or **SSSFF**?
+
+**Enter the number of S/F outcomes in the sample space:** [_]{$cmp_space}{10}
+END_PGML
+Section::End();
+
+Section::Begin("Are these S/F outcomes equally likely?");
+BEGIN_PGML
+**Checkpoint:** Are these [`2^5`] outcomes equally likely? For example are **SSSSF** and **SSSFF** equally likely?
+[_]{$rb_equal}
+END_PGML
+Section::End();
+
+# -----------------------
+Section::Begin("Additive rule for outcomes");
+BEGIN_PGML
+Because the S/F outcomes are **not** equally likely, we cannot just do:
+
+- “number of favorable outcomes divided by total outcomes.”
+
+Instead we use the **additive rule for outcomes**:
+
+- The probability of an event equals the sum of the probabilities of the outcomes in that event.
+
+So here:
+- Event E = “all S/F strings with exactly 4 S’s”
+- We need to add the probabilities of those favorable strings.
+END_PGML
+Section::End();
+
+
+Section::Begin("Use independence to compute two outcome probabilities");
+BEGIN_PGML
+The 5 emails are independent, so the probability of a specific S/F string is the product of the email probabilities.
+
+- \(P(S)=0.95\) use the fraction 19/20
+- \(P(F)=0.05\) use the fraction 1/20
+
+**1)** Compute [` P(SSSSF) `] (exactly 4 successes).
+Numerator: [_]{$cmp_num_1}{10} / Denominator: [_]{$cmp_den_1}{10}
+
+**2)** Compute [` P(FSSSS) `] (exactly 4 successes).
+Numerator: [_]{$cmp_num_2}{10} / Denominator: [_]{$cmp_den_2}{10}
+
+**Note:** [@ $hint_indep @]
+END_PGML
+Section::End();
+
+Section::Begin("Same probability for any 4S–1F string");
+BEGIN_PGML
+Any outcome with exactly **4 successes** and **1 failure** has the **same** probability. Enter this probability in the form [`(P(S))^4`] times [`(P(F))^1`]:
+
+**Enter this probability as a single expression:** [_]{$cmp_prob_one}{20}
+END_PGML
+Section::End();
+
+Section::Begin("Count favorable outcomes using the MISSISSIPPI idea");
+BEGIN_PGML
+Event E consists of all permutations of `SSSSF`. We know that all these permutations have the same probability. So we just need to use the `MISSISSIPPI` idea to figure out how many of all outcomes in the sample space consist exactly 4 S's and 1 F.
+
+**Enter the number of favorable outcomes in E:** [_]{$cmp_count}{10}
+END_PGML
+Section::End();
+
+Section::Begin("Final Answer");
+BEGIN_PGML
+At this point we know that there are 5 events in Event (E=“exactly 4 successes out of 5 emails.”). Each one have the same probability [`p=(0.95)^4(0.05)^1`]. Using **additive rule for outcomes** what is the probability of getting exactly 4 successes out of 5 emails?
+**Final Answer:** [_]{$cmp_final}{30}
+END_PGML
+Section::End();
+
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning combinations?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+BEGIN_PGML_SOLUTION
+The probability is:
+
+**1.** Use the binomial model with \(n=5\) and \(p=0.95\):
+\\(
+P(E)=\\binom{5}{4}\\left(\\dfrac{19}{20}\\right)^4\\left(\\dfrac{1}{20}\\right)^1
+\\).
+
+**2.** Simplify:
+\\(
+P(E)=5\\left(\\dfrac{19^4}{20^5}\\right)
+\\).
+
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem9.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem9.pg
new file mode 100644
index 0000000000..4396b41fe3
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_CalculateProbability_GuidedProblem9.pg
@@ -0,0 +1,297 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Birthday Problem (Complement Rule) (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Counting Methods)
+## Level(2)
+## KEYWORDS('birthday problem','complement rule','counting','permutations','probability')
+## Static(1)
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Context & Data
+# =======================================================
+Context("Numeric");
+Context()->flags->set(implicitMultiplication => 1);
+
+# Use Compute for better handling of formula inputs vs raw numbers
+$num = Compute("(365)(364)(363)(362)(361)");
+$den = Compute("365^5");
+$pAc = Compute("((365)(364)(363)(362)(361))/(365^5)");
+$pA = Compute("1 - ((365)(364)(363)(362)(361))/(365^5)");
+
+# Extra scenarios (rounded answers required)
+$pAc20_val = 1;
+for ($k=0; $k<20; $k++) { $pAc20_val *= (365-$k)/365; }
+$pA20_val = 1 - $pAc20_val;
+$pA20_round = sprintf("%.4f",$pA20_val);
+
+$pAc30_val = 1;
+for ($k=0; $k<30; $k++) { $pAc30_val *= (365-$k)/365; }
+$pA30_val = 1 - $pAc30_val;
+$pA30_round = sprintf("%.4f",$pA30_val);
+
+# =======================================================
+# Comparators
+# =======================================================
+$cmp_num = $num->cmp;
+$cmp_den = $den->cmp;
+$cmp_pAc = $pAc->cmp;
+$cmp_pA = $pA->cmp;
+
+# Rounded-to-4-decimals checkers
+$cmp_pA20 = Real($pA20_round)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = eval { $student->value };
+ if (!defined($v)) {
+ $ansHash->{score} = 0;
+ $ansHash->{ans_message} = "Enter a decimal number rounded to the nearest 10000th (4 digits after the decimal point).";
+ return 0;
+ }
+ my $s = sprintf("%.4f",$v);
+ if ($s eq $pA20_round) {
+ $ansHash->{score} = 1;
+ $ansHash->{ans_message} = "Correct!";
+ } else {
+ $ansHash->{score} = 0;
+ $ansHash->{ans_message} = "Round to the nearest 10000th (4 digits after the decimal point).";
+ }
+ return $ansHash->{score};
+ }
+);
+
+$cmp_pA30 = Real($pA30_round)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = eval { $student->value };
+ if (!defined($v)) {
+ $ansHash->{score} = 0;
+ $ansHash->{ans_message} = "Enter a decimal number rounded to the nearest 10000th (4 digits after the decimal point).";
+ return 0;
+ }
+ my $s = sprintf("%.4f",$v);
+ if ($s eq $pA30_round) {
+ $ansHash->{score} = 1;
+ $ansHash->{ans_message} = "Correct!";
+ } else {
+ $ansHash->{score} = 0;
+ $ansHash->{ans_message} = "Round to the nearest 10000th (4 digits after the decimal point).";
+ }
+ return $ansHash->{score};
+ }
+);
+
+# Rating Check
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = eval { $student->value };
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ansHash->{score} = 1;
+ $ansHash->{ans_message} = "Thanks!";
+ } else {
+ $ansHash->{score} = 0;
+ $ansHash->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+ return $ansHash->{score};
+ }
+);
+
+# =======================================================
+# RadioButtons
+# =======================================================
+$rb_comp = RadioButtons(
+ [
+ 'Exactly 2 people share a birthday',
+ 'At least 2 people share a birthday',
+ 'All 5 people have different birthdays',
+ 'All 5 people share the same birthday'
+ ],
+ 2, # correct is "All 5 people have different birthdays"
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+$rb_formula = RadioButtons(
+ [
+ 'P(A) = 1 + P(complement of A)',
+ 'P(A) = P(complement of A)',
+ 'P(A) = 1 - P(complement of A)',
+ 'P(A) = 1 / P(complement of A)'
+ ],
+ 2, # correct is "P(A) = 1 - P(complement of A)"
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin();
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+In a room of 5 people, what is the probability that at least 2 of them share a birthday?
+
+Assume:
+- 365 equally likely birthdays (ignore leap day)
+- birthdays are independent
+END_PGML
+Section::End();
+
+Section::Begin("Identify the complement event");
+BEGIN_PGML
+Let event **A** be: “At least 2 of the 5 people share a birthday.”
+
+**Checkpoint:** Which event is the complement of event A?
+
+[_]{$rb_comp}
+END_PGML
+Section::End();
+
+Section::Begin("Use the complement rule");
+BEGIN_PGML
+In this problem finding the probability of the complement event (All 5 people have different birthdays) is easier.
+
+**Checkpoint:** Which formula can used to find [`` P(A) ``] once we have [`` P(\text{complement of }A) ``]?
+
+[_]{$rb_formula}
+END_PGML
+Section::End();
+
+Section::Begin("Count the complement event");
+BEGIN_PGML
+We should use:
+[`` P(\text{complement of }A)=\dfrac{\text{number of ways 5 people can have different birthdays}}{\text{number of all possibilities regarding birthdays of 5 people}}. ``]
+
+**Numerator (two ways to understand it):**
+
+**Way 1 (direct counting):**
+Person 1 has 365 choices.
+Person 2 must avoid that birthday: 364 choices.
+Then 363, then 362, then 361.
+So the numerator is:
+[`` (365)(364)(363)(362)(361) ``]
+
+**Way 2 (permutations idea):**
+This is like first picking 5 days out of 365 and then multiplying that by:
+[`` 5! ``]
+This is equal to:
+[`` P(365,5) ``]
+and:
+[`` P(365,5)=(365)(364)(363)(362)(361) ``]
+
+**Enter the numerator:** [_]{$cmp_num}{25}
+
+**Denominator:**
+Each of the 5 people can have any of 365 birthdays, independently.
+So the denominator is:
+[`` 365^5 ``]
+
+**Enter the denominator:** [_]{$cmp_den}{15}
+END_PGML
+Section::End();
+
+Section::Begin("Compute P(complement of A) and P(A)");
+BEGIN_PGML
+Let [`` A^c ``] be the complement event.
+
+**1)** Compute [`` P(A^c) ``]:
+[_]{$cmp_pAc}{35}
+
+**2)** Compute [`` P(A) ``]:
+[_]{$cmp_pA}{35}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# NEW STEP: n = 20
+# -------------------------------------------------------
+Section::Begin("What if there are 20 people in the room?");
+BEGIN_PGML
+Now suppose there are [`` 20 ``] people in the room.
+
+Using the same complement idea, compute the probability that **at least 2** of them share a birthday.
+
+**Enter your final answer rounded to the nearest 10000th (4 digits after the decimal point):** [_]{$cmp_pA20}{10}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# NEW STEP: n = 30
+# -------------------------------------------------------
+Section::Begin("What if there are 30 people in the room?");
+BEGIN_PGML
+Now suppose there are [`` 30 ``] people in the room.
+
+Using the same complement idea, compute the probability that **at least 2** of them share a birthday.
+
+**Enter your final answer rounded to the nearest 10000th (4 digits after the decimal point):** [_]{$cmp_pA30}{10}
+
+**Note:** The birthday problem refers to the counterintuitive fact that only 30 people are needed for that probability to exceed 70%. So there is a high chance, that in your statistics class of about 30, at least 2 students share a birthday.
+END_PGML
+Section::End();
+
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning combinations?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+BEGIN_PGML_SOLUTION
+The probability is:
+
+**1.** Let [`` A ``] be the event “at least 2 people share a birthday.”
+Then [`` A^c ``] is “all 5 birthdays are different.”
+
+**2.** Count outcomes.
+
+- Total outcomes: [`` 365^5 ``]
+- Favorable outcomes for [`` A^c ``]: [`` (365)(364)(363)(362)(361) ``]
+
+So,
+[`` P(A^c)=\dfrac{(365)(364)(363)(362)(361)}{365^5}. ``]
+
+**3.** Use the complement rule:
+[`` P(A)=1-P(A^c)=1-\dfrac{(365)(364)(363)(362)(361)}{365^5}. ``]
+
+**4.** Extra scenarios:
+
+For [`` 20 ``] people, the rounded answer is:
+[`` P(A)\approx 0.4114 ``]
+
+For [`` 30 ``] people, the rounded answer is:
+[`` P(A)\approx 0.7063 ``]
+
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_Combinations_GuidedProblem1.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_Combinations_GuidedProblem1.pg
new file mode 100644
index 0000000000..f5c00a5329
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_Combinations_GuidedProblem1.pg
@@ -0,0 +1,182 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Combinations: Group of 3 from 10 (nCr) (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Combinatorics)
+## DBsection(Combinations)
+## Level(1)
+## KEYWORDS('combination','nCr','order does not matter','group','binomial coefficient','factorial','overcounting')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data
+# =======================================================
+Context("Numeric");
+
+$n = 10;
+$r = 3;
+
+$stage1 = $n; # first pick (if order mattered)
+$stage2 = $n - 1; # second pick
+$stage3 = $n - 2; # third pick
+
+$P_n_r = $stage1 * $stage2 * $stage3; # 10*9*8 = 720
+$r_fact = 6; # 3! = 6
+$C_n_r = $P_n_r / $r_fact; # 120
+
+$val_stage1 = Real($stage1);
+$val_stage2 = Real($stage2);
+$val_stage3 = Real($stage3);
+$val_perm = Real($P_n_r);
+$val_rfact = Real($r_fact);
+$val_final = Real($C_n_r);
+
+# =======================================================
+# Precompute evaluators (LB-friendly)
+# =======================================================
+$cmp_stage1 = $val_stage1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-9) < 0.5 } => "The first pick is made before anyone is chosen, so you start with all 10 students.",
+));
+
+$cmp_stage2 = $val_stage2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-10) < 0.5 } => "After the first student is chosen, there is one fewer student available.",
+ sub { abs($_[0]-8) < 0.5 } => "This is the second stage: only one student has been used so far.",
+));
+
+$cmp_stage3 = $val_stage3->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-9) < 0.5 } => "This is the third stage: two students have already been used.",
+));
+
+$cmp_perm = $val_perm->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-($stage1+$stage2+$stage3)) < 0.5 } => "It looks like you added instead of multiplying.",
+ sub { abs($_[0]-1000) < 0.5 } => "1000 is \(10^3\). That would allow repeats. Here, you cannot pick the same student twice.",
+));
+
+$cmp_rfact = $val_rfact->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-3) < 0.5 } => "That is not \(3!\). Factorial means multiply: \(3!=3\cdot2\cdot1\).",
+ sub { abs($_[0]-2) < 0.5 } => "You may have used only \(2!\). For 3 chosen students, the number of orders is \(3!\).",
+));
+
+$cmp_final = $val_final->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-$P_n_r) < 0.5 } => "That counts ordered selections (permutations). A group ignores order, so you must divide by \(3!\).",
+ sub { abs($_[0]-60) < 0.5 } => "60 suggests dividing by 12. For a group of 3, the overcount factor is \(3!\), not 12.",
+ sub { abs($_[0]-1000) < 0.5 } => "1000 is \(10^3\). That allows repeats and order. For a group: no repeats, and order does not matter.",
+));
+
+$cmp_rating = Real(3)->cmp(checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return ($v == int($v) && $v >= 1 && $v <= 5);
+ })->withPostFilter(AnswerHints(
+ sub { $_[0] < 1 || $_[0] > 5 } => "Please enter an integer from 1 to 5.",
+ sub { $_[0] != int($_[0]) } => "Please enter a whole number (integer) from 1 to 5.",
+ ));
+
+# =======================================================
+# Guided flow (Scaffold)
+# =======================================================
+Scaffold::Begin();
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A class has **10 students**.
+
+In how many different ways can we form a **group of 3 students**?
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Count as if order matters (temporary step)");
+BEGIN_PGML
+First, count as if the group was chosen in **stages** (like an ordered list):
+
+- pick a **first** student,
+- then pick a **second** student from the remaining,
+- then pick a **third** student from the remaining.
+
+Fill in the number of choices at each stage:
+
+Stage 1: [____]{$cmp_stage1}
+
+Stage 2: [____]{$cmp_stage2}
+
+Stage 3: [____]{$cmp_stage3}
+
+Now multiply (Multiplication Principle):
+
+Ordered count = (stage 1)(stage 2)(stage 3) = [__________]{$cmp_perm}
+
+Note: This is an over-count of the number of groups of 3 one can make out of 10 students. Because order does not matter in a group.
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Combination (definition and formula)");
+BEGIN_PGML
+A **combination** is a selection where **order does not matter**.
+
+But the previous step counted *orders*.
+For example, choosing (Alex, Ben, Chloe) and (Ben, Chloe, Alex) is the **same group** of 3 students.
+
+How many different orders (permutations) can the same 3-student group have?
+
+That number is [`3!`].
+
+Compute [`3!`]: [____]{$cmp_rfact}
+
+So the combination count is:
+
+[`` C(10,3)=\dfrac{P(10,3)}{3!}=\dfrac{10!}{(3!)(7!)}. ``]
+
+Compute [`C(10,3)`]: [__________]{$cmp_final}
+
+In general, the number of combinations of **n** distinct objects taken **r** at a time is:
+[`` C(n,r)=\binom{n}{r}=\dfrac{n!}{r!(n-r)!}. ``]
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning combinations?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_Combinations_GuidedProblem2.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_Combinations_GuidedProblem2.pg
new file mode 100644
index 0000000000..e44942c5ce
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_Combinations_GuidedProblem2.pg
@@ -0,0 +1,207 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Combinations: 5-Card Hand from a 52-Card Deck (nCr) (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Combinatorics)
+## DBsection(Combinations)
+## Level(2)
+## KEYWORDS('combination','nCr','order does not matter','cards','5-card hand','binomial coefficient','factorial','overcounting')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data (keep everything ASCII + LB-friendly)
+# =======================================================
+Context("Numeric");
+
+$n = 52;
+$r = 5;
+
+$stage1 = $n;
+$stage2 = $n - 1;
+$stage3 = $n - 2;
+$stage4 = $n - 3;
+$stage5 = $n - 4;
+
+# Ordered count P(52,5)
+$P_n_r = $stage1 * $stage2 * $stage3 * $stage4 * $stage5; # 52*51*50*49*48
+
+# Overcount factor 5!
+$r_fact = 120;
+
+# Combination count C(52,5)
+$C_n_r = int($P_n_r / $r_fact + 0.5); # 2598960 (force integer)
+
+# For a common wrong idea: 52^5 (repeats allowed)
+$pow_nr = $n**$r;
+
+$val_stage1 = Real($stage1);
+$val_stage2 = Real($stage2);
+$val_stage3 = Real($stage3);
+$val_stage4 = Real($stage4);
+$val_stage5 = Real($stage5);
+$val_perm = Real($P_n_r);
+$val_rfact = Real($r_fact);
+$val_final = Real($C_n_r);
+
+# =======================================================
+# Precompute evaluators (LB-friendly)
+# =======================================================
+$cmp_stage1 = $val_stage1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-51) < 0.5 } => "This is the first card. Nothing has been removed yet, so you start with all 52 cards.",
+));
+
+$cmp_stage2 = $val_stage2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-52) < 0.5 } => "After the first card is drawn, there is one fewer card available.",
+ sub { abs($_[0]-50) < 0.5 } => "This is the second draw. Only one card has been drawn so far.",
+));
+
+$cmp_stage3 = $val_stage3->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-51) < 0.5 } => "This is the third draw. Two cards have already been drawn.",
+));
+
+$cmp_stage4 = $val_stage4->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-50) < 0.5 } => "This is the fourth draw. Three cards have already been drawn.",
+));
+
+$cmp_stage5 = $val_stage5->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-49) < 0.5 } => "This is the fifth draw. Four cards have already been drawn.",
+));
+
+$cmp_perm = $val_perm->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-($stage1+$stage2+$stage3+$stage4+$stage5)) < 0.5 } => "It looks like you added instead of multiplying.",
+ sub { abs($_[0]-$pow_nr) < 1 } => "That looks like \(52^5\). That would allow repeats. Here, once a card is drawn, it is not available again.",
+));
+
+$cmp_rfact = $val_rfact->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-5) < 0.5 } => "That is not \(5!\). Factorial means multiply: \(5!=5\cdot4\cdot3\cdot2\cdot1\).",
+ sub { abs($_[0]-24) < 0.5 } => "24 is \(4!\). For a 5-card hand, the number of orders is \(5!\).",
+ sub { abs($_[0]-60) < 0.5 } => "60 is missing a factor of 2. Check \(5\cdot4\cdot3\cdot2\cdot1\).",
+));
+
+$cmp_final = $val_final->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-$P_n_r) < 0.5 } => "That counts ordered draws (permutations). A 5-card hand ignores order, so you must divide by \(5!\).",
+ sub { abs($_[0]-int($P_n_r/5 + 0.5)) < 1 } => "Dividing by 5 is not enough. You must divide by \(5!\), because there are \(5!\) orders of the same 5 cards.",
+ sub { abs($_[0]-$pow_nr) < 1 } => "That looks like \(52^5\), which allows repeats and order. For a hand: no repeats, and order does not matter.",
+));
+
+$cmp_rating = Real(3)->cmp(checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return ($v == int($v) && $v >= 1 && $v <= 5);
+ })->withPostFilter(AnswerHints(
+ sub { $_[0] < 1 || $_[0] > 5 } => "Please enter an integer from 1 to 5.",
+ sub { $_[0] != int($_[0]) } => "Please enter a whole number (integer) from 1 to 5.",
+ ));
+
+# =======================================================
+# Guided flow (Scaffold)
+# =======================================================
+Scaffold::Begin();
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A standard deck has **52 distinct cards**.
+
+In how many different ways can you form a **5-card hand** (where order does not matter)?
+END_PGML
+Section::End();
+
+Section::Begin("Count as if order matters (temporary step)");
+BEGIN_PGML
+First, count as if the 5 cards were drawn in **stages** (like an ordered list):
+
+- draw a **first** card,
+- then a **second** card from the remaining,
+- then a **third**,
+- then a **fourth**,
+- then a **fifth**.
+
+Fill in the number of choices at each stage:
+
+Stage 1: [____]{$cmp_stage1}
+
+Stage 2: [____]{$cmp_stage2}
+
+Stage 3: [____]{$cmp_stage3}
+
+Stage 4: [____]{$cmp_stage4}
+
+Stage 5: [____]{$cmp_stage5}
+
+Now multiply (Multiplication Principle):
+
+Ordered count = (stage 1)(stage 2)(stage 3)(stage 4)(stage 5) = [__________]{$cmp_perm}
+
+Note: This is an over-count of the number of 5-card hands one can make out of 52 cards. Because order does not matter in a hand.
+END_PGML
+Section::End();
+
+Section::Begin("Combination (definition and formula)");
+BEGIN_PGML
+A **combination** is a selection where **order does not matter**.
+
+But the previous step counted *orders*.
+For the same 5 cards, different draw orders are counted as different outcomes.
+
+How many different orders (permutations) can the same 5-card hand have?
+
+That number is [`5!`].
+
+Compute [`5!`]: [____]{$cmp_rfact}
+
+So the combination count is:
+
+[`` C(52,5)=\dfrac{P(52,5)}{5!}=\dfrac{52!}{(5!)(47!)}. ``]
+
+Compute [`C(52,5)`]: [__________]{$cmp_final}
+
+In general, the number of combinations of **n** distinct objects taken **r** at a time is:
+[`` C(n,r)=\binom{n}{r}=\dfrac{n!}{r!(n-r)!}. ``]
+END_PGML
+Section::End();
+
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning combinations?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_Combinations_GuidedProblem3.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_Combinations_GuidedProblem3.pg
new file mode 100644
index 0000000000..fa3a6c9b5c
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_Combinations_GuidedProblem3.pg
@@ -0,0 +1,207 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Combinations: Team of 5 from 8 Players (nCr) (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Combinatorics)
+## DBsection(Combinations)
+## Level(1)
+## KEYWORDS('combination','nCr','order does not matter','team','binomial coefficient','factorial','overcounting')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data (keep everything ASCII + LB-friendly)
+# =======================================================
+Context("Numeric");
+
+$n = 8;
+$r = 5;
+
+$stage1 = $n;
+$stage2 = $n - 1;
+$stage3 = $n - 2;
+$stage4 = $n - 3;
+$stage5 = $n - 4;
+
+# Ordered count P(8,5)
+$P_n_r = $stage1 * $stage2 * $stage3 * $stage4 * $stage5; # 8*7*6*5*4
+
+# Overcount factor 5!
+$r_fact = 120;
+
+# Combination count C(8,5)
+$C_n_r = int($P_n_r / $r_fact + 0.5); # 56 (force integer)
+
+# Common wrong idea: 8^5 (repeats allowed)
+$pow_nr = $n**$r;
+
+$val_stage1 = Real($stage1);
+$val_stage2 = Real($stage2);
+$val_stage3 = Real($stage3);
+$val_stage4 = Real($stage4);
+$val_stage5 = Real($stage5);
+$val_perm = Real($P_n_r);
+$val_rfact = Real($r_fact);
+$val_final = Real($C_n_r);
+
+# =======================================================
+# Precompute evaluators (LB-friendly)
+# =======================================================
+$cmp_stage1 = $val_stage1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-7) < 0.5 } => "This is the first pick. Nobody has been chosen yet, so you start with all 8 players.",
+));
+
+$cmp_stage2 = $val_stage2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-8) < 0.5 } => "After the first player is chosen, there is one fewer player available.",
+ sub { abs($_[0]-6) < 0.5 } => "This is the second stage: only one player has been used so far.",
+));
+
+$cmp_stage3 = $val_stage3->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-7) < 0.5 } => "This is the third stage: two players have already been used.",
+));
+
+$cmp_stage4 = $val_stage4->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-6) < 0.5 } => "This is the fourth stage: three players have already been used.",
+));
+
+$cmp_stage5 = $val_stage5->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-5) < 0.5 } => "This is the fifth stage: four players have already been used.",
+));
+
+$cmp_perm = $val_perm->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-($stage1+$stage2+$stage3+$stage4+$stage5)) < 0.5 } => "It looks like you added instead of multiplying.",
+ sub { abs($_[0]-$pow_nr) < 1 } => "That looks like \(8^5\). That would allow repeats. Here, once a player is chosen, they cannot be chosen again.",
+));
+
+$cmp_rfact = $val_rfact->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-5) < 0.5 } => "That is not \(5!\). Factorial means multiply: \(5!=5\cdot4\cdot3\cdot2\cdot1\).",
+ sub { abs($_[0]-24) < 0.5 } => "24 is \(4!\). For a 5-player team, the number of orders is \(5!\).",
+ sub { abs($_[0]-60) < 0.5 } => "60 is missing a factor of 2. Check \(5\cdot4\cdot3\cdot2\cdot1\).",
+));
+
+$cmp_final = $val_final->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-$P_n_r) < 0.5 } => "That counts ordered selections (permutations). A team ignores order, so you must divide by \(5!\).",
+ sub { abs($_[0]-int($P_n_r/5 + 0.5)) < 1 } => "Dividing by 5 is not enough. You must divide by \(5!\), because there are \(5!\) orders of the same 5 players.",
+ sub { abs($_[0]-$pow_nr) < 1 } => "That looks like \(8^5\), which allows repeats and order. For a team: no repeats, and order does not matter.",
+));
+
+$cmp_rating = Real(3)->cmp(checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return ($v == int($v) && $v >= 1 && $v <= 5);
+ })->withPostFilter(AnswerHints(
+ sub { $_[0] < 1 || $_[0] > 5 } => "Please enter an integer from 1 to 5.",
+ sub { $_[0] != int($_[0]) } => "Please enter a whole number (integer) from 1 to 5.",
+ ));
+
+# =======================================================
+# Guided flow (Scaffold)
+# =======================================================
+Scaffold::Begin();
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A basketball roster has **8 players**.
+
+How many different **teams of 5** can be formed (where order does not matter)?
+END_PGML
+Section::End();
+
+Section::Begin("Count as if order matters (temporary step)");
+BEGIN_PGML
+First, count as if the 5 players were chosen in **stages** (like an ordered list):
+
+- pick a **first** player,
+- then a **second** player from the remaining,
+- then a **third**,
+- then a **fourth**,
+- then a **fifth**.
+
+Fill in the number of choices at each stage:
+
+Stage 1: [____]{$cmp_stage1}
+
+Stage 2: [____]{$cmp_stage2}
+
+Stage 3: [____]{$cmp_stage3}
+
+Stage 4: [____]{$cmp_stage4}
+
+Stage 5: [____]{$cmp_stage5}
+
+Now multiply (Multiplication Principle):
+
+Ordered count = (stage 1)(stage 2)(stage 3)(stage 4)(stage 5) = [__________]{$cmp_perm}
+
+Note: This is an over-count of the number of teams of 5 one can make out of 8 players. Because order does not matter in a team.
+END_PGML
+Section::End();
+
+Section::Begin("Combination (definition and formula)");
+BEGIN_PGML
+A **combination** is a selection where **order does not matter**.
+
+But the previous step counted *orders*.
+For the same 5 players, different selection orders were counted as different outcomes.
+
+How many different orders (permutations) can the same 5-player team have?
+
+That number is [`5!`].
+
+Compute [`5!`]: [____]{$cmp_rfact}
+
+So the combination count is:
+
+[`` C(8,5)=\dfrac{P(8,5)}{5!}=\dfrac{8!}{(5!)(3!)}. ``]
+
+Compute [`C(8,5)`]: [__________]{$cmp_final}
+
+In general, the number of combinations of **n** distinct objects taken **r** at a time is:
+[`` C(n,r)=\binom{n}{r}=\dfrac{n!}{r!(n-r)!}. ``]
+END_PGML
+Section::End();
+
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning combinations?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_Factorial_GuidedProblem1.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_Factorial_GuidedProblem1.pg
new file mode 100644
index 0000000000..77fb015c56
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_Factorial_GuidedProblem1.pg
@@ -0,0 +1,209 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Factorials (Example 3) (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Combinatorics)
+## DBsection(Factorials)
+## Level(1)
+## KEYWORDS('factorial','cancellation','simplify','combinatorics')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data / answers
+# =======================================================
+Context("Numeric");
+
+# Step 2 (blank checks)
+$val_6_to_5 = Real(5); # 6! = 6(5)!
+$val_12_to_11 = Real(11); # 12! = 12(11)!
+$val_8_to_6 = Real(6); # 8! = 8*7*(6)!
+$val_10_to_8 = Real(8); # 10! = 10*9*(8)!
+
+# Parts
+$val_part1 = Real(720); # 6!
+$val_part2 = Real(10); # 10!/9!
+$val_part3 = Real(720); # 10!/7!
+$val_part4 = Real(77520); # 20!/(13!7!)
+
+# =======================================================
+# Guided flow (Scaffold)
+# =======================================================
+Scaffold::Begin();
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+Compute each quantity:
+
+1) [`6!`]
+
+2) [`\dfrac{10!}{9!}`]
+
+3) [`\dfrac{10!}{7!}`]
+
+4) [`\dfrac{20!}{(13!)(7!)}`]
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Definition of factorial");
+BEGIN_PGML
+For a natural number [`n`]:
+
+[`` n! = n(n-1)(n-2)\cdots(2)(1), \qquad 0! = 1. ``]
+
+Two useful shortcut identities are:
+
+[`` n! = n(n-1)!, \qquad n! = n(n-1)(n-2)!. ``]
+
+**Checkpoint (fill in the missing number):**
+
+Using [`n! = n(n-1)!`]
+
+- [`6! = 6(k)!`] so [`k =`] [____]{$val_6_to_5->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Factorial indices are not negative.",
+ sub { abs($_[0]-6) < 0.0008 } => "Careful: it should drop by 1 (use n-1).",
+))}
+
+- [`12! = 12(k)!`] so [`k =`] [____]{$val_12_to_11->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Factorial indices are not negative.",
+ sub { abs($_[0]-12) < 0.0008 } => "Careful: it should drop by 1 (use n-1).",
+))}
+
+Using [`n! = n(n-1)(n-2)!`]
+
+- [`8! = 8\cdot 7\cdot (k)!`] so [`k =`] [____]{$val_8_to_6->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Factorial indices are not negative.",
+ sub { abs($_[0]-7) < 0.0008 } => "Careful: it should drop by 2 (use n-2).",
+))}
+
+- [`10! = 10\cdot 9\cdot (k)!`] so [`k =`] [____]{$val_10_to_8->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Factorial indices are not negative.",
+ sub { abs($_[0]-9) < 0.0008 } => "Careful: it should drop by 2 (use n-2).",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Part 1: Compute 6!");
+BEGIN_PGML
+Start from the definition:
+
+[`` 6! = 6\cdot 5\cdot 4\cdot 3\cdot 2\cdot 1. ``]
+
+Final answer: [__________]{$val_part1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A factorial value cannot be negative.",
+ sub { abs($_[0]-120) < 0.5 } => "That is 5!, not 6!.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Part 2: Compute 10!/9!");
+BEGIN_PGML
+Show the cancellation *before* cancelling:
+
+[`` \dfrac{10!}{9!} = \dfrac{10\cdot 9!}{9!}. ``]
+
+Now the factor [`9!`] cancels, leaving:
+
+[`` \dfrac{10!}{9!} = 10. ``]
+
+Final answer: [__________]{$val_part2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "This value cannot be negative.",
+ sub { abs($_[0]-1) < 0.0008 } => "If you got 1, you cancelled the 10 by mistake. Only 9! cancels.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Part 3: Compute 10!/7!");
+BEGIN_PGML
+Show the cancellation *before* cancelling:
+
+[`` \dfrac{10!}{7!} = \dfrac{10\cdot 9\cdot 8\cdot 7!}{7!}. ``]
+
+Now the factor [`7!`] cancels, leaving:
+
+[`` \dfrac{10!}{7!} = 10\cdot 9\cdot 8. ``]
+
+Final answer: [__________]{$val_part3->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "This value cannot be negative.",
+ sub { abs($_[0]-10) < 0.5 } => "After cancelling, you still must multiply 10·9·8.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Part 4: Compute 20!/((13!)(7!))");
+BEGIN_PGML
+Rewrite [`20!`] to expose a [`13!`] factor:
+
+[`` 20! = 20\cdot 19\cdot 18\cdot 17\cdot 16\cdot 15\cdot 14\cdot 13!. ``]
+
+Substitute *before* cancelling:
+
+[`` \dfrac{20!}{(13!)(7!)} =
+\dfrac{20\cdot 19\cdot 18\cdot 17\cdot 16\cdot 15\cdot 14\cdot 13!}{(13!)(7!)}. ``]
+
+Now cancel the common factor [`13!`]:
+
+[`` \dfrac{20!}{(13!)(7!)} =
+\dfrac{20\cdot 19\cdot 18\cdot 17\cdot 16\cdot 15\cdot 14}{7!}. ``]
+
+And remember:
+
+[`` 7! = 7\cdot 6\cdot 5\cdot 4\cdot 3\cdot 2\cdot 1. ``]
+
+Final answer: [__________]{$val_part4->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "This value cannot be negative.",
+ sub { abs($_[0]-1) < 0.0008 } => "If you got 1, something cancelled incorrectly: the numerator is much larger than the denominator.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for practicing factorials and cancellation?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{Real(3)->cmp(checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return ($v == int($v) && $v >= 1 && $v <= 5);
+ })->withPostFilter(AnswerHints(
+ sub { $_[0] < 1 || $_[0] > 5 } => "Please enter an integer from 1 to 5.",
+ sub { $_[0] != int($_[0]) } => "Please enter a whole number (integer) from 1 to 5.",
+ ))}
+ END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_MultiplicationPrinciple_GuidedProblem1.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_MultiplicationPrinciple_GuidedProblem1.pg
new file mode 100644
index 0000000000..f90367dc88
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_MultiplicationPrinciple_GuidedProblem1.pg
@@ -0,0 +1,126 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Combinatorics: Multiplication Principle (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Combinatorics)
+## DBsection(Multiplication Principle)
+## Level(1)
+## KEYWORDS('multiplication principle','fundamental counting principle','counting','combinatorics','pizza choices')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data
+# =======================================================
+Context("Numeric");
+
+$bread = 3;
+$topping = 5;
+$cheese = 2;
+
+$total = $bread * $topping * $cheese;
+
+$val_bread = Real($bread);
+$val_topping = Real($topping);
+$val_cheese = Real($cheese);
+$val_total = Real($total);
+
+# =======================================================
+# Guided flow (Scaffold)
+# =======================================================
+Scaffold::Begin();
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A pizzeria lets you choose:
+- One out of **3** types of bread
+- One out of **5** toppings
+- One out of **2** types of cheese
+
+How many different pizzas can you order?
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Multiplication Principle");
+BEGIN_PGML
+The Multiplication Principle is the intuitive idea that if there are **m** ways of doing some action and there are **n** ways of doing another action, then there are **mn** ways of performing both actions.
+
+In this problem:
+- You make **one bread choice**, **one topping choice**, **one cheese choice**.
+- Each complete pizza corresponds to one “path” through these choices.
+- Because choices are made in stages, we multiply the number of options.
+
+**Checkpoint:** Fill in the multiplication expression:
+
+Total pizzas = ( [____]{$val_bread->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] == $topping } => "That is the number of toppings. This blank is for bread choices.",
+ sub { $_[0] == $cheese } => "That is the number of cheese choices. This blank is for bread choices.",
+))} )( [____]{$val_topping->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] == $bread } => "That is the number of bread choices. This blank is for toppings.",
+ sub { $_[0] == $cheese } => "That is the number of cheese choices. This blank is for toppings.",
+))} )( [____]{$val_cheese->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] == $bread } => "That is the number of bread choices. This blank is for cheese.",
+ sub { $_[0] == $topping } => "That is the number of toppings. This blank is for cheese.",
+))} )
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Final Answer");
+BEGIN_PGML
+Now compute the total number of different pizzas:
+
+[__________]{$val_total->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { $_[0] == $bread + $topping + $cheese } =>
+ "That looks like you added. Here we multiply because choices are made in stages.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning the Multiplication Principle?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{Real(3)->cmp(checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return ($v == int($v) && $v >= 1 && $v <= 5);
+ })->withPostFilter(AnswerHints(
+ sub { $_[0] < 1 || $_[0] > 5 } => "Please enter an integer from 1 to 5.",
+ sub { $_[0] != int($_[0]) } => "Please enter a whole number (integer) from 1 to 5.",
+ ))}
+ END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_MultiplicationPrinciple_GuidedProblem2.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_MultiplicationPrinciple_GuidedProblem2.pg
new file mode 100644
index 0000000000..739db592af
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_MultiplicationPrinciple_GuidedProblem2.pg
@@ -0,0 +1,166 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Combinatorics: Permutations as a Product (5-person Line) (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Combinatorics)
+## DBsection(Permutations)
+## Level(1)
+## KEYWORDS('multiplication principle','permutations','factorial','line up','queue')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data
+# =======================================================
+Context("Numeric");
+
+$n = 5;
+$ans = 120; # 5! = 120
+
+$val1 = Real(5);
+$val2 = Real(4);
+$val3 = Real(3);
+$val4 = Real(2);
+$val5 = Real(1);
+
+$val_ans = Real($ans);
+
+# =======================================================
+# MC: notation for the answer (correct = 5!)
+# Use MathJax delimiters \( \) inside option strings.
+# =======================================================
+$rb_notation = RadioButtons(
+ [
+ '\(5^5\)',
+ '\(5!\)',
+ '\(5 + 4 + 3 + 2 + 1\)',
+ '\(\binom{5}{2}\)',
+ '\(5/5\)',
+ ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Guided flow (Scaffold)
+# =======================================================
+Scaffold::Begin();
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+Five people walk into a bank and want to form a single line.
+
+How many different lineups (orders) are possible?
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Count the options for each position");
+BEGIN_PGML
+Work position by position.
+
+How many choices do we have for:
+
+First position: [____]{$val1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] == 4 } => "Not yet. At the first position, all 5 people are available.",
+))}
+
+Second position: [____]{$val2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] == 5 } => "After the first position is filled, one person is already used up.",
+ sub { $_[0] == 3 } => "Too small. Only one person has been used up after the first position.",
+))}
+
+Third position: [____]{$val3->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] == 4 } => "After the first two positions are filled, two people are already used up.",
+ sub { $_[0] == 2 } => "Too small. After two positions, 3 people remain, not 2.",
+))}
+
+Fourth position: [____]{$val4->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] == 3 } => "After three positions are filled, two people remain.",
+))}
+
+Last position: [____]{$val5->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] == 2 } => "After four positions are filled, only one person remains.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Why multiplication?");
+BEGIN_PGML
+Why should we use the Multiplication Principle here?
+
+Because forming a lineup happens in **stages**:
+- choose who goes in the first spot,
+- then choose who goes in the second spot,
+- then the third, and so on.
+
+Each full lineup corresponds to one “path” through these choices, so we multiply the number of options from each stage.
+
+**Notation checkpoint:** Which notation can be used to express the number of lineups?
+
+[@ $rb_notation->buttons() @]*
+END_PGML
+ANS($rb_notation->cmp);
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Final Answer");
+BEGIN_PGML
+Now multiply your answers from Step 2 to get the total number of different lineups.
+
+[__________]{$val_ans->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { $_[0] == 15 } => "That looks like you added 5+4+3+2+1. Here we multiply.",
+ sub { $_[0] == 25 } => "That looks like \(5^2\). For a lineup, the number of choices decreases each position.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning factorials and lineups?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{Real(3)->cmp(checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return ($v == int($v) && $v >= 1 && $v <= 5);
+ })->withPostFilter(AnswerHints(
+ sub { $_[0] < 1 || $_[0] > 5 } => "Please enter an integer from 1 to 5.",
+ sub { $_[0] != int($_[0]) } => "Please enter a whole number (integer) from 1 to 5.",
+ ))}
+ END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_MultiplicationPrinciple_GuidedProblem3.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_MultiplicationPrinciple_GuidedProblem3.pg
new file mode 100644
index 0000000000..3260ce76da
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_MultiplicationPrinciple_GuidedProblem3.pg
@@ -0,0 +1,261 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — 4-Digit PIN Codes (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Combinatorics)
+## DBsection(Multiplication Principle)
+## Level(1)
+## KEYWORDS('multiplication principle','counting','PIN','repetition','leading zero')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data
+# =======================================================
+Context("Numeric");
+
+# (a) no limitation
+$a1 = 10; $a2 = 10; $a3 = 10; $a4 = 10; $aP = $a1*$a2*$a3*$a4; # 10000
+
+# (b) no repetition (leading zero allowed)
+$b1 = 10; $b2 = 9; $b3 = 8; $b4 = 7; $bP = $b1*$b2*$b3*$b4; # 5040
+
+# (c) first digit not zero (repetition allowed)
+$c1 = 9; $c2 = 10; $c3 = 10; $c4 = 10; $cP = $c1*$c2*$c3*$c4; # 9000
+
+# (d) first digit not zero AND no repetition
+$d1 = 9; $d2 = 9; $d3 = 8; $d4 = 7; $dP = $d1*$d2*$d3*$d4; # 4536
+
+# MathObjects
+$val_a1 = Real($a1); $val_a2 = Real($a2); $val_a3 = Real($a3); $val_a4 = Real($a4); $val_aP = Real($aP);
+$val_b1 = Real($b1); $val_b2 = Real($b2); $val_b3 = Real($b3); $val_b4 = Real($b4); $val_bP = Real($bP);
+$val_c1 = Real($c1); $val_c2 = Real($c2); $val_c3 = Real($c3); $val_c4 = Real($c4); $val_cP = Real($cP);
+$val_d1 = Real($d1); $val_d2 = Real($d2); $val_d3 = Real($d3); $val_d4 = Real($d4); $val_dP = Real($dP);
+
+# Common wrong answers
+$wrong_add_a = 10+10+10+10; # 40
+$wrong_9pow4 = 9**4; # 6561
+
+# =======================================================
+# Step 2 MC: Why multiplication?
+# (Correct option is C; looks randomized.)
+# =======================================================
+$rb_why_mult = RadioButtons(
+ [
+ "Because we are adding the options for each digit.",
+ "Because digits must be in increasing order.",
+ "Because we are choosing digits one stage at a time (1st, 2nd, 3rd, 4th), and each full PIN is one path through these choices.",
+ "Because there is only one PIN once the first digit is chosen.",
+ "Because multiplication is always used in every counting problem.",
+ ],
+ 2,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Guided flow (Scaffold)
+# =======================================================
+Scaffold::Begin();
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A 4-digit numerical PIN uses digits 0 through 9.
+
+Find the number of possible PINs:
+
+a) If there is no limitation.
+b) If we want to avoid repetition (no digit can appear twice).
+c) If the first digit cannot be zero.
+d) If the first digit cannot be zero and no repetition is allowed.
+
+In each part, you must write the number of options for each digit (stage 1 to stage 4), then write the product.
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Why multiplication?");
+BEGIN_PGML
+Why should we use the Multiplication Principle here?
+
+[@ $rb_why_mult->buttons() @]*
+END_PGML
+ANS($rb_why_mult->cmp);
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Part (a): No limitation");
+BEGIN_PGML
+a) No limitation (digits 0-9 allowed, repetition allowed).
+
+1st digit options: [____]{$val_a1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-9) < 0.0008 } => "In part (a), 0 is allowed, so there are 10 options.",
+))}
+
+2nd digit options: [____]{$val_a2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-9) < 0.0008 } => "Repetition is allowed in part (a), so there are still 10 options.",
+))}
+
+3rd digit options: [____]{$val_a3->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+))}
+
+4th digit options: [____]{$val_a4->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+))}
+
+Product (total PINs): [__________]{$val_aP->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-$wrong_add_a) < 0.5 } => "That looks like you added. Here we multiply the stage counts.",
+ sub { abs($_[0]-1000) < 0.5 } => "That would be for 3 digits. This is 4 digits.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Part (b): Avoid repetition");
+BEGIN_PGML
+b) Avoid repetition (once a digit is used, it cannot be used again). Leading zero is allowed.
+
+1st digit options: [____]{$val_b1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-9) < 0.0008 } => "Leading zero is allowed here, so the first digit has 10 options.",
+))}
+
+2nd digit options: [____]{$val_b2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-10) < 0.0008 } => "No repetition: after choosing the first digit, only 9 digits remain.",
+))}
+
+3rd digit options: [____]{$val_b3->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-9) < 0.0008 } => "After two digits are used, 8 digits remain.",
+))}
+
+4th digit options: [____]{$val_b4->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-8) < 0.0008 } => "After three digits are used, 7 digits remain.",
+))}
+
+Product (total PINs): [__________]{$val_bP->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-$aP) < 0.5 } => "That is part (a) with repetition allowed. Here the stage counts decrease.",
+ sub { abs($_[0]-$wrong_add_a) < 0.5 } => "That looks like you added. Here we multiply the stage counts.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Part (c): First digit cannot be zero");
+BEGIN_PGML
+c) First digit cannot be zero (repetition is allowed).
+
+1st digit options: [____]{$val_c1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-10) < 0.0008 } => "First digit cannot be zero, so there are 9 options (1-9).",
+))}
+
+2nd digit options: [____]{$val_c2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-9) < 0.0008 } => "Only the first digit is restricted. The second digit has 10 options (0-9).",
+))}
+
+3rd digit options: [____]{$val_c3->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+))}
+
+4th digit options: [____]{$val_c4->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+))}
+
+Product (total PINs): [__________]{$val_cP->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-$aP) < 0.5 } => "That would allow the first digit to be zero. Here the first stage is 9, not 10.",
+ sub { abs($_[0]-$wrong_add_a) < 0.5 } => "That looks like you added. Here we multiply the stage counts.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Part (d): First digit cannot be zero AND no repetition");
+BEGIN_PGML
+d) First digit cannot be zero AND no repetition is allowed.
+
+1st digit options: [____]{$val_d1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-10) < 0.0008 } => "First digit cannot be zero, so there are 9 options (1-9).",
+))}
+
+2nd digit options: [____]{$val_d2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-10) < 0.0008 } => "No repetition: after choosing the first digit, 9 digits remain.",
+ sub { abs($_[0]-8) < 0.0008 } => "Too small: only one digit has been used so far, so 9 remain.",
+))}
+
+3rd digit options: [____]{$val_d3->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-9) < 0.0008 } => "After two digits are used, 8 digits remain.",
+))}
+
+4th digit options: [____]{$val_d4->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-8) < 0.0008 } => "After three digits are used, 7 digits remain.",
+))}
+
+Product (total PINs): [__________]{$val_dP->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "A count cannot be negative.",
+ sub { abs($_[0]-$cP) < 0.5 } => "That is part (c) with repetition allowed. Here the choices decrease because repetition is not allowed.",
+ sub { abs($_[0]-$wrong_9pow4) < 0.5 } => "That looks like you used 9 options for all 4 digits. Here the later stages decrease due to no repetition.",
+ sub { abs($_[0]-$wrong_add_a) < 0.5 } => "That looks like you added. Here we multiply the stage counts.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning counting with PIN codes?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{Real(3)->cmp(checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return ($v == int($v) && $v >= 1 && $v <= 5);
+ })->withPostFilter(AnswerHints(
+ sub { $_[0] < 1 || $_[0] > 5 } => "Please enter an integer from 1 to 5.",
+ sub { $_[0] != int($_[0]) } => "Please enter a whole number (integer) from 1 to 5.",
+ ))}
+ END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_Permutations_GuidedProblem1.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_Permutations_GuidedProblem1.pg
new file mode 100644
index 0000000000..6dcecb1a6b
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_Permutations_GuidedProblem1.pg
@@ -0,0 +1,148 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Permutations: Podium Finish (nPr) (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Combinatorics)
+## DBsection(Permutations)
+## Level(1)
+## KEYWORDS('permutation','nPr','order matters','multiplication principle','podium','factorial')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data / answers
+# =======================================================
+Context("Numeric");
+
+$n = 12;
+$r = 3;
+
+$stage1 = $n; # gold
+$stage2 = $n - 1; # silver
+$stage3 = $n - 2; # bronze
+
+$P_n_r = $stage1 * $stage2 * $stage3; # 12*11*10 = 1320
+
+$val_stage1 = Real($stage1);
+$val_stage2 = Real($stage2);
+$val_stage3 = Real($stage3);
+$val_prod = Real($P_n_r);
+$val_final = Real($P_n_r);
+
+# =======================================================
+# Guided flow (Scaffold)
+# =======================================================
+Scaffold::Begin();
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A race has **12 runners**.
+
+How many different ways can **gold**, **silver**, and **bronze** medals be awarded?
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Count by stages (order matters)");
+BEGIN_PGML
+Think of awarding medals in **stages**:
+
+- Choose the **gold** medalist first,
+- then the **silver** medalist from the remaining runners,
+- then the **bronze** medalist from the remaining runners.
+
+Fill in the number of choices at each stage:
+
+Gold: [____]{$val_stage1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-11) < 0.5 } => "Gold is chosen first, before anyone is removed.",
+))}
+
+Silver (after gold is chosen): [____]{$val_stage2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-12) < 0.5 } => "After gold is chosen, there is one fewer runner available.",
+ sub { abs($_[0]-10) < 0.5 } => "Silver is the second stage. Only one runner has been used so far.",
+))}
+
+Bronze (after gold and silver are chosen): [____]{$val_stage3->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-11) < 0.5 } => "Bronze is the third stage. Two runners have already been used.",
+))}
+
+Now multiply (Multiplication Principle):
+
+Total ways = (gold)(silver)(bronze) = [__________]{$val_prod->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-($stage1+$stage2+$stage3)) < 0.5 } => "It looks like you added instead of multiplying.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Permutation (definition and formula)");
+BEGIN_PGML
+A **permutation** is an arrangement where **order matters**.
+
+Here, (gold, silver, bronze) is an ordered result, so this is a permutation.
+
+Permutations of [`n`] elements taken [`r`] at a time are written as [`P(n,r)`] (or [`{}_nP_r`]) and:
+
+[`` P(n,r)=n(n-1)\cdots(n-r+1)=\dfrac{n!}{(n-r)!}. ``]
+
+For this problem:
+[`` P(12,3)=\dfrac{12!}{9!}. ``]
+
+Compute [`P(12,3)`]: [__________]{$val_final->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-220) < 0.5 } => "That looks like combinations. For medals, order matters.",
+ sub { abs($_[0]-132) < 0.5 } => "That looks like \(12\cdot 11\). We need three positions, so also multiply by 10.",
+ sub { abs($_[0]-720) < 0.5 } => "720 is \(6!\). Here we need \(12\cdot 11\cdot 10\).",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning permutations?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{Real(3)->cmp(checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return ($v == int($v) && $v >= 1 && $v <= 5);
+ })->withPostFilter(AnswerHints(
+ sub { $_[0] < 1 || $_[0] > 5 } => "Please enter an integer from 1 to 5.",
+ sub { $_[0] != int($_[0]) } => "Please enter a whole number (integer) from 1 to 5.",
+ ))}
+ END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_Permutations_GuidedProblem2.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_Permutations_GuidedProblem2.pg
new file mode 100644
index 0000000000..29a94b0797
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_Permutations_GuidedProblem2.pg
@@ -0,0 +1,161 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Permutations: Queue of 5 from 20 (nPr) (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Combinatorics)
+## DBsection(Permutations)
+## Level(1)
+## KEYWORDS('permutation','nPr','order matters','multiplication principle','queue','factorial')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data / answers
+# =======================================================
+Context("Numeric");
+
+$n = 20;
+$r = 5;
+
+$stage1 = $n; # position 1
+$stage2 = $n - 1; # position 2
+$stage3 = $n - 2; # position 3
+$stage4 = $n - 3; # position 4
+$stage5 = $n - 4; # position 5
+
+$P_n_r = $stage1 * $stage2 * $stage3 * $stage4 * $stage5; # 20*19*18*17*16
+
+$val_stage1 = Real($stage1);
+$val_stage2 = Real($stage2);
+$val_stage3 = Real($stage3);
+$val_stage4 = Real($stage4);
+$val_stage5 = Real($stage5);
+$val_prod = Real($P_n_r);
+$val_final = Real($P_n_r);
+
+# =======================================================
+# Guided flow (Scaffold)
+# =======================================================
+Scaffold::Begin();
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A class has **20 students**.
+
+In how many different ways can we form a **queue of 5 students** (first through fifth)?
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Count by stages (order matters)");
+BEGIN_PGML
+Think of choosing the line in **stages**:
+
+- Choose who stands in **position 1**,
+- then choose who stands in **position 2** from the remaining students,
+- continue until **position 5**.
+
+Fill in the number of choices at each stage:
+
+Position 1: [____]{$val_stage1->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-19) < 0.5 } => "Position 1 is chosen first, before anyone is removed.",
+))}
+
+Position 2: [____]{$val_stage2->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-20) < 0.5 } => "After position 1 is chosen, there is one fewer student available.",
+ sub { abs($_[0]-18) < 0.5 } => "Position 2 is the second stage. Only one student has been used so far.",
+))}
+
+Position 3: [____]{$val_stage3->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-19) < 0.5 } => "Position 3 is the third stage. Two students have already been used.",
+))}
+
+Position 4: [____]{$val_stage4->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-18) < 0.5 } => "Position 4 is the fourth stage. Three students have already been used.",
+))}
+
+Position 5: [____]{$val_stage5->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-17) < 0.5 } => "Position 5 is the fifth stage. Four students have already been used.",
+))}
+
+Now multiply (Multiplication Principle):
+
+Total ways = (pos 1)(pos 2)(pos 3)(pos 4)(pos 5) = [__________]{$val_prod->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-($stage1+$stage2+$stage3+$stage4+$stage5)) < 0.5 } => "It looks like you added instead of multiplying.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Permutation (definition and formula)");
+BEGIN_PGML
+A **permutation** is an arrangement where **order matters**.
+
+A queue is ordered (first, second, third, ...), so this is a permutation.
+
+Permutations of [`n`] elements taken [`r`] at a time are written as [`P(n,r)`] (or [`{}_nP_r`]) and:
+
+[`` P(n,r)=n(n-1)\cdots(n-r+1)=\dfrac{n!}{(n-r)!}. ``]
+
+For this problem:
+[`` P(20,5)=\dfrac{20!}{15!}. ``]
+
+Compute [`P(20,5)`]: [__________]{$val_final->cmp->withPostFilter(AnswerHints(
+ sub { $_[0] < 0 } => "Counts cannot be negative.",
+ sub { abs($_[0]-15504) < 1 } => "That looks like \(20\cdot19\cdot18\cdot17\cdot16/6\). Dividing by 6 suggests combinations. For a queue, order matters.",
+ sub { abs($_[0]-116280) < 1 } => "That looks like you stopped after 4 positions (20·19·18·17). We need 5 positions.",
+))}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning permutations?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{Real(3)->cmp(checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return ($v == int($v) && $v >= 1 && $v <= 5);
+ })->withPostFilter(AnswerHints(
+ sub { $_[0] < 1 || $_[0] > 5 } => "Please enter an integer from 1 to 5.",
+ sub { $_[0] != int($_[0]) } => "Please enter a whole number (integer) from 1 to 5.",
+ ))}
+ END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_Permutations_GuidedProblem3.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_Permutations_GuidedProblem3.pg
new file mode 100644
index 0000000000..b2000d85aa
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_Permutations_GuidedProblem3.pg
@@ -0,0 +1,163 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Permutations: 3 People in 7 Chairs (nPr) (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Combinatorics)
+## DBsection(Permutations)
+## Level(1)
+## KEYWORDS('permutation','nPr','order matters','multiplication principle','chairs','factorial')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data
+# =======================================================
+Context("Numeric");
+
+$n = 7; # chairs
+$r = 3; # people (distinct)
+
+$stage1 = $n; # Person 1
+$stage2 = $n - 1; # Person 2
+$stage3 = $n - 2; # Person 3
+
+$P_n_r = $stage1 * $stage2 * $stage3; # 7*6*5 = 210
+
+$val_stage1 = Real($stage1);
+$val_stage2 = Real($stage2);
+$val_stage3 = Real($stage3);
+$val_prod = Real($P_n_r);
+$val_final = Real($P_n_r);
+
+# =======================================================
+# AnswerHints predicates (robust: use answerHash)
+# =======================================================
+$cmp_stage1 = $val_stage1->cmp->withPostFilter(AnswerHints(
+ sub { my $ans = shift; my $s = $ans->{student_ans}; return ($s ne "" && $s < 0); } => "Counts cannot be negative.",
+ sub { my $ans = shift; my $s = $ans->{student_ans}; return abs($s - 6) < 0.5; } => "Person 1 is seated first, before any chair is taken.",
+));
+
+$cmp_stage2 = $val_stage2->cmp->withPostFilter(AnswerHints(
+ sub { my $ans = shift; my $s = $ans->{student_ans}; return ($s ne "" && $s < 0); } => "Counts cannot be negative.",
+ sub { my $ans = shift; my $s = $ans->{student_ans}; return abs($s - 7) < 0.5; } => "After Person 1 sits, there is one fewer chair available.",
+ sub { my $ans = shift; my $s = $ans->{student_ans}; return abs($s - 5) < 0.5; } => "Person 2 is the second stage: only one chair has been used so far.",
+));
+
+$cmp_stage3 = $val_stage3->cmp->withPostFilter(AnswerHints(
+ sub { my $ans = shift; my $s = $ans->{student_ans}; return ($s ne "" && $s < 0); } => "Counts cannot be negative.",
+ sub { my $ans = shift; my $s = $ans->{student_ans}; return abs($s - 6) < 0.5; } => "Person 3 is the third stage: two chairs have already been taken.",
+));
+
+$cmp_prod = $val_prod->cmp->withPostFilter(AnswerHints(
+ sub { my $ans = shift; my $s = $ans->{student_ans}; return ($s ne "" && $s < 0); } => "Counts cannot be negative.",
+ sub { my $ans = shift; my $s = $ans->{student_ans}; return abs($s - ($stage1 + $stage2 + $stage3)) < 0.5; } => "It looks like you added instead of multiplying.",
+));
+
+$cmp_final = $val_final->cmp->withPostFilter(AnswerHints(
+ sub { my $ans = shift; my $s = $ans->{student_ans}; return ($s ne "" && $s < 0); } => "Counts cannot be negative.",
+ sub { my $ans = shift; my $s = $ans->{student_ans}; return abs($s - 35) < 0.5; } => "35 is a combinations-style count (order ignored). Here, order matters.",
+ sub { my $ans = shift; my $s = $ans->{student_ans}; return abs($s - 343) < 0.5; } => "343 is 7^3, but you cannot reuse a chair. One person per chair.",
+ sub { my $ans = shift; my $s = $ans->{student_ans}; return abs($s - 42) < 0.5; } => "42 is (7)(6): that is only two people seated. We need three.",
+));
+
+$cmp_rating = Real(3)->cmp(checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return ($v == int($v) && $v >= 1 && $v <= 5); # accept any 1-5 as "correct"
+ })->withPostFilter(AnswerHints(
+ sub { my $ans = shift; my $s = $ans->{student_ans}; return ($s ne "" && ($s < 1 || $s > 5)); } => "Please enter an integer from 1 to 5.",
+ sub { my $ans = shift; my $s = $ans->{student_ans}; return ($s ne "" && $s != int($s)); } => "Please enter a whole number (integer) from 1 to 5.",
+ ));
+
+# =======================================================
+# Guided flow (Scaffold)
+# =======================================================
+Scaffold::Begin();
+
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+There are **7 chairs** in a row and **3 distinct people**.
+
+In how many different ways can the 3 people sit down (one person per chair)?
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Count by stages (order matters)");
+BEGIN_PGML
+Think of seating people in **stages**:
+
+- Seat **Person 1** first,
+- then seat **Person 2** in one of the remaining chairs,
+- then seat **Person 3** in one of the remaining chairs.
+
+Fill in the number of choices at each stage:
+
+Person 1: [____]{$cmp_stage1}
+
+Person 2: [____]{$cmp_stage2}
+
+Person 3: [____]{$cmp_stage3}
+
+Now multiply (Multiplication Principle):
+
+Total ways = (P1)(P2)(P3) = [__________]{$cmp_prod}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+Section::Begin("Permutation (definition and formula)");
+BEGIN_PGML
+A **permutation** is an arrangement where **order matters**.
+
+Different people in different chairs gives different outcomes, so this is a permutation.
+
+Permutations of [`n`] objects taken [`r`] at a time are written as [`P(n,r)`] (or [`{}_nP_r`]) and:
+
+[`` P(n,r)=n(n-1)\cdots(n-r+1)=\dfrac{n!}{(n-r)!}. ``]
+
+For this problem:
+[`` P(7,3)=\dfrac{7!}{4!}. ``]
+
+Compute [`P(7,3)`]: [__________]{$cmp_final}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning permutations?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_Permutations_GuidedProblem4.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_Permutations_GuidedProblem4.pg
new file mode 100644
index 0000000000..bd6745009d
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Combinatorics/Combinatorics_Permutations_GuidedProblem4.pg
@@ -0,0 +1,197 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Probability via Counting: MISSISSIPPI Distinct Arrangements (Guided / Scaffolded)
+## ENDDESCRIPTION
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Data & Calculations
+# =======================================================
+Context("Numeric");
+
+# Word: MISSISSIPPI
+# Counts: M=1, I=4, S=4, P=2 (total n=11)
+$n = 11;
+$nM = 1;
+$nI = 4;
+$nS = 4;
+$nP = 2;
+
+# helper: factorial
+sub fact {
+ my ($m) = @_;
+ return 1 if ($m <= 1);
+ my $p = 1;
+ for (my $k = 2; $k <= $m; $k++) { $p *= $k; }
+ return $p;
+}
+
+# Distinct permutations: n! / (nI! nS! nP! nM!)
+$ans_val = fact($n) / ( fact($nI) * fact($nS) * fact($nP) * fact($nM) );
+
+# MathObjects
+$valN = Real($n);
+$valNI = Real($nI);
+$valNS = Real($nS);
+$valNP = Real($nP);
+$valAns = Real($ans_val);
+
+# =======================================================
+# Checkpoints (MC)
+# =======================================================
+
+# Section 2: meaning checkpoint (Formula checkpoint removed as requested)
+$rb_why_divide = RadioButtons(
+ [
+ "Because factorials make numbers smaller, so it must be correct.",
+ "Because swapping identical objects creates a new arrangement.",
+ "Because swapping identical objects does NOT create a new arrangement, so \(n!\) overcounts.",
+ "Because we always divide by the number of different letter types.",
+ ],
+ 2,
+ labels => "ABC",
+);
+
+# =======================================================
+# Evaluators
+# =======================================================
+
+$cmp_n = $valN->cmp->withPostFilter(AnswerHints(
+ sub { my ($c, $s) = @_; return $s == 10; } => "Count the letters carefully: MISSISSIPPI has 11 letters.",
+));
+
+$cmp_nI = $valNI->cmp->withPostFilter(AnswerHints(
+ sub { my ($c, $s) = @_; return $s == 3; } => "MISSISSIPPI has 4 I's (not 3).",
+));
+
+$cmp_nS = $valNS->cmp->withPostFilter(AnswerHints(
+ sub { my ($c, $s) = @_; return $s == 3; } => "MISSISSIPPI has 4 S's (not 3).",
+));
+
+$cmp_nP = $valNP->cmp->withPostFilter(AnswerHints(
+ sub { my ($c, $s) = @_; return $s == 1; } => "MISSISSIPPI has 2 P's (not 1).",
+));
+
+# Function to create answer evaluator for the final result
+sub get_ans_cmp {
+ return Real($ans_val)->cmp->withPostFilter(AnswerHints(
+ sub { my ($c, $s) = @_; return abs($s - fact(11)) < 0.5; } =>
+ "That is \(11!\), which would be correct only if all letters were different. Here we have repeats.",
+ sub { my ($c, $s) = @_; return $s == 0; } => "The result must be a positive integer.",
+ ));
+}
+
+# Rating evaluator
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = $student->value;
+ return (defined($v) && $v == int($v) && $v >= 1 && $v <= 5);
+ }
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin();
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+How many **distinct arrangements** of the letters in **MISSISSIPPI** are possible?
+
+(Swapping two identical letters does **not** create a new arrangement.)
+END_PGML
+Section::End();
+
+Section::Begin("Permutations with repeated objects (The Formula)");
+BEGIN_PGML
+If there are [`` n ``] total objects, and some objects are identical:
+
+- Object type 1 repeats [`` n_1 ``] times
+- Object type 2 repeats [`` n_2 ``] times
+- ...
+- Object type [`` k ``] repeats [`` n_k ``] times
+
+with [`` n_1+n_2+\cdots+n_k = n ``], then the number of **distinct permutations** is:
+
+[`` \frac{n!}{n_1!\,n_2!\cdots n_k!} ``]
+
+Here is the logic (this is the key idea):
+
+1) Start with [`` n! ``] arrangements **as if every object were different**.
+2) But if a certain object repeats [`` n_1 ``] times, then swapping those [`` n_1 ``] identical objects does **not** create a new arrangement.
+ That means each distinct arrangement was counted [`` n_1! ``] times in [`` n! ``] because of those identical objects.
+3) If another object repeats [`` n_2 ``] times, that creates another overcounting factor of [`` n_2! ``], and so on.
+4) Therefore each distinct arrangement is counted [`` n_1!\,n_2!\cdots n_k! ``] times inside [`` n! ``].
+5) To fix the overcounting, divide:
+
+[`` \text{distinct permutations}=\frac{n!}{n_1!\,n_2!\cdots n_k!}. ``]
+
+**Checkpoint:** Why do we divide by factorials of the repeats?
+
+[@ $rb_why_divide->buttons() @]*
+END_PGML
+ANS($rb_why_divide->cmp);
+Section::End();
+
+Section::Begin("Count the repeated letters in MISSISSIPPI");
+BEGIN_PGML
+Now apply the idea to **MISSISSIPPI**.
+
+First count the letters:
+
+Total letters: [`` n = ``] [____]{$cmp_n}
+
+Number of I's: [____]{$cmp_nI}
+Number of S's: [____]{$cmp_nS}
+Number of P's: [____]{$cmp_nP}
+
+(There is also one M, but [``1! = 1``], so it will not change the count.)
+END_PGML
+Section::End();
+
+Section::Begin("Apply the formula (final answer)");
+BEGIN_PGML
+Using the formula:
+
+[`` \text{distinct arrangements} = \frac{n!}{n_I!\,n_S!\,n_P!} ``]
+
+Compute the number of distinct arrangements:
+
+[__________]{get_ans_cmp()}
+END_PGML
+Section::End();
+
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning permutations with repeated objects?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/1.png b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/1.png
new file mode 100644
index 0000000000..f3177f250a
Binary files /dev/null and b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/1.png differ
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/ContinuousRandomVariables_PDF_GuidedProblem1.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/ContinuousRandomVariables_PDF_GuidedProblem1.pg
new file mode 100644
index 0000000000..060f14f83a
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/ContinuousRandomVariables_PDF_GuidedProblem1.pg
@@ -0,0 +1,286 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Continuous Random Variables: Intro to PDFs (Geometry Only) (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Continuous Random Variables)
+## Level(2)
+## KEYWORDS('continuous random variable','probability density function','pdf','area','geometry','interval probability')
+## Static(1)
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser flag (LB-safe)
+# ----------------------------------------------------------------
+$inLibraryBrowser = 0;
+if (defined($envir{isLibrary}) && $envir{isLibrary}) { $inLibraryBrowser = 1; }
+if (defined($envir{isLibraryBrowser}) && $envir{isLibraryBrowser}) { $inLibraryBrowser = 1; }
+
+# =======================================================
+# Context & Data
+# =======================================================
+Context("Numeric");
+
+# PDF described by the provided graph:
+# - Constant on [0,2] with height 1/3
+# - Linearly decreases from height 1/3 at x=2 to 0 at x=4
+
+$h2 = Compute("1/3"); # f(2)
+$h3 = Compute("1/6"); # f(3) (halfway down)
+
+# Areas (probabilities) by geometry
+$A_rect_0_2 = Compute("2*(1/3)"); # area on [0,2]
+$A_tri_2_4 = Compute("(1/2)*2*(1/3)"); # area on [2,4]
+$A_total = Compute("1");
+
+$P_0_1 = Compute("1*(1/3)"); # rectangle on [0,1]
+$P_3_4 = Compute("(1/2)*1*(1/6)"); # small triangle on [3,4]
+$P_1_2 = Compute("1*(1/3)"); # rectangle on [1,2]
+$P_2_3 = Compute("(1/2)*1*((1/3)+(1/6))"); # trapezoid on [2,3]
+$P_1_3 = Compute("1/3 + 0.25"); # This evaluates to 7/12 (0.5833...)
+
+$P_point2 = Real(0);
+
+# =======================================================
+# Evaluators (with non-revealing hints)
+# =======================================================
+
+$cmp_Arect = $A_rect_0_2->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 2) < 1e-6 } => "That is only the base length. Rectangle area = (base)(height).",
+ sub { abs($_[0] - (1/3)) < 1e-6 } => "That is only the height. Rectangle area = (base)(height).",
+));
+
+$cmp_Atri = $A_tri_2_4->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 2) < 1e-6 } => "That is only the base length. Triangle area = (1/2)(base)(height).",
+ sub { abs($_[0] - (1/3)) < 1e-6 } => "That is only the height. Triangle area = (1/2)(base)(height).",
+));
+
+$cmp_Atotal = $A_total->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - $A_rect_0_2->value) < 1e-6 } => "You entered only the rectangle area. Add rectangle + triangle.",
+ sub { abs($_[0] - $A_tri_2_4->value) < 1e-6 } => "You entered only the triangle area. Add rectangle + triangle.",
+));
+
+$cmp_f2 = $h2->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 0) < 1e-6 } => "f(2) is the height of the graph at x=2, not a probability.",
+));
+
+$cmp_f3 = $h3->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - $h2->value) < 1e-6 } => "At x=3 the height is lower than at x=2 because the line is decreasing.",
+));
+
+$cmp_P01 = $P_0_1->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 1) < 1e-6 } => "Probability is an area, not a width. Use rectangle area: (base)(height).",
+));
+
+$cmp_P34 = $P_3_4->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (1/6)) < 1e-6 } => "That is the height at x=3, not the area. Use triangle area: (1/2)(base)(height).",
+));
+
+$cmp_P13 = $P_1_3->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - $P_1_2->value) < 1e-6 } => "That is only the area from 1 to 2. You also need the area from 2 to 3.",
+ sub { abs($_[0] - $P_2_3->value) < 1e-6 } => "That is only the area from 2 to 3. You also need the area from 1 to 2.",
+));
+
+$cmp_point2 = $P_point2->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - $h2->value) < 1e-6 } => "That is f(2), a height (density). A single point has zero width, so probability is 0.",
+));
+
+$rb_area = RadioButtons(
+ [
+ "The value f(3).",
+ "The area under the graph of f(x) from x=1 to x=3.",
+ "The number of x-values between 1 and 3.",
+ ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+if ($ENABLE_GP_RATING) {
+ $cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($c, $s, $ans) = @_;
+ my $v = eval { $s->value };
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ans->{score} = 1; $ans->{ans_message} = "Thanks!";
+ } else {
+ $ans->{score} = 0; $ans->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+ return $ans->{score};
+ }
+ );
+}
+
+# =======================================================
+# Scaffold
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(can_open => "always", is_open => "always");
+} else {
+ Scaffold::Begin(open_one_at_a_time => 1, can_open => "when_previous_correct");
+}
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+This guided problem introduces **probability density functions** (pdfs) using **geometry only** (no integration).
+
+Let [`` X ``] be a continuous random variable with pdf [`` f(x) ``] shown in the graph below.
+
+You will:
+- check the two pdf conditions,
+- compute probabilities of intervals by finding **areas under the curve**,
+- see why point probabilities are 0.
+
+[@ image("pdf_rect_triangle.png", width => 520) @]*
+END_PGML
+Section::End();
+
+Section::Begin("Two conditions and the interval rule");
+BEGIN_PGML
+Every density function [`` f(x) ``] must satisfy:
+
+1. [`` f(x)\ge 0 ``] for all [`` x ``] (the graph never drops below the x-axis).
+2. The total area under the graph of [`` f(x) ``] is 1.
+
+Also, for any continuous random variable [`` X ``]:
+[`` P(a\le X\le b)=P(a< X\le b)=P(a\le X< b)=P(a< X< b) ``]
+
+**Checkpoint:** Which expression represents [`` P(1\le X\le 3) ``]?
+
+[@ $rb_area->buttons() @]*
+END_PGML
+ANS($rb_area->cmp);
+Section::End();
+
+Section::Begin("Geometry toolbox");
+BEGIN_PGML
+We will compute probabilities using basic area formulas:
+
+- Rectangle area = (base)(height)
+- Triangle area = (1/2)(base)(height)
+- Trapezoid area = (1/2)(base)(sum of the parallel side lengths)
+
+In this graph:
+- The part from [`` x=0 ``] to [`` x=2 ``] is a rectangle region under a constant height.
+- The part from [`` x=2 ``] to [`` x=4 ``] is a triangle region under a straight line.
+END_PGML
+Section::End();
+
+Section::Begin("Check condition 2: total area is 1");
+BEGIN_PGML
+Compute the area in two pieces:
+
+1) Area under [`` f(x) ``] from [`` 0 ``] to [`` 2 ``] (rectangle): [____]
+
+2) Area under [`` f(x) ``] from [`` 2 ``] to [`` 4 ``] (triangle): [____]
+
+3) Total area (rectangle + triangle): [____]
+END_PGML
+ANS($cmp_Arect);
+ANS($cmp_Atri);
+ANS($cmp_Atotal);
+Section::End();
+
+Section::Begin("Density values vs probabilities");
+BEGIN_PGML
+A pdf value like [`` f(2) ``] is a **height** (a density), not a probability.
+
+Read the height from the graph:
+
+1) [`` f(2)= ``] [____]
+
+2) [`` f(3)= ``] [____]
+END_PGML
+ANS($cmp_f2);
+ANS($cmp_f3);
+Section::End();
+
+Section::Begin("Interval probabilities by area (practice)");
+BEGIN_PGML
+Now compute probabilities as **areas** under the graph.
+
+1) [`` P(0\le X\le 1) ``] (a rectangle region): [____]
+
+2) [`` P(3\le X\le 4) ``] (a small triangle region): [____]
+
+3) [`` P(1\le X\le 3) ``] (split it at [`` x=2 ``]; rectangle + trapezoid): [____]
+END_PGML
+ANS($cmp_P01);
+ANS($cmp_P34);
+ANS($cmp_P13);
+Section::End();
+
+Section::Begin("Endpoints do not matter");
+BEGIN_PGML
+Compute the "open-interval" version:
+
+[`` P(1< X< 3)= ``] [____]
+
+Now compute the difference:
+
+[`` P(1\le X\le 3)-P(1< X< 3)= ``] [____]
+END_PGML
+ANS($P_1_3->cmp);
+ANS(Real(0)->cmp);
+Section::End();
+
+Section::Begin("Point probability is zero");
+BEGIN_PGML
+A single point has zero width, so its "area" is zero.
+
+Compute:
+
+[`` P(X=2)= ``] [____]
+END_PGML
+ANS($cmp_point2);
+Section::End();
+
+Section::Begin("Final Answer");
+BEGIN_PGML
+Enter the key takeaways:
+
+Total area under the pdf [`` = ``] [____]
+[`` P(1\le X\le 3)= ``] [____]
+[`` P(X=2)= ``] [____]
+END_PGML
+ANS($A_total->cmp);
+ANS($P_1_3->cmp);
+ANS($P_point2->cmp);
+Section::End();
+
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for understanding what a pdf means?
+
+Rating (enter 1-5): [___]
+END_PGML
+ ANS($cmp_rating);
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/ContinuousRandomVariables_PDF_GuidedProblem2.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/ContinuousRandomVariables_PDF_GuidedProblem2.pg
new file mode 100644
index 0000000000..463fb14573
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/ContinuousRandomVariables_PDF_GuidedProblem2.pg
@@ -0,0 +1,334 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Continuous Random Variables: Intro to PDFs (Geometry Only, Quarter Circle + Rectangle) (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Continuous Random Variables)
+## Level(2)
+## KEYWORDS('continuous random variable','probability density function','pdf','area','geometry','interval probability','point probability')
+## Static(1)
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser flag (LB-safe)
+# ----------------------------------------------------------------
+$inLibraryBrowser = 0;
+if (defined($envir{isLibrary}) && $envir{isLibrary}) { $inLibraryBrowser = 1; }
+if (defined($envir{isLibraryBrowser}) && $envir{isLibraryBrowser}) { $inLibraryBrowser = 1; }
+
+# =======================================================
+# Context & Data
+# =======================================================
+Context("Numeric");
+
+# PDF shape:
+# - On [0,1]: a quarter-circle arc that passes (0,0) and (1,1)
+# (circle centered at (0,1), radius 1): f(x)=1 - sqrt(1-x^2)
+# - On [1, 1+pi/4]: a rectangle of height 1
+# - Elsewhere: 0
+#
+# Geometry facts:
+# - Area under sqrt(1-x^2) on [0,1] is a quarter circle area = pi/4
+# - So area under f(x)=1 - sqrt(1-x^2) on [0,1] is (area of 1x1 square) - (pi/4) = 1 - pi/4
+# - Rectangle width is pi/4, height 1, so rectangle area is pi/4
+# - Total area = 1
+
+$pi4 = Compute("pi/4");
+$pi8 = Compute("pi/8");
+
+$arcArea = Compute("1 - pi/4"); # area on [0,1]
+$rectWidth = Compute("pi/4"); # (1+pi/4) - 1
+$rectArea = Compute("pi/4"); # width * height
+$totalArea = Compute("1");
+
+# Interval probabilities
+$P_Xge1 = $rectArea; # P(X >= 1) = rectangle area
+$P_0_to_1 = $arcArea; # P(0<=X<=1)
+$P_1_to_1pi8 = $pi8; # slice of rectangle: width pi/8, height 1
+$P_0_to_1pi8 = Compute($arcArea->string . " + " . $pi8->string); # arc + slice
+$P_1pi8_to_1pi4 = $pi8; # remaining rectangle: pi/8
+
+$P_point = Real(0);
+$f_at_1 = Real(1);
+
+# =======================================================
+# Evaluators (+ hints)
+# =======================================================
+
+# Definition checkpoint (MC)
+$rb_pdfprob = RadioButtons(
+ [
+ "The height of the graph at x=1 (that is, f(1)).",
+ "The area under the graph of f(x) from x=1 to x=1+pi/8.",
+ "The number of x-values between 1 and 1+pi/8.",
+ ],
+ 1, # correct is B (not A)
+ labels => "ABC",
+ displayLabels => 0,
+ checked => 0,
+);
+
+# Areas to verify pdf
+$cmp_arcArea = $arcArea->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 1) < 1e-6 } =>
+ "1 is the area of the 1×1 square. The arc area is (square area) minus (quarter-circle area).",
+ sub { abs($_[0] - $pi4->value) < 1e-6 } =>
+ "pi/4 is the quarter-circle area. The arc area here is 1 - pi/4.",
+));
+
+$cmp_rectWidth = $rectWidth->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (1 + $pi4->value)) < 1e-6 } =>
+ "That is the RIGHT endpoint. The width is (1+pi/4) - 1.",
+));
+
+$cmp_rectArea = $rectArea->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - $rectWidth->value) < 1e-6 } =>
+ "You entered the width only. Rectangle area = (width)(height). The height is 1.",
+));
+
+$cmp_totalArea = $totalArea->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - $arcArea->value) < 1e-6 } =>
+ "You entered only the arc part. Add arc + rectangle.",
+ sub { abs($_[0] - $rectArea->value) < 1e-6 } =>
+ "You entered only the rectangle part. Add arc + rectangle.",
+));
+
+# Probabilities
+$cmp_P_0_1 = $P_0_to_1->cmp;
+$cmp_P_Xge1 = $P_Xge1->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (1 - $pi4->value)) < 1e-6 } =>
+ "That is the arc area (from 0 to 1). For X>=1, you want the rectangle area.",
+));
+
+$cmp_P_0_to_1pi8 = $P_0_to_1pi8->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - $arcArea->value) < 1e-6 } =>
+ "That is only the arc part (0 to 1). You also need the rectangle slice from 1 to 1+pi/8.",
+ sub { abs($_[0] - $pi8->value) < 1e-6 } =>
+ "That is only the rectangle slice. You also need the arc part from 0 to 1.",
+));
+
+$cmp_P_tail = $P_1pi8_to_1pi4->cmp;
+
+# Endpoints + point probability
+$cmp_same_open = $P_0_to_1->cmp;
+$cmp_diff_endpoints = Real(0)->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - $P_0_to_1->value) < 1e-6 } =>
+ "You entered the probability itself. The difference should be 0 for a continuous random variable.",
+));
+
+$cmp_f1 = $f_at_1->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 0) < 1e-6 } =>
+ "f(1) is a height (density), not a probability. Read the height at x=1 from the graph.",
+));
+
+$cmp_point = $P_point->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 1) < 1e-6 } =>
+ "1 is f(1), the height. A single point has zero width, so the probability is 0.",
+));
+
+# Rating (1–5)
+if ($ENABLE_GP_RATING) {
+ $cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($c, $s, $ans) = @_;
+ my $v = eval { $s->value };
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ans->{score} = 1; $ans->{ans_message} = "Thanks!";
+ } else {
+ $ans->{score} = 0; $ans->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+ return $ans->{score};
+ }
+ );
+}
+
+# =======================================================
+# Scaffold (LB-safe)
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(can_open => "always", is_open => "always");
+} else {
+ Scaffold::Begin(open_one_at_a_time => 1, can_open => "when_previous_correct");
+}
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+This guided problem introduces **probability density functions** (pdfs) using **geometry only** (no integration).
+
+Let [`` X ``] be a continuous random variable with pdf [`` f(x) ``] shown in the graph below.
+
+You will:
+- check the two pdf conditions,
+- compute probabilities of intervals by finding **areas under the curve**,
+- see why point probabilities are 0.
+
+[@ image("pdf_quartercircle_origin_to_1_1_plus_rectangle.png", width => 520) @]*
+END_PGML
+Section::End();
+
+Section::Begin("Two conditions and the interval rule");
+BEGIN_PGML
+Every density function [`` f(x) ``] must satisfy:
+
+1. [`` f(x)\ge 0 ``] for all [`` x ``] (the graph never drops below the x-axis).
+2. The total area under the graph of [`` f(x) ``] is 1.
+
+Also, for any continuous random variable [`` X ``]:
+[`` P(a\le X\le b)=P(a< X\le b)=P(a\le X< b)=P(a< X< b) ``]
+
+**Checkpoint:** Which expression represents a probability like [`` P(1\le X\le 1+\pi/8) ``]?
+
+[@ $rb_pdfprob->buttons() @]*
+END_PGML
+ANS($rb_pdfprob->cmp);
+Section::End();
+
+Section::Begin("Geometry toolbox (the only formulas we need)");
+BEGIN_PGML
+We will compute probabilities using basic geometry:
+
+- Rectangle area = (base)(height)
+- Quarter circle area (radius 1) = [`` \pi/4 ``]
+
+Key idea for the curved part:
+On [`` 0\le x\le 1 ``], the pdf is the “top of the 1×1 square” minus a quarter-circle arc.
+So the area under the curve on [`` 0\le x\le 1 ``] is:
+
+(area of 1×1 square) − (area of quarter circle).
+END_PGML
+Section::End();
+
+Section::Begin("Check condition 2: total area is 1");
+BEGIN_PGML
+Compute the total area in pieces.
+
+1) Area under the curved part on [`` 0\le x\le 1 ``] (square minus quarter circle):
+
+[____]
+
+2) Width (base) of the rectangle part (from [`` 1 ``] to [`` 1+\pi/4 ``]):
+
+[____]
+
+3) Area of the rectangle part (height 1):
+
+[____]
+
+4) Total area (curved part + rectangle part):
+
+[____]
+END_PGML
+ANS($cmp_arcArea);
+ANS($cmp_rectWidth);
+ANS($cmp_rectArea);
+ANS($cmp_totalArea);
+Section::End();
+
+Section::Begin("Interval probabilities by geometry");
+BEGIN_PGML
+Now compute probabilities as **areas** under the graph.
+
+1) [`` P(0\le X\le 1) ``] (this is exactly the curved-part area):
+
+[____]
+
+2) [`` P(X\ge 1) ``] (this is exactly the rectangle area):
+
+[____]
+
+3) [`` P(0\le X\le 1+\pi/8) ``] (curved part + a rectangle slice of width [`` \pi/8 ``]):
+
+[____]
+
+4) [`` P(1+\pi/8\le X\le 1+\pi/4) ``] (the remaining rectangle slice):
+
+[____]
+END_PGML
+ANS($cmp_P_0_1);
+ANS($cmp_P_Xge1);
+ANS($cmp_P_0_to_1pi8);
+ANS($cmp_P_tail);
+Section::End();
+
+Section::Begin("Endpoints do not matter");
+BEGIN_PGML
+For continuous random variables, endpoints do not affect probability.
+
+Compute:
+
+1) [`` P(0< X< 1)= ``] [____]
+
+2) [`` P(0\le X\le 1)-P(0< X< 1)= ``] [____]
+END_PGML
+ANS($cmp_same_open);
+ANS($cmp_diff_endpoints);
+Section::End();
+
+Section::Begin("Point probability is zero");
+BEGIN_PGML
+A pdf value like [`` f(1) ``] is a **height** (density), not a probability.
+
+1) Read from the graph: [`` f(1)= ``] [____]
+
+2) But the probability of a single point is always zero for a continuous random variable:
+[`` P(X=1)= ``] [____]
+END_PGML
+ANS($cmp_f1);
+ANS($cmp_point);
+Section::End();
+
+Section::Begin("Final Answer");
+BEGIN_PGML
+Enter the key takeaways:
+
+Total area under the pdf [`` = ``] [____]
+[`` P(X\ge 1)= ``] [____]
+[`` P(X=1)= ``] [____]
+END_PGML
+ANS($totalArea->cmp);
+ANS($P_Xge1->cmp);
+ANS($P_point->cmp);
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating 1–5) (hidden in LB)
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for understanding what a pdf means?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]
+END_PGML
+ ANS($cmp_rating);
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/ContinuousRandomVariables_PDF_GuidedProblem3.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/ContinuousRandomVariables_PDF_GuidedProblem3.pg
new file mode 100644
index 0000000000..abd1141892
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/ContinuousRandomVariables_PDF_GuidedProblem3.pg
@@ -0,0 +1,214 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Continuous Random Variables: Uniform(0,1) Interval Probabilities (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Continuous Random Variables)
+## Level(2)
+## KEYWORDS('continuous random variable','uniform distribution','pdf','area','geometry','interval probability')
+## Static(1)
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser flag (LB-safe)
+# ----------------------------------------------------------------
+$inLibraryBrowser = 0;
+if (defined($envir{isLibrary}) && $envir{isLibrary}) { $inLibraryBrowser = 1; }
+if (defined($envir{isLibraryBrowser}) && $envir{isLibraryBrowser}) { $inLibraryBrowser = 1; }
+
+# =======================================================
+# Context & Data
+# =======================================================
+Context("Numeric");
+
+# Uniform(0,1): f(x)=1 on [0,1], 0 otherwise
+$A_total = Compute("1");
+
+$P_gt_075 = Compute("1 - 0.75"); # 0.25
+$P_le_02 = Compute("0.2"); # 0.2
+$P_04_07 = Compute("0.7 - 0.4"); # 0.3
+
+# =======================================================
+# MC checkpoint (1)
+# =======================================================
+$rb_rule = RadioButtons(
+ [
+ "It is the height f(a).",
+ "It is the area under f(x) from a to b.",
+ "It is the number of points between a and b.",
+ ],
+ 1, # correct is B (not A)
+ labels => "ABC",
+ displayLabels => 0,
+ checked => 0,
+);
+
+# =======================================================
+# Evaluators (with friendly hints)
+# =======================================================
+$cmp_total = $A_total->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 0) < 1e-6 } =>
+ "Total area under a pdf cannot be 0. For Uniform(0,1), the region is a 1-by-1 rectangle.",
+));
+
+$cmp_gt_075 = $P_gt_075->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 0.75) < 1e-6 } =>
+ "0.75 is the left endpoint, not the probability. For Uniform(0,1), probability is the width of the interval (with height 1).",
+ sub { abs($_[0] - 1) < 1e-6 } =>
+ "1 is the height, not the probability. Probability is an area (width)(height).",
+));
+
+$cmp_le_02 = $P_le_02->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 0.8) < 1e-6 } =>
+ "0.8 is P(X>0.2). Here you want P(X<=0.2).",
+));
+
+$cmp_04_07 = $P_04_07->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 0.4) < 1e-6 } =>
+ "0.4 is the left endpoint. For Uniform(0,1), probability is the width: 0.7 minus 0.4.",
+ sub { abs($_[0] - 0.7) < 1e-6 } =>
+ "0.7 is the right endpoint. For Uniform(0,1), probability is the width: 0.7 minus 0.4.",
+));
+
+# Endpoints check (same value)
+$cmp_closed = $P_04_07->cmp;
+
+# Rating (1–5)
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($c, $s, $ans) = @_;
+ my $v = eval { $s->value };
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ans->{score} = 1; $ans->{ans_message} = "Thanks!";
+ } else {
+ $ans->{score} = 0; $ans->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+ return $ans->{score};
+ }
+);
+
+# =======================================================
+# Scaffold (LB-safe)
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(can_open => "always", is_open => "always");
+} else {
+ Scaffold::Begin(open_one_at_a_time => 1, can_open => "when_previous_correct");
+}
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A random variable [`` X ``] has the **uniform distribution on** [`` [0,1] ``].
+Its density function is [`` f(x)=1 ``] if [`` 0\le x\le 1 ``] and [`` f(x)=0 ``] otherwise, as shown in the figure.
+
+[@ image("uniform_0_to_1.jpg", width => 520) @]*
+
+a. Find [`` P(X>0.75) ``].
+b. Find [`` P(X\le 0.2) ``].
+c. Find [`` P(0.4buttons() @]*
+END_PGML
+ANS($rb_rule->cmp);
+Section::End();
+
+Section::Begin("Warm-up: why the total area is 1");
+BEGIN_PGML
+For Uniform(0,1), the graph is a rectangle with:
+
+- base length [`` 1-0 ``]
+- height [`` 1 ``]
+
+So the total area is (base)(height).
+
+Total area under the pdf: [____]
+END_PGML
+ANS($cmp_total);
+Section::End();
+
+Section::Begin("Compute the probabilities (geometry only)");
+BEGIN_PGML
+Because the height is 1 on [`` [0,1] ``], the area over an interval is:
+
+(width)(height) = (width)(1) = width.
+
+So for Uniform(0,1), probabilities are just **lengths of intervals** inside [`` [0,1] ``].
+
+a) [`` P(X>0.75)= ``] [____]
+
+b) [`` P(X\le 0.2)= ``] [____]
+
+c) [`` P(0.4 "ABC",
+ displayLabels => 0,
+ checked => 0,
+);
+
+# =======================================================
+# Evaluators (+ hints)
+# =======================================================
+$cmp_height = $height->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 30) < 1e-6 } =>
+ "30 is the length of the interval. For Uniform(0,30), the constant height is 1/30.",
+));
+
+$cmp_totalA = $totalA->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 30) < 1e-6 } =>
+ "That is the width. Total area = (width)(height) = 30*(1/30).",
+ sub { abs($_[0] - (1/30)) < 1e-6 } =>
+ "That is the height. Total area = (width)(height) = 30*(1/30).",
+));
+
+$cmp_le_10 = $P_le_10->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 10) < 1e-6 } =>
+ "10 is the width (in minutes). Multiply by the height 1/30.",
+ sub { abs($_[0] - (1/30)) < 1e-6 } =>
+ "1/30 is the height. Multiply by the width 10 minutes.",
+));
+
+$cmp_5_20 = $P_5_20->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (20-5)) < 1e-6 } =>
+ "20-5 is the width. Multiply by the height 1/30.",
+ sub { abs($_[0] - (1/30)) < 1e-6 } =>
+ "1/30 is the height. Multiply by the width 20-5.",
+));
+
+$cmp_ge_25 = $P_ge_25->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 25) < 1e-6 } =>
+ "25 is the left endpoint. 'At least 25' means the interval from 25 to 30, which has width 5.",
+ sub { abs($_[0] - (25*(1/30))) < 1e-6 } =>
+ "That would be the area from 0 to 25. Here you want from 25 to 30.",
+));
+
+# Rating (1–5)
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($c, $s, $ans) = @_;
+ my $v = eval { $s->value };
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ans->{score} = 1; $ans->{ans_message} = "Thanks!";
+ } else {
+ $ans->{score} = 0; $ans->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+ return $ans->{score};
+ }
+);
+
+# =======================================================
+# Scaffold (LB-safe)
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(can_open => "always", is_open => "always");
+} else {
+ Scaffold::Begin(open_one_at_a_time => 1, can_open => "when_previous_correct");
+}
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+At a certain bus stop, buses run every 30 minutes without fail.
+A man arrives at the bus stop at a random time (with no regard for the schedule) to catch the next bus.
+
+Assume his waiting time [`` X ``] is uniformly distributed between 0 and 30 minutes.
+
+[@ image("uniform_0_to_30.jpg", width => 520) @]*
+
+Find the probability that he has to wait:
+
+a) a maximum of 10 minutes
+b) between 5 and 20 minutes
+c) at least 25 minutes
+END_PGML
+Section::End();
+
+Section::Begin("Uniform(0,30): what the height means");
+BEGIN_PGML
+For a uniform distribution on [`` [0,30] ``], the pdf is a rectangle.
+
+To make the total area equal to 1, the height must be:
+
+height = [`` 1/30 ``]
+
+1) Enter the height of the pdf: [____]
+
+2) Check: total area = (width)(height) = [`` 30(1/30) ``] = [____]
+END_PGML
+ANS($cmp_height);
+ANS($cmp_totalA);
+Section::End();
+
+Section::Begin("Key idea (one checkpoint)");
+BEGIN_PGML
+**Checkpoint:** Which statement explains how to compute probabilities for Uniform(0,30)?
+
+[@ $rb_width->buttons() @]*
+END_PGML
+ANS($rb_width->cmp);
+Section::End();
+
+Section::Begin("Compute the probabilities (areas of rectangles)");
+BEGIN_PGML
+For Uniform(0,30), probability over an interval is:
+
+(area) = (width of the interval)(height [`` 1/30 ``]).
+
+a) “Maximum of 10 minutes” means [`` 0\le X\le 10 ``].
+[`` P(X\le 10)= ``] [____]
+
+b) “Between 5 and 20 minutes” means [`` 5\le X\le 20 ``].
+[`` P(5\le X\le 20)= ``] [____]
+
+c) “At least 25 minutes” means [`` 25\le X\le 30 ``].
+[`` P(X\ge 25)= ``] [____]
+END_PGML
+ANS($cmp_le_10);
+ANS($cmp_5_20);
+ANS($cmp_ge_25);
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating 1–5) (hidden in LB)
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning uniform waiting-time probabilities?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]
+END_PGML
+ ANS($cmp_rating);
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/ContinuousRandomVariables_PDF_GuidedProblem5.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/ContinuousRandomVariables_PDF_GuidedProblem5.pg
new file mode 100644
index 0000000000..0824104a4d
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/ContinuousRandomVariables_PDF_GuidedProblem5.pg
@@ -0,0 +1,247 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Normal Distribution + Empirical Rule (68–95–99.7) (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Continuous Random Variables)
+## Level(2)
+## KEYWORDS('normal distribution','bell curve','empirical rule','68-95-99.7 rule','probability density function')
+## Static(1)
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser flag (LB-safe)
+# ----------------------------------------------------------------
+$inLibraryBrowser = 0;
+if (defined($envir{isLibrary}) && $envir{isLibrary}) { $inLibraryBrowser = 1; }
+if (defined($envir{isLibraryBrowser}) && $envir{isLibraryBrowser}) { $inLibraryBrowser = 1; }
+
+# =======================================================
+# Context & Data
+# =======================================================
+Context("Numeric");
+
+$mu = Real(69.5);
+$sigma = Real(2.5);
+
+# Empirical-rule building blocks
+$half68 = Real(0.34); # half of 0.68
+$tail2 = Real(0.025); # (1-0.95)/2
+
+# Target probabilities (empirical rule approximations)
+$Pa = Real(0.50);
+$Pb = Real(0.34);
+$Pc = Real(0.68);
+$Pd = Real(0.95);
+$Pe = Real(0.025);
+
+# =======================================================
+# One checkpoint (minimal MC)
+# =======================================================
+$rb_area = RadioButtons(
+ [
+ "A probability is the area under the normal curve over an interval.",
+ "A probability is the height of the curve at a point.",
+ "A probability is the x-value where the curve is highest.",
+ ],
+ 0, # correct is A
+ labels => "ABC",
+ displayLabels => 0,
+ checked => 0,
+);
+
+# =======================================================
+# Evaluators (with non-giveaway hints)
+# =======================================================
+
+$cmp_half68 = $half68->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 0.68) < 0.02 } =>
+ "0.68 is the probability from mu - sigma to mu + sigma. From mu to mu + sigma is HALF of that (symmetry).",
+ sub { abs($_[0] - 0.50) < 0.02 } =>
+ "0.50 is the area to one side of the mean. Here you want only from mu to mu + sigma.",
+));
+
+$cmp_tail2 = $tail2->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 0.05) < 0.02 } =>
+ "0.05 is the total area OUTSIDE mu ± 2sigma (both tails). One tail is half of that.",
+ sub { abs($_[0] - 0.95) < 0.02 } =>
+ "0.95 is the area INSIDE mu ± 2sigma, not the tail area.",
+));
+
+$cmp_a = $Pa->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 0.34) < 0.02 } =>
+ "0.34 is from mu to mu + sigma. Here you want P(X > mu), which is half the curve.",
+));
+
+$cmp_b = $Pb->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 0.68) < 0.02 } =>
+ "0.68 is from mu - sigma to mu + sigma. Here you want only from mu to mu + sigma.",
+));
+
+$cmp_c = $Pc->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 0.34) < 0.02 } =>
+ "0.34 is only from mu to mu + sigma. Here you want from mu - sigma to mu + sigma (both sides).",
+ sub { abs($_[0] - 0.95) < 0.02 } =>
+ "0.95 is for mu ± 2sigma. This interval is mu ± 1sigma.",
+));
+
+$cmp_d = $Pd->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 0.68) < 0.02 } =>
+ "0.68 is for mu ± 1sigma. This interval is mu ± 2sigma.",
+));
+
+$cmp_e = $Pe->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 0.05) < 0.02 } =>
+ "0.05 is BOTH tails beyond ±2sigma. 'Shorter than mu - 2sigma' is only the left tail (half).",
+));
+
+# Rating (1–5)
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($c, $s, $ans) = @_;
+ my $v = eval { $s->value };
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ans->{score} = 1; $ans->{ans_message} = "Thanks!";
+ } else {
+ $ans->{score} = 0; $ans->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+ return $ans->{score};
+ }
+);
+
+# =======================================================
+# Scaffold (LB-safe)
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(can_open => "always", is_open => "always");
+} else {
+ Scaffold::Begin(open_one_at_a_time => 1, can_open => "when_previous_correct");
+}
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+In this guided problem we are going to learn about the most important and most commonly used probability density function. Most people have heard of the "bell curve." It is the graph of a specific density function [`` f(x) ``] that describes the behavior of many continuous random variables as different as the heights and weights of human beings, IQs, aggregated scores such as SAT, measurement errors and the velocities of molecules in a gas.
+
+We are also going to learn about the empirical rule (also known as the 68, 95, 99.7 Rule.) That can be used to solve the following problem.
+
+Heights of 25-year-old men in a certain region have mean 69.5 inches and standard deviation 2.5 inches. These heights are approximately normally distributed. Thus the height [`` X ``] of a randomly selected 25-year-old man is a normal random variable with mean [`` \mu = 69.5 ``] and standard deviation [`` \sigma = 2.5 ``].
+
+Find the probability that a randomly selected 25-year-old man
+
+a) is more than 69.5 inches tall.
+b) is between 69.5 and 72 inches tall.
+c) is between 67 and 72 inches tall
+d) is between 64.5 and 74.5 inches
+e) is shorter than 64.5
+END_PGML
+Section::End();
+
+Section::Begin("Normal density function + picture");
+BEGIN_PGML
+The **normal distribution** has the density function:
+
+[`` f(x)=\frac{1}{\sigma\sqrt{2\pi}}\,e^{-\frac{(x-\mu)^2}{2\sigma^2}} ``]
+
+In this formula [`` \mu ``] and [`` \sigma ``] are the **mean** and **standard deviation** of the normal distribution. [`` \mu ``] determines were the distribution is centered at and [`` \sigma ``] determines the amount of variability in the distribution. A probability like [`` P(a 520) @]*
+
+**Checkpoint:** Which statement is correct?
+
+[@ $rb_area->buttons() @]*
+END_PGML
+ANS($rb_area->cmp);
+Section::End();
+
+Section::Begin("Empirical Rule (68–95–99.7)");
+BEGIN_PGML
+For a normal (bell-shaped) distribution, the empirical rule says approximately:
+
+- About [`` 0.68 ``] of the area is between [`` \mu-\sigma ``] and [`` \mu+\sigma ``].
+- About [`` 0.95 ``] of the area is between [`` \mu-2\sigma ``] and [`` \mu+2\sigma ``].
+- About [`` 0.997 ``] of the area is between [`` \mu-3\sigma ``] and [`` \mu+3\sigma ``].
+
+1) Empirical Rule, find [`` P(\mu< X< \mu+\sigma) ``].
+Answer: [____]
+
+2) Empirical Rule, find [`` P(X<\mu-2\sigma) ``].
+Answer: [____]
+END_PGML
+ANS($cmp_half68);
+ANS($cmp_tail2);
+Section::End();
+
+Section::Begin("Use the empirical rule to answer (a)–(e)");
+BEGIN_PGML
+First, notice how the given numbers line up with [`` \mu ``] and [`` \sigma ``]:
+
+- [`` 72 ``] is [`` \mu+\sigma ``] because [`` 72-69.5=2.5=\sigma ``].
+- [`` 67 ``] is [`` \mu-\sigma ``] because [`` 69.5-67=2.5=\sigma ``].
+- [`` 64.5 ``] is [`` \mu-2\sigma ``] and [`` 74.5 ``] is [`` \mu+2\sigma ``] because they are 5 inches from the mean and [`` 5=2\sigma ``].
+
+Now use the empirical rule areas:
+
+a) More than 69.5 inches tall means [`` X>\mu ``].
+[`` P(X>69.5)= ``] [____]
+
+b) Between 69.5 and 72 inches is from [`` \mu ``] to [`` \mu+\sigma ``].
+[`` P(69.5 "ABC", displayLabels => 0
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(can_open => "always", is_open => "always");
+} else {
+ Scaffold::Begin(open_one_at_a_time => 1, can_open => "when_previous_correct");
+}
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+In this guided problem we are going to practice the **normal distribution** (the famous "bell curve") and the **empirical rule** (also called the 68–95–99.7 rule).
+
+Suppose IQ scores for a large population are approximately normally distributed with mean [`` \mu=100 ``] and standard deviation [`` \sigma=15 ``]. Let [`` X ``] be the IQ score of a randomly selected person.
+
+Use the empirical rule to approximate the following probabilities:
+
+a) [`` P(X>130) ``]
+b) [`` P(85\mu)=0.50 ``].
+- [`` \mu ``] controls the **center** (where the peak is).
+- [`` \sigma ``] controls the **spread**:
+- bigger [`` \sigma ``] → wider/flatter curve (more variability),
+- smaller [`` \sigma ``] → narrower/taller curve (less variability).
+- A valid pdf never goes below the x-axis, and the **total area** under it is 1.
+
+[@ image("1.png", width => 520, height => 300) @]*
+
+**Checkpoint:** Which statement is correct?
+
+[@ $rb_area->buttons() @]*
+END_PGML
+ANS($rb_area->cmp);
+Section::End();
+
+Section::Begin("Empirical Rule (68–95–99.7) + two building blocks");
+BEGIN_PGML
+For a normal (bell-shaped) distribution, the empirical rule says approximately:
+
+- About [`` 0.68 ``] of the area is between [`` \mu-\sigma ``] and [`` \mu+\sigma ``].
+- About [`` 0.95 ``] of the area is between [`` \mu-2\sigma ``] and [`` \mu+2\sigma ``].
+- About [`` 0.997 ``] of the area is between [`` \mu-3\sigma ``] and [`` \mu+3\sigma ``].
+
+We will also use two quick building blocks:
+
+1) Area between [`` \mu+2\sigma ``] and [`` \mu+3\sigma ``] (one side only) is
+[`` \frac{0.997-0.95}{2} ``]. Answer: [____]
+
+2) Left-tail area below [`` \mu-3\sigma ``] is
+[`` \frac{1-0.997}{2} ``]. Answer: [____]
+END_PGML
+ANS($band2to3->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 0.047) < 0.02 } => "0.047 is the TOTAL area between +-2sigma and +-3sigma. One side is half.",
+)));
+ANS($tail3->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 0.003) < 0.02 } => "0.003 is BOTH tails beyond +-3sigma. One tail is half.",
+)));
+Section::End();
+
+Section::Begin("Use the empirical rule to answer (a)–(e)");
+BEGIN_PGML
+First, match each IQ value to [`` \mu ``] and [`` \sigma ``]:
+
+- [`` 85=100-15=\mu-\sigma ``]
+- [`` 130=100+30=\mu+2\sigma ``]
+- [`` 70=100-30=\mu-2\sigma ``]
+- [`` 145=100+45=\mu+3\sigma ``]
+- [`` 55=100-45=\mu-3\sigma ``]
+
+Now use the empirical-rule areas:
+
+a) [`` P(X>130)= ``] [____]
+
+b) [`` P(85cmp);
+ANS($Pb->cmp);
+ANS($Pc->cmp);
+ANS($Pd->cmp);
+ANS($Pe->cmp);
+Section::End();
+
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning the empirical rule with normal distributions?
+Rating (enter 1-5): [___]
+END_PGML
+ ANS(Real(3)->cmp(checker => sub {
+ my ($c, $s, $ans) = @_;
+ my $v = eval { $s->value };
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ans->{score} = 1; $ans->{ans_message} = "Thanks!";
+ } else {
+ $ans->{score} = 0; $ans->{ans_message} = "Enter 1-5.";
+ }
+ return $ans->{score};
+ }));
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/pdf_quartercircle_origin_to_1_1_plus_rectangle.png b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/pdf_quartercircle_origin_to_1_1_plus_rectangle.png
new file mode 100644
index 0000000000..6e0acd477d
Binary files /dev/null and b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/pdf_quartercircle_origin_to_1_1_plus_rectangle.png differ
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/pdf_rect_triangle.png b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/pdf_rect_triangle.png
new file mode 100644
index 0000000000..4ffe555fdf
Binary files /dev/null and b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/pdf_rect_triangle.png differ
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/uniform_0_to_1.jpg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/uniform_0_to_1.jpg
new file mode 100644
index 0000000000..2ea9edd77a
Binary files /dev/null and b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/uniform_0_to_1.jpg differ
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/uniform_0_to_30.jpg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/uniform_0_to_30.jpg
new file mode 100644
index 0000000000..bc5a7ca56c
Binary files /dev/null and b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/ContinuousRandomVariables/uniform_0_to_30.jpg differ
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_BinomialRV_GuidedProblem1.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_BinomialRV_GuidedProblem1.pg
new file mode 100644
index 0000000000..c3e376a943
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_BinomialRV_GuidedProblem1.pg
@@ -0,0 +1,273 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Identifying a Binomial Random Variable + Binomial Formula (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Random Variables)
+## Level(2)
+## KEYWORDS('binomial distribution','binomial random variable','probability formula','expected value','variance','standard deviation')
+## Static(1)
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE by default)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Robust Library Browser detection (LB / SetMaker preview)
+# ----------------------------------------------------------------
+$inLibraryBrowser = 0;
+if (defined($envir{isLibrary}) && $envir{isLibrary}) { $inLibraryBrowser = 1; }
+if (defined($envir{isLibraryBrowser}) && $envir{isLibraryBrowser}) { $inLibraryBrowser = 1; }
+if (defined($main::displayMode) && $main::displayMode eq 'TeXML') { $inLibraryBrowser = 1; }
+
+# Disable rating in LB to reduce preview failures
+if ($inLibraryBrowser) { $ENABLE_GP_RATING = 0; }
+
+# =======================================================
+# Context & Binomial Parameters (correct option is D)
+# =======================================================
+Context("Numeric");
+
+$n = Real(6);
+$p = Compute("1/6");
+
+$EX = Compute("1"); # np
+$Var = Compute("5/6"); # np(1-p)
+$Sig = Compute("sqrt(5/6)");
+
+$P0 = Compute("(5/6)^6");
+$P1 = Compute("6*(1/6)*(5/6)^5");
+$P2 = Compute("15*(1/6)^2*(5/6)^4");
+$Ple2 = Compute("(5/6)^6 + 6*(1/6)*(5/6)^5 + 15*(1/6)^2*(5/6)^4");
+
+# =======================================================
+# RadioButtons
+# =======================================================
+
+$rb_pick = RadioButtons(
+ ["Option A", "Option B", "Option C", "Option D", "Option E"],
+ 3, # Index of Option D
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+$rb_whyA = RadioButtons(
+ [
+ "Because X is the sum of results, not a count of successes.",
+ "Because the success probability changes from draw to draw (no replacement).",
+ "Because the number of trials is not fixed.",
+ "Because each trial has more than two outcomes.",
+ "Because probabilities cannot add to 1.",
+ ],
+ 1,
+ labels => "ABC",
+);
+
+$rb_whyB = RadioButtons(
+ [
+ "Because the number of trials is not fixed.",
+ "Because X is not counting successes; it is adding the outcomes.",
+ "Because p changes from trial to trial.",
+ "Because the trials are not independent.",
+ "Because there are no successes or failures.",
+ ],
+ 1,
+ labels => "ABC",
+);
+
+$rb_whyC = RadioButtons(
+ [
+ "Because the probability of success is not constant.",
+ "Because the number of trials is not fixed in advance.",
+ "Because X is the sum of outcomes.",
+ "Because each trial has more than two outcomes.",
+ "Because probabilities cannot add to 1.",
+ ],
+ 1,
+ labels => "ABC",
+);
+
+$rb_whyE = RadioButtons(
+ [
+ "Because the success probability changes from selection to selection (no replacement).",
+ "Because X is the sum of outcomes.",
+ "Because the number of trials is not fixed.",
+ "Because the outcomes are not equally likely.",
+ "Because there are more than two outcomes per trial.",
+ ],
+ 0,
+ labels => "ABC",
+);
+
+# =======================================================
+# Evaluators (with AnswerHints)
+# =======================================================
+
+$cmp_n = $n->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 4) < 1e-6 } => "Count the number of trials (rolls) in the binomial option.",
+));
+
+$cmp_p = $p->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (5/6)) < 1e-6 } => "5/6 is the probability of NOT rolling a 6. Use p=1/6.",
+));
+
+$cmp_EX = $EX->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 6) < 1e-6 } => "Use E(X)=np with p=1/6.",
+));
+
+$cmp_Var = $Var->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (5/36)) < 1e-6 } => "Don't forget the factor n in Var(X)=np(1-p).",
+));
+
+$cmp_Peq2 = $P2->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (1/6)) < 1e-6 } => "Use the binomial formula with n=6 and x=2.",
+));
+
+$cmp_Ple2 = $Ple2->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - $P2->value) < 1e-6 } => "For P(X<=2), add P(0)+P(1)+P(2).",
+));
+
+$cmp_Sig = $Sig->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (5/6)) < 1e-6 } => "Standard deviation is the square root of the variance.",
+));
+
+if ($ENABLE_GP_RATING) {
+ $cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = eval { $student->value };
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ansHash->{score} = 1; $ansHash->{ans_message} = "Thanks!";
+ } else {
+ $ansHash->{score} = 0; $ansHash->{ans_message} = "Enter 1 to 5.";
+ }
+ return $ansHash->{score};
+ }
+ );
+}
+
+# =======================================================
+# Main Problem Rendering
+# =======================================================
+
+# 1. Force a top-level render so the Library Browser "wakes up"
+BEGIN_PGML
+## Guided Problem: Identifying a Binomial Random Variable
+END_PGML
+
+# 2. Start Scaffold (Force open for LB preview)
+if ($inLibraryBrowser) {
+ Scaffold::Begin(can_open => "always", is_open => "always");
+} else {
+ Scaffold::Begin();
+}
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+Five discrete random variables are described below. Exactly **one** of them is binomial.
+
+* **Option A:** Draw 5 cards from a standard deck **without replacement**. Let [`` X ``] be the number of hearts drawn.
+* **Option B:** Roll a fair die 6 times. Let [`` X ``] be the **sum** of the 6 results.
+* **Option C:** Flip a fair coin until the first head occurs. Let [`` X ``] be the number of flips.
+* **Option D:** Roll a fair die 6 times. Let [`` X ``] be the number of times the result is 6.
+* **Option E:** Select 10 light bulbs from a box of 20 bulbs (4 are defective) **without replacement**. Let [`` X ``] be the number of defective bulbs selected.
+
+We are going to figure out which option describes a binomial random variable.
+END_PGML
+Section::End();
+
+Section::Begin("Definition");
+BEGIN_PGML
+A random variable [`` X ``] has a **binomial distribution** with parameters [`` n ``] and [`` p ``] if:
+
+1. There are [`` n ``] identical and independent trials of a common procedure.
+2. Each trial has exactly two outcomes: success or failure.
+3. The probability of success on any one trial is the same number [`` p ``].
+4. [`` X ``] counts the number of successes in the [`` n ``] trials.
+
+Based on the definition, which option is binomial?
+
+[@ $rb_pick->buttons() @]*
+END_PGML
+ANS($rb_pick->cmp);
+Section::End();
+
+Section::Begin("Why the other options are not binomial");
+BEGIN_PGML
+**Option A:** Why is Option A not binomial?
+[@ $rb_whyA->buttons() @]*
+
+**Option B:** Why is Option B not binomial?
+[@ $rb_whyB->buttons() @]*
+
+**Option C:** Why is Option C not binomial?
+[@ $rb_whyC->buttons() @]*
+
+**Option E:** Why is Option E not binomial?
+[@ $rb_whyE->buttons() @]*
+END_PGML
+ANS($rb_whyA->cmp);
+ANS($rb_whyB->cmp);
+ANS($rb_whyC->cmp);
+ANS($rb_whyE->cmp);
+Section::End();
+
+Section::Begin("Identify the parameters n and p");
+BEGIN_PGML
+Now focus on the binomial option.
+- A "trial" is one roll of the die.
+- A "success" is rolling a 6.
+
+1) [`` n= ``] [____]{$cmp_n}
+2) [`` p= ``] [____]{$cmp_p}
+END_PGML
+Section::End();
+
+Section::Begin("Formula, mean, and variance");
+BEGIN_PGML
+**Binomial probability formula:** For [`` x=0,1,2,\dots,n ``], [`` P(X=x)=\binom{n}{x}p^x(1-p)^{n-x} ``]
+
+**Mean and variance:** [`` E(X)=np ``], [`` \mathrm{Var}(X)=np(1-p) ``]
+
+1) [`` E(X)= ``] [____]{$cmp_EX}
+2) [`` \mathrm{Var}(X)= ``] [____]{$cmp_Var}
+END_PGML
+Section::End();
+
+Section::Begin("Compute probabilities and sigma_X");
+BEGIN_PGML
+1) Compute [`` P(X=2) ``]: [____]{$cmp_Peq2}
+2) Compute [`` P(X \le 2) ``]: [____]{$cmp_Ple2}
+3) Compute the standard deviation: [`` \sigma_X=\sqrt{\mathrm{Var}(X)}= ``] [____]{$cmp_Sig}
+END_PGML
+Section::End();
+
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+ How useful was this guided problem (1-5)? [___]{$cmp_rating}
+ END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_BinomialRV_GuidedProblem2.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_BinomialRV_GuidedProblem2.pg
new file mode 100644
index 0000000000..c00559062b
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_BinomialRV_GuidedProblem2.pg
@@ -0,0 +1,286 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Identifying a Binomial Random Variable + Binomial Formula (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Random Variables)
+## Level(2)
+## KEYWORDS('binomial distribution','binomial random variable','probability formula','expected value','variance','standard deviation')
+## Static(1)
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE by default)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Robust Library Browser detection (LB / SetMaker preview)
+# ----------------------------------------------------------------
+$inLibraryBrowser = 0;
+if (defined($envir{isLibrary}) && $envir{isLibrary}) { $inLibraryBrowser = 1; }
+if (defined($envir{isLibraryBrowser}) && $envir{isLibraryBrowser}) { $inLibraryBrowser = 1; }
+if (defined($main::displayMode) && $main::displayMode eq 'TeXML') { $inLibraryBrowser = 1; }
+
+# Disable rating in LB to reduce preview failures
+if ($inLibraryBrowser) { $ENABLE_GP_RATING = 0; }
+
+# =======================================================
+# Context & Binomial Parameters (correct option is C)
+# =======================================================
+Context("Numeric");
+
+# Option C: n=50, p=0.03
+$n = Real(50);
+$p = Compute("3/100");
+
+$EX = Compute("50*(3/100)"); # np
+$Var = Compute("50*(3/100)*(97/100)"); # np(1-p)
+$Sig = Compute("sqrt(50*(3/100)*(97/100))");
+
+$P0 = Compute("(97/100)^50");
+$P1 = Compute("50*(3/100)*(97/100)^49");
+$P2 = Compute("1225*(3/100)^2*(97/100)^48"); # C(50,2)=1225
+$Ple2 = Compute("(97/100)^50 + 50*(3/100)*(97/100)^49 + 1225*(3/100)^2*(97/100)^48");
+
+# =======================================================
+# RadioButtons
+# =======================================================
+
+$rb_pick = RadioButtons(
+ ["Option A", "Option B", "Option C", "Option D", "Option E"],
+ 2, # Index of Option C
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+$rb_whyA = RadioButtons(
+ [
+ "Because X is the sum of results, not a count of successes.",
+ "Because there is no fixed number of identical trials; it counts events in a time interval.",
+ "Because the success probability changes from draw to draw (no replacement).",
+ "Because each trial has more than two outcomes.",
+ "Because probabilities cannot add to 1.",
+ ],
+ 1,
+ labels => "ABC",
+);
+
+$rb_whyB = RadioButtons(
+ [
+ "Because the number of trials is not fixed in advance (you stop when you reach 5 successes).",
+ "Because X is not counting successes; it is adding outcomes.",
+ "Because the success probability changes from draw to draw (no replacement).",
+ "Because each trial has more than two outcomes.",
+ "Because probabilities cannot add to 1.",
+ ],
+ 0,
+ labels => "ABC",
+);
+
+$rb_whyD = RadioButtons(
+ [
+ "Because the success probability changes from selection to selection (no replacement).",
+ "Because the number of trials is not fixed.",
+ "Because X is the sum of outcomes.",
+ "Because each trial has more than two outcomes.",
+ "Because probabilities cannot add to 1.",
+ ],
+ 0,
+ labels => "ABC",
+);
+
+$rb_whyE = RadioButtons(
+ [
+ "Because the number of trials is not fixed.",
+ "Because X is not counting successes in repeated success/failure trials; it is a function of two dice.",
+ "Because the success probability changes from trial to trial.",
+ "Because each trial has more than two outcomes.",
+ "Because probabilities cannot add to 1.",
+ ],
+ 1,
+ labels => "ABC",
+);
+
+# =======================================================
+# Evaluators (with AnswerHints)
+# =======================================================
+
+$cmp_n = $n->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 10) < 1e-6 } => "10 is used in Option D (club size). For the binomial option, n is the number of chips tested.",
+ sub { abs($_[0] - 5) < 1e-6 } => "5 is the number of made baskets in Option B. For the binomial option, n is the number of chips tested.",
+));
+
+$cmp_p = $p->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (97/100)) < 1e-6 } => "97/100 is the probability a chip is NOT defective. Here p is the probability a chip IS defective.",
+ sub { abs($_[0] - 0.3) < 1e-6 } => "Careful: 3 percent means 0.03, not 0.3.",
+));
+
+$cmp_EX = $EX->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (3/100)) < 1e-6 } => "3/100 is p. The mean is E(X)=np.",
+ sub { abs($_[0] - 50) < 1e-6 } => "50 is n. The mean is E(X)=np.",
+));
+
+$cmp_Var = $Var->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (3/100)*(97/100)) < 1e-6 } => "That is p(1-p). Don't forget the factor n in Var(X)=np(1-p).",
+));
+
+$cmp_Peq2 = $P2->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (3/100)) < 1e-6 } => "3/100 is p for one trial. For P(X=2), use C(n,2)p^2(1-p)^(n-2).",
+ sub { abs($_[0] - (50*(3/100)*(97/100)^49)) < 1e-6 } => "That looks like P(X=1). For P(X=2), you need the C(n,2) term.",
+));
+
+$cmp_Ple2 = $Ple2->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - $P2->value) < 1e-6 } => "For P(X<=2), add P(0)+P(1)+P(2).",
+));
+
+$cmp_Sig = $Sig->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - $Var->value) < 1e-6 } => "That is the variance. Standard deviation is the square root of the variance.",
+));
+
+if ($ENABLE_GP_RATING) {
+ $cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = eval { $student->value };
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ansHash->{score} = 1; $ansHash->{ans_message} = "Thanks!";
+ } else {
+ $ansHash->{score} = 0; $ansHash->{ans_message} = "Enter 1 to 5.";
+ }
+ return $ansHash->{score};
+ }
+ );
+}
+
+# =======================================================
+# Main Problem Rendering
+# =======================================================
+
+BEGIN_PGML
+## Guided Problem: Identifying a Binomial Random Variable
+END_PGML
+
+if ($inLibraryBrowser) {
+ Scaffold::Begin(can_open => "always", is_open => "always");
+} else {
+ Scaffold::Begin(open_one_at_a_time => 1, can_open => "when_previous_correct");
+}
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+Five discrete random variables are described below. Exactly **one** of them is binomial.
+
+* **Option A:** A call center receives an average of 8 calls per hour. Let [`` X ``] be the number of calls received between 10:00 AM and 10:30 AM.
+* **Option B:** A basketball player has a 70 percent free-throw average. They practice by shooting until they successfully make 5 baskets. Let [`` X ``] be the total number of shots they had to take.
+* **Option C:** A manufacturer knows that 3 percent of their computer chips are defective. They randomly select 50 chips from a massive production line to test. Let [`` X ``] be the number of defective chips in the sample.
+* **Option D:** A small club has 10 members: 6 students and 4 faculty. A committee of 3 members is chosen at random. Let [`` X ``] be the number of faculty members on the committee.
+* **Option E:** You roll two fair 6-sided dice. Let [`` X ``] be the absolute difference between the two numbers shown.
+
+We are going to figure out which option describes a binomial random variable.
+END_PGML
+Section::End();
+
+Section::Begin("Definition");
+
+BEGIN_PGML
+A random variable [`` X ``] has a **binomial distribution** with parameters [`` n ``] and [`` p ``] if:
+
+1. There are [`` n ``] identical and independent trials of a common procedure.
+2. Each trial has exactly two outcomes: success or failure.
+3. The probability of success on any one trial is the same number [`` p ``].
+4. [`` X ``] counts the number of successes in the [`` n ``] trials.
+
+Based on the definition, which option is binomial?
+
+[@ $rb_pick->buttons() @]*
+END_PGML
+ANS($rb_pick->cmp);
+Section::End();
+
+Section::Begin("Why the other options are not binomial");
+BEGIN_PGML
+**Option A:** Why is Option A not binomial?
+[@ $rb_whyA->buttons() @]*
+
+**Option B:** Why is Option B not binomial?
+[@ $rb_whyB->buttons() @]*
+
+**Option D:** Why is Option D not binomial?
+[@ $rb_whyD->buttons() @]*
+
+**Option E:** Why is Option E not binomial?
+[@ $rb_whyE->buttons() @]*
+END_PGML
+ANS($rb_whyA->cmp);
+ANS($rb_whyB->cmp);
+ANS($rb_whyD->cmp);
+ANS($rb_whyE->cmp);
+Section::End();
+
+Section::Begin("Identify the parameters n and p");
+BEGIN_PGML
+Now focus on the binomial option.
+
+- A "trial" is testing one chip.
+- A "success" is finding a defective chip.
+
+1) [`` n= ``] [____]
+2) [`` p= ``] [____]
+END_PGML
+ANS($cmp_n);
+ANS($cmp_p);
+Section::End();
+
+Section::Begin("Formula, mean, and variance");
+BEGIN_PGML
+**Binomial probability formula:** For [`` x=0,1,2,\dots,n ``], [`` P(X=x)=\binom{n}{x}p^x(1-p)^{n-x} ``]
+
+**Mean and variance:** [`` E(X)=np ``], [`` \mathrm{Var}(X)=np(1-p) ``]
+
+1) [`` E(X)= ``] [____]
+2) [`` \mathrm{Var}(X)= ``] [____]
+END_PGML
+ANS($cmp_EX);
+ANS($cmp_Var);
+Section::End();
+
+Section::Begin("Compute probabilities and sigma_X");
+BEGIN_PGML
+1) Compute [`` P(X=2) ``]: [____]
+2) Compute [`` P(X \le 2) ``]: [____]
+3) Compute the standard deviation: [`` \sigma_X=\sqrt{\mathrm{Var}(X)}= ``] [____]
+END_PGML
+ANS($cmp_Peq2);
+ANS($cmp_Ple2);
+ANS($cmp_Sig);
+Section::End();
+
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+ How useful was this guided problem (1-5)? [___]
+ END_PGML
+ ANS($cmp_rating);
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_BinomialRV_GuidedProblem3.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_BinomialRV_GuidedProblem3.pg
new file mode 100644
index 0000000000..b1b4e6346e
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_BinomialRV_GuidedProblem3.pg
@@ -0,0 +1,254 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Identifying a Binomial Random Variable (Marbles & Replacement)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi / Gemini AI)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Random Variables)
+## Level(2)
+## KEYWORDS('binomial distribution','binomial random variable','probability formula','expected value','variance','standard deviation')
+## Static(1)
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# Robust Library Browser detection
+# ----------------------------------------------------------------
+$inLibraryBrowser = 0;
+if (defined($envir{isLibrary}) && $envir{isLibrary}) { $inLibraryBrowser = 1; }
+if (defined($envir{isLibraryBrowser}) && $envir{isLibraryBrowser}) { $inLibraryBrowser = 1; }
+if (defined($main::displayMode) && $main::displayMode eq 'TeXML') { $inLibraryBrowser = 1; }
+
+# Disable rating in LB to reduce preview failures
+$ENABLE_GP_RATING = $inLibraryBrowser ? 0 : 1;
+
+# =======================================================
+# Context & Binomial Parameters (Option E is Binomial)
+# =======================================================
+Context("Numeric");
+
+$n = Real(15);
+$p = Compute("0.20");
+$q = Compute("0.80");
+
+$EX = Compute("$n * $p");
+$Var = Compute("$n * $p * $q");
+$Sig = Compute("sqrt($Var)");
+
+# P(X=2) = C(15,2) * (0.2^2) * (0.8^13)
+$P2 = Compute("105 * (0.2**2) * (0.8**13)");
+# P(X<=2) = P(0) + P(1) + P(2)
+$P0 = Compute("0.8**15");
+$P1 = Compute("15 * 0.2 * 0.8**14");
+$Ple2 = Compute("$P0 + $P1 + $P2");
+
+# =======================================================
+# RadioButtons
+# =======================================================
+
+$rb_pick = RadioButtons(
+ ["Option A", "Option B", "Option C", "Option D", "Option E"],
+ 4, # Index of Option E
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+$rb_whyA = RadioButtons(
+ [
+ "Because X is the sum of results, not a count of successes.",
+ "Because there is no fixed number of identical trials; it counts events in a time interval.",
+ "Because the success probability changes from draw to draw.",
+ "Because each trial has more than two outcomes.",
+ "Because probabilities cannot add to 1.",
+ ],
+ 1, labels => "ABC"
+);
+
+$rb_whyB = RadioButtons(
+ [
+ "Because the number of trials is not fixed.",
+ "Because the probability of success (p) is not constant over the shift.",
+ "Because X is not counting successes; it is adding the outcomes.",
+ "Because the trials are not independent.",
+ "Because there are no successes or failures.",
+ ],
+ 1, labels => "ABC"
+);
+
+$rb_whyC = RadioButtons(
+ [
+ "Because the probability of success is not constant.",
+ "Because the number of trials is not fixed in advance (you stop when you reach 3 successes).",
+ "Because X is the sum of outcomes.",
+ "Because each trial has more than two outcomes.",
+ "Because probabilities cannot add to 1.",
+ ],
+ 1, labels => "ABC"
+);
+
+$rb_whyD = RadioButtons(
+ [
+ "Because the trials are not independent (outcome of one shot changes the probability of the next).",
+ "Because X is the sum of outcomes.",
+ "Because the number of trials is not fixed.",
+ "Because the outcomes are not equally likely.",
+ "Because there are more than two outcomes per trial.",
+ ],
+ 0, labels => "ABC"
+);
+
+# =======================================================
+# Evaluators
+# =======================================================
+$cmp_n = $n->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 15) > 1e-6 } => "Check the number of marbles selected in the binomial scenario.",
+));
+
+$cmp_p = $p->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 0.80) < 1e-6 } => "0.80 is the probability of NOT picking a blue marble (q).",
+));
+
+if ($ENABLE_GP_RATING) {
+ $cmp_rating = Real(3)->cmp(checker => sub {
+ my ($c, $s, $ans) = @_;
+ my $v = eval { $s->value };
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ans->{score} = 1; $ans->{ans_message} = "Thanks!";
+ } else {
+ $ans->{score} = 0; $ans->{ans_message} = "Enter 1 to 5.";
+ }
+ return $ans->{score};
+ });
+}
+
+# =======================================================
+# Main Problem Rendering
+# =======================================================
+
+BEGIN_PGML
+## Guided Problem: Identifying a Binomial Random Variable
+END_PGML
+
+if ($inLibraryBrowser) {
+ Scaffold::Begin(can_open => "always", is_open => "always");
+} else {
+ Scaffold::Begin(open_one_at_a_time => 1, can_open => "when_previous_correct");
+}
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+Five discrete random variables are described below. Exactly **one** of them is binomial.
+
+* **Option A:** A radioactive source emits particles at a rate of 5 per minute. Let [`` X ``] be the number of particles detected in the first 2 minutes.
+* **Option B:** A quality control inspector tests components from a large batch. The probability of a defect is 2% for the first hour of a shift but increases by 0.5% every hour as the machine heats up. Let [`` X ``] be the number of defects found in a sample of 40 components over a 4-hour shift.
+* **Option C:** A software developer is fixing bugs. The probability of fixing a bug on the first attempt is 0.8. They work until they have fixed exactly 3 bugs. Let [`` X ``] be the total number of attempts they had to make.
+* **Option D:** A hunter is aiming at a target. He fires 10 shots. For each shot, if he hits the target, he becomes more confident and his probability of hitting the next shot increases. Let [`` X ``] be the number of hits in 10 shots.
+* **Option E:** A large bag contains thousands of marbles, 20% of which are blue. You reach in and select 15 marbles one by one, replacing each marble before picking the next. Let [`` X ``] be the number of blue marbles selected.
+
+We are going to figure out which option describes a binomial random variable.
+END_PGML
+Section::End();
+
+Section::Begin("Definition");
+
+BEGIN_PGML
+A random variable [`` X ``] has a **binomial distribution** with parameters [`` n ``] and [`` p ``] if:
+
+1. There are [`` n ``] identical and independent trials of a common procedure.
+2. Each trial has exactly two outcomes: success or failure.
+3. The probability of success on any one trial is the same number [`` p ``].
+4. [`` X ``] counts the number of successes in the [`` n ``] trials.
+
+Based on the definition, which option is binomial?
+
+[@ $rb_pick->buttons() @]*
+END_PGML
+ANS($rb_pick->cmp);
+Section::End();
+
+Section::Begin("Why the other options are not binomial");
+BEGIN_PGML
+For each option that is **not** binomial, choose the best reason.
+
+**Option A:** Why is Option A not binomial?
+[@ $rb_whyA->buttons() @]*
+
+**Option B:** Why is Option B not binomial?
+[@ $rb_whyB->buttons() @]*
+
+**Option C:** Why is Option C not binomial?
+[@ $rb_whyC->buttons() @]*
+
+**Option D:** Why is Option D not binomial?
+[@ $rb_whyD->buttons() @]*
+END_PGML
+ANS($rb_whyA->cmp);
+ANS($rb_whyB->cmp);
+ANS($rb_whyC->cmp);
+ANS($rb_whyD->cmp);
+Section::End();
+
+Section::Begin("Identify the parameters n and p");
+BEGIN_PGML
+Now focus on the binomial option.
+
+- A "trial" is selecting one marble.
+- A "success" is selecting a blue marble.
+
+1) [`` n= ``] [____]
+2) [`` p= ``] [____]
+END_PGML
+ANS($cmp_n);
+ANS($cmp_p);
+Section::End();
+
+Section::Begin("Formula, mean, and variance");
+BEGIN_PGML
+**Binomial probability formula:** For [`` x=0,1,2,\dots,n ``], [`` P(X=x)=\binom{n}{x}p^x(1-p)^{n-x} ``]
+
+**Mean and variance:** [`` E(X)=np ``], [`` \mathrm{Var}(X)=np(1-p) ``]
+
+1) [`` E(X)= ``] [____]
+2) [`` \mathrm{Var}(X)= ``] [____]
+END_PGML
+ANS($EX->cmp);
+ANS($Var->cmp);
+Section::End();
+
+Section::Begin("Compute probabilities and sigma_X");
+BEGIN_PGML
+1) Compute [`` P(X=2) ``]: [____]
+2) Compute [`` P(X \le 2) ``]: [____]
+3) Compute the standard deviation: [`` \sigma_X=\sqrt{\mathrm{Var}(X)}= ``] [____]
+END_PGML
+ANS($P2->cmp);
+ANS($Ple2->cmp);
+ANS($Sig->cmp);
+Section::End();
+
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+ How useful was this guided problem (1-5)? [___]
+ END_PGML
+ ANS($cmp_rating);
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_BinomialRV_GuidedProblem4.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_BinomialRV_GuidedProblem4.pg
new file mode 100644
index 0000000000..a13cef101d
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_BinomialRV_GuidedProblem4.pg
@@ -0,0 +1,285 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Binomial Counting: Parts Needed for 5 Service Calls (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Random Variables)
+## Level(2)
+## KEYWORDS('binomial','probability distribution','discrete random variable','at most','cumulative probability')
+## Static(1)
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser flag (hide rating in LB)
+# ----------------------------------------------------------------
+$inLibraryBrowser = 0;
+if (defined($envir{isLibrary}) && $envir{isLibrary}) { $inLibraryBrowser = 1; }
+if (defined($envir{isLibraryBrowser}) && $envir{isLibraryBrowser}) { $inLibraryBrowser = 1; }
+
+# =======================================================
+# Context & Data
+# =======================================================
+Context("Numeric");
+
+# X = number of calls (out of 5) that require the part
+# p = 1/3, q = 2/3
+$p = Compute("1/3");
+$q = Compute("2/3");
+
+# Binomial probabilities for n=5
+$P0 = Compute("(2/3)^5");
+$P1 = Compute("5*(1/3)*(2/3)^4");
+$P2 = Compute("10*(1/3)^2*(2/3)^3");
+$P3 = Compute("10*(1/3)^3*(2/3)^2");
+$P4 = Compute("5*(1/3)^4*(2/3)");
+$P5 = Compute("(1/3)^5");
+
+$sumP = Compute("1");
+
+# Cumulative probabilities
+$C0 = Compute($P0->string);
+$C1 = Compute($P0->string . " + " . $P1->string);
+$C2 = Compute($P0->string . " + " . $P1->string . " + " . $P2->string);
+$C3 = Compute($P0->string . " + " . $P1->string . " + " . $P2->string . " + " . $P3->string);
+$C4 = Compute($P0->string . " + " . $P1->string . " + " . $P2->string . " + " . $P3->string . " + " . $P4->string);
+$C5 = Compute("1");
+
+# Part (a)
+$PatMost1 = $C1;
+
+# Part (b) minimum m with P(X<=m) >= 0.95
+$minParts = Real(3);
+
+# =======================================================
+# Evaluators
+# =======================================================
+
+$cmp_n_calls = Real(5)->cmp;
+$cmp_minX = Real(0)->cmp;
+$cmp_maxX = Real(5)->cmp;
+$cmp_kvals = Real(6)->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 5) < 1e-6 } => "X can be 0,1,2,3,4,5 (that is 6 possible values)."
+));
+
+$cmp_p0 = $P0->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (1/3)**5) < 1e-6 } => "That would be the probability all 5 calls require the part. For X=0 you want no successes: (2/3)^5."
+));
+$cmp_p1 = $P1->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (2/3)**5) < 1e-6 } => "That is P(X=0). For X=1 you need exactly one success: C(5,1)(1/3)^1(2/3)^4."
+));
+
+$cmp_atMost1 = $PatMost1->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - $P1->value) < 1e-6 } => "At most 1 means X=0 or X=1. Add P(0)+P(1)."
+));
+
+$cmp_minParts = $minParts->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = eval { $student->value };
+ if (!defined($v) || $v != int($v) || $v < 0 || $v > 5) {
+ $ansHash->{ans_message} = "Enter an integer from 0 to 5.";
+ return 0;
+ }
+ return ($v == 3) ? 1 : 0;
+ }
+);
+
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($c, $s, $ans) = @_;
+ my $v = eval { $s->value };
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ans->{score} = 1; $ans->{ans_message} = "Thanks!";
+ } else {
+ $ans->{score} = 0; $ans->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+ return $ans->{score};
+ }
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+
+# Force scaffold open for Library Browser
+if ($inLibraryBrowser) {
+ Scaffold::Begin(can_open => "always", is_open => "always");
+} else {
+ Scaffold::Begin(open_one_at_a_time => 1, can_open => "when_previous_correct");
+}
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+An appliance repairman services five washing machines on site each day.
+One-third of the service calls require installation of a particular part.
+
+Let [`` X ``] be the number (out of 5) that require this part.
+
+a) The repairman has only one such part on his truck today. Find the probability that the one part will be enough today (that is, [`` X \le 1 ``]).
+b) Find the minimum number of such parts he should take each day so that the probability he has enough is at least 95%.
+END_PGML
+Section::End();
+
+Section::Begin("Outcomes and possible values of X");
+BEGIN_PGML
+Each service call can be thought of as:
+
+- Success (S): the machine requires the part, with probability [`` 1/3 ``]
+- Failure (F): it does not require the part, with probability [`` 2/3 ``]
+
+The random variable counts successes in 5 calls:
+[`` X = \text{number of S in 5 calls} ``]
+
+1) How many service calls are there each day? [____]{$cmp_n_calls}
+
+2) Smallest possible value of [`` X ``]: [____]{$cmp_minX}
+
+3) Largest possible value of [`` X ``]: [____]{$cmp_maxX}
+
+4) How many possible values can [`` X ``] take? [____]{$cmp_kvals}
+END_PGML
+Section::End();
+
+Section::Begin("Quick reminders (binomial probabilities)");
+BEGIN_PGML
+This is a binomial setting: each call is independent, and the probability of "requires the part" is the same each time.
+
+For [`` k=0,1,2,3,4,5 ``]:
+[`` P(X=k)=\binom{5}{k}\left(\frac{1}{3}\right)^k\left(\frac{2}{3}\right)^{5-k} ``]
+END_PGML
+Section::End();
+
+Section::Begin("Construct the probability distribution of X");
+BEGIN_PGML
+Fill in the probability distribution table for [`` X ``]. (Fractions are fine.)
+END_PGML
+
+BEGIN_TEXT
+$BCENTER
+
+
+ | \(x\) |
+ \(P(X=x)\) |
+
+ | 0 | \{ NAMED_ANS_RULE("p0",12) \} |
+ | 1 | \{ NAMED_ANS_RULE("p1",12) \} |
+ | 2 | \{ NAMED_ANS_RULE("p2",12) \} |
+ | 3 | \{ NAMED_ANS_RULE("p3",12) \} |
+ | 4 | \{ NAMED_ANS_RULE("p4",12) \} |
+ | 5 | \{ NAMED_ANS_RULE("p5",12) \} |
+
+$ECENTER
+END_TEXT
+
+NAMED_ANS("p0", $cmp_p0);
+NAMED_ANS("p1", $cmp_p1);
+NAMED_ANS("p2", $P2->cmp);
+NAMED_ANS("p3", $P3->cmp);
+NAMED_ANS("p4", $P4->cmp);
+NAMED_ANS("p5", $P5->cmp);
+
+Section::End();
+
+Section::Begin("Check the probability distribution");
+BEGIN_PGML
+Check that the probabilities add to 1:
+
+[`` P(0)+P(1)+P(2)+P(3)+P(4)+P(5)= ``] [____]{$sumP->cmp}
+END_PGML
+Section::End();
+
+Section::Begin("At most one part is needed (Part a)");
+BEGIN_PGML
+"One part is enough" means **at most one** machine requires the part:
+
+[`` X \le 1 ``] means [`` X=0 ``] or [`` X=1 ``].
+
+Compute:
+[`` P(X \le 1)=P(X=0)+P(X=1)= ``] [____]{$cmp_atMost1}
+END_PGML
+Section::End();
+
+Section::Begin("How many parts for at least 95%? (Part b)");
+BEGIN_PGML
+If the repairman carries [`` m ``] parts, then he has enough exactly when [`` X \le m ``].
+
+So we want the **smallest** [`` m ``] such that:
+[`` P(X \le m) \ge 0.95 ``]
+
+Compute cumulative probabilities:
+END_PGML
+
+BEGIN_TEXT
+$BCENTER
+
+
+ | \(m\) |
+ \(P(X \le m)\) |
+
+ | 0 | \{ NAMED_ANS_RULE("c0",12) \} |
+ | 1 | \{ NAMED_ANS_RULE("c1",12) \} |
+ | 2 | \{ NAMED_ANS_RULE("c2",12) \} |
+ | 3 | \{ NAMED_ANS_RULE("c3",12) \} |
+ | 4 | \{ NAMED_ANS_RULE("c4",12) \} |
+ | 5 | \{ NAMED_ANS_RULE("c5",12) \} |
+
+$ECENTER
+END_TEXT
+
+NAMED_ANS("c0", $C0->cmp);
+NAMED_ANS("c1", $C1->cmp);
+NAMED_ANS("c2", $C2->cmp);
+NAMED_ANS("c3", $C3->cmp);
+NAMED_ANS("c4", $C4->cmp);
+NAMED_ANS("c5", $C5->cmp);
+
+BEGIN_PGML
+Now enter the minimum number of parts [`` m ``] that makes [`` P(X \le m)\ge 0.95 ``]:
+
+Minimum number of parts: [____]{$cmp_minParts}
+END_PGML
+Section::End();
+
+Section::Begin("Final Answer");
+BEGIN_PGML
+Enter your final results.
+
+[`` P(X\le 1)= ``] [____]{$PatMost1->cmp}
+
+Minimum number of parts [`` m= ``] [____]{$minParts->cmp}
+END_PGML
+Section::End();
+
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning binomial probability and cumulative probability?
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_ExVar_GuidedProblem1.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_ExVar_GuidedProblem1.pg
new file mode 100644
index 0000000000..9d0e9cc91a
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_ExVar_GuidedProblem1.pg
@@ -0,0 +1,302 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Mean, Variance, and Standard Deviation from a Discrete Distribution (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Random Variables)
+## Level(2)
+## KEYWORDS('expected value','mean','variance','standard deviation','discrete random variable','probability distribution')
+## Static(1)
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser flag (hide rating in LB)
+# ----------------------------------------------------------------
+$inLibraryBrowser = $main::inLibraryBrowser || 0;
+
+# =======================================================
+# Context & Data
+# =======================================================
+Context("Numeric");
+
+# Distribution (given)
+$x1 = -1; $p1 = Real(0.2);
+$x2 = 0; $p2 = Real(0.4);
+$x3 = 1; $p3 = Real(0.3);
+$x4 = 2; $p4 = Real(0.1);
+
+# Correct computed columns (do NOT display these numbers in the problem text)
+$xp1 = Real($x1)->value * $p1->value; # xP
+$xp2 = Real($x2)->value * $p2->value;
+$xp3 = Real($x3)->value * $p3->value;
+$xp4 = Real($x4)->value * $p4->value;
+
+$x2p1 = (Real($x1)->value**2) * $p1->value; # x^2 P
+$x2p2 = (Real($x2)->value**2) * $p2->value;
+$x2p3 = (Real($x3)->value**2) * $p3->value;
+$x2p4 = (Real($x4)->value**2) * $p4->value;
+
+$EX = $xp1 + $xp2 + $xp3 + $xp4;
+$EX2 = $x2p1 + $x2p2 + $x2p3 + $x2p4;
+
+$Var = $EX2 - ($EX**2);
+$Sig = sqrt($Var);
+
+# =======================================================
+# Evaluators (light, stable; hints are guidance only)
+# =======================================================
+
+sub numCmp {
+ my ($v) = @_;
+ return Real($v)->cmp;
+}
+
+sub numCmpHint {
+ my ($v, @h) = @_;
+ return Real($v)->cmp->withPostFilter(AnswerHints(@h));
+}
+
+# Row blanks (no numeric-revealing hints)
+$cmp_xp1 = numCmp($xp1);
+$cmp_xp2 = numCmp($xp2);
+$cmp_xp3 = numCmp($xp3);
+$cmp_xp4 = numCmp($xp4);
+
+$cmp_x2p1 = numCmp($x2p1);
+$cmp_x2p2 = numCmp($x2p2);
+$cmp_x2p3 = numCmp($x2p3);
+$cmp_x2p4 = numCmp($x2p4);
+
+# Totals (again, no revealing hints)
+$cmp_EX = numCmp($EX);
+$cmp_EX2 = numCmp($EX2);
+
+# Variance + sigma with guidance hints (no numbers)
+$cmp_var = numCmpHint($Var,
+ sub { abs($_[0] - $_[1]) < 1e-6 } =>
+ "Use Var(X) = E(X^2) - [E(X)]^2, using the two totals from your table.",
+);
+
+$cmp_sig = numCmpHint($Sig,
+ sub { abs($_[0] - $_[1]) < 1e-6 } =>
+ "Standard deviation is the square root of the variance: sigma_X = sqrt(Var(X)).",
+);
+
+# Final answers (three expression blanks)
+$cmp_final_EX = numCmp($EX);
+$cmp_final_var = numCmp($Var);
+$cmp_final_sig = numCmp($Sig);
+
+# =======================================================
+# Rating (1–5)
+# =======================================================
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = eval { $student->value };
+
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ansHash->{score} = 1;
+ $ansHash->{ans_message} = "Thanks!";
+ } else {
+ $ansHash->{score} = 0;
+ $ansHash->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+ return $ansHash->{score};
+ }
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin();
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A discrete random variable [`` X ``] has the following probability distribution:
+
+[`` \begin{array}{c|cccc}
+x & -1 & 0 & 1 & 2 \\
+\hline
+P(X=x) & 0.2 & 0.4 & 0.3 & 0.1
+\end{array} ``]
+
+Find:
+
+a. [`` E(X) ``]
+b. [`` \mathrm{Var}(X) ``]
+c. [`` \sigma_X ``]
+END_PGML
+Section::End();
+
+# --- Keep this section exactly in spirit: formulas + what to do ---
+Section::Begin("Quick reminders");
+BEGIN_PGML
+Use these steps and formulas:
+
+**Mean (expected value):**
+Multiply each value by its probability, then add.
+[`` E(X)=\sum x\,P(X=x) ``]
+
+**Variance:**
+First compute [`` E(X^2) ``] by squaring each [`` x ``], multiplying by its probability, then adding.
+Then:
+[`` \mathrm{Var}(X)=E(X^2)-[E(X)]^2 ``]
+
+**Standard deviation:**
+Take the square root of the variance.
+[`` \sigma_X=\sqrt{\mathrm{Var}(X)} ``]
+END_PGML
+Section::End();
+
+Section::Begin("Work table (compute E(X) and E(X^2))");
+BEGIN_PGML
+Fill the two computed columns row-by-row:
+
+- Column 3: compute [`` xP(X=x) ``]
+- Column 4: compute [`` x^2P(X=x) ``]
+
+Then add each computed column.
+The total of column 3 is [`` E(X) ``], and the total of column 4 is [`` E(X^2) ``].
+END_PGML
+
+BEGIN_TEXT
+$BCENTER
+
+
+ | \(x\) |
+ \(P(X=x)\) |
+ \(xP(X=x)\) |
+ \(x^2P(X=x)\) |
+
+
+
+ | -1 |
+ 0.2 |
+ \{ NAMED_ANS_RULE("xp1",12) \} |
+ \{ NAMED_ANS_RULE("x2p1",12) \} |
+
+
+
+ | 0 |
+ 0.4 |
+ \{ NAMED_ANS_RULE("xp2",12) \} |
+ \{ NAMED_ANS_RULE("x2p2",12) \} |
+
+
+
+ | 1 |
+ 0.3 |
+ \{ NAMED_ANS_RULE("xp3",12) \} |
+ \{ NAMED_ANS_RULE("x2p3",12) \} |
+
+
+
+ | 2 |
+ 0.1 |
+ \{ NAMED_ANS_RULE("xp4",12) \} |
+ \{ NAMED_ANS_RULE("x2p4",12) \} |
+
+
+
+ | Totals |
+
+ \{ NAMED_ANS_RULE("EX",12) \}
+ (this total is \(E(X)\))
+ |
+
+ \{ NAMED_ANS_RULE("EX2",12) \}
+ (this total is \(E(X^2)\))
+ |
+
+
+$ECENTER
+END_TEXT
+
+Section::End();
+
+# Register evaluators immediately after the table (top-to-bottom, left-to-right)
+NAMED_ANS("xp1", $cmp_xp1);
+NAMED_ANS("x2p1", $cmp_x2p1);
+
+NAMED_ANS("xp2", $cmp_xp2);
+NAMED_ANS("x2p2", $cmp_x2p2);
+
+NAMED_ANS("xp3", $cmp_xp3);
+NAMED_ANS("x2p3", $cmp_x2p3);
+
+NAMED_ANS("xp4", $cmp_xp4);
+NAMED_ANS("x2p4", $cmp_x2p4);
+
+NAMED_ANS("EX", $cmp_EX);
+NAMED_ANS("EX2", $cmp_EX2);
+
+Section::Begin("Compute Var(X) and sigma_X");
+BEGIN_PGML
+Now use your two totals from the table:
+
+1) Compute the variance:
+[`` \mathrm{Var}(X)=E(X^2)-[E(X)]^2 = ``] [____]{$cmp_var}
+
+2) Compute the standard deviation:
+[`` \sigma_X=\sqrt{\mathrm{Var}(X)} = ``] [____]{$cmp_sig}
+END_PGML
+Section::End();
+
+Section::Begin("Final Answer");
+BEGIN_PGML
+Enter your final results.
+END_PGML
+
+BEGIN_TEXT
+$PAR
+$BR \(E(X)=\) \{ NAMED_ANS_RULE("finalEX",12) \}
+$BR \(\mathrm{Var}(X)=\) \{ NAMED_ANS_RULE("finalVar",12) \}
+$BR \(\sigma_X=\) \{ NAMED_ANS_RULE("finalSig",12) \}
+END_TEXT
+
+Section::End();
+
+NAMED_ANS("finalEX", $cmp_final_EX);
+NAMED_ANS("finalVar", $cmp_final_var);
+NAMED_ANS("finalSig", $cmp_final_sig);
+
+# -------------------------------------------------------
+# Feedback (rating 1–5) (hidden in LB)
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning expected value and variance?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_ExVar_GuidedProblem2.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_ExVar_GuidedProblem2.pg
new file mode 100644
index 0000000000..6fc4af8fac
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_ExVar_GuidedProblem2.pg
@@ -0,0 +1,429 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Positive Difference of Two Dice: Distribution, Mean, Std Dev, and P(X<=2) (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Random Variables)
+## Level(2)
+## KEYWORDS('probability distribution','discrete random variable','two dice','positive difference','expected value','variance','standard deviation')
+## Static(1)
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser flag (hide rating in LB)
+# ----------------------------------------------------------------
+$inLibraryBrowser = $main::inLibraryBrowser || 0;
+
+# =======================================================
+# Context
+# =======================================================
+Context("Numeric");
+
+# =======================================================
+# True distribution for X = |D1 - D2|
+# Possible values: 0,1,2,3,4,5
+# Counts out of 36: 6,10,8,6,4,2
+# =======================================================
+$P0 = Compute("6/36");
+$P1 = Compute("10/36");
+$P2 = Compute("8/36");
+$P3 = Compute("6/36");
+$P4 = Compute("4/36");
+$P5 = Compute("2/36");
+
+$sumP = Compute("1");
+
+# Work-table columns (exact)
+$xp0 = Compute("0*(6/36)");
+$xp1 = Compute("1*(10/36)");
+$xp2 = Compute("2*(8/36)");
+$xp3 = Compute("3*(6/36)");
+$xp4 = Compute("4*(4/36)");
+$xp5 = Compute("5*(2/36)");
+
+$x2p0 = Compute("(0^2)*(6/36)");
+$x2p1 = Compute("(1^2)*(10/36)");
+$x2p2 = Compute("(2^2)*(8/36)");
+$x2p3 = Compute("(3^2)*(6/36)");
+$x2p4 = Compute("(4^2)*(4/36)");
+$x2p5 = Compute("(5^2)*(2/36)");
+
+# Totals
+$EX = Compute("35/18"); # sum xP
+$EX2 = Compute("35/6"); # sum x^2P
+$Var = Compute("665/324"); # EX2 - (EX)^2
+$Sig = Compute("sqrt(665)/18");
+
+$P_le2 = Compute("2/3");
+
+# =======================================================
+# Evaluators (stable; hints are guidance only)
+# =======================================================
+
+# Outcomes / values
+$cmp_n_outcomes = Real(36)->cmp;
+$cmp_minX = Real(0)->cmp;
+$cmp_maxX = Real(5)->cmp;
+$cmp_kvals = Real(6)->cmp;
+
+# Distribution entries (Part a)
+$cmp_p0 = $P0->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (1/6)) < 1e-6 } => "Difference 0 happens when the dice match (a double). Count those outcomes, then divide by 36.",
+));
+$cmp_p1 = $P1->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (1/3)) < 1e-6 } => "For X=1, think: the dice differ by 1 (like 2 and 3). Count ordered pairs with |i-j|=1, then divide by 36.",
+));
+$cmp_p2 = $P2->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (2/9)) < 1e-6 } => "For X=2, count ordered pairs (i,j) with |i-j|=2, then divide by 36.",
+));
+$cmp_p3 = $P3->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (1/6)) < 1e-6 } => "For X=3, count ordered pairs with |i-j|=3, then divide by 36.",
+));
+$cmp_p4 = $P4->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (1/9)) < 1e-6 } => "For X=4, the dice must be far apart (like 1 and 5). Count ordered pairs with |i-j|=4, then divide by 36.",
+));
+$cmp_p5 = $P5->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (1/18)) < 1e-6 } => "For X=5, only the most extreme faces work (1 and 6 in either order). Divide the count by 36.",
+));
+
+# Check sum to 1
+$cmp_sumP = $sumP->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (2/3)) < 1e-6 } => "2/3 is P(X<=2). Here you are checking that ALL probabilities add to 1.",
+));
+
+# Work-table: copied probabilities (to avoid AnSwEr warnings, these are NAMED and graded)
+$cmp_pw0 = $P0->cmp;
+$cmp_pw1 = $P1->cmp;
+$cmp_pw2 = $P2->cmp;
+$cmp_pw3 = $P3->cmp;
+$cmp_pw4 = $P4->cmp;
+$cmp_pw5 = $P5->cmp;
+
+# Work-table computed columns
+$cmp_xp0 = $xp0->cmp; $cmp_x2p0 = $x2p0->cmp;
+$cmp_xp1 = $xp1->cmp; $cmp_x2p1 = $x2p1->cmp;
+$cmp_xp2 = $xp2->cmp; $cmp_x2p2 = $x2p2->cmp;
+$cmp_xp3 = $xp3->cmp; $cmp_x2p3 = $x2p3->cmp;
+$cmp_xp4 = $xp4->cmp; $cmp_x2p4 = $x2p4->cmp;
+$cmp_xp5 = $xp5->cmp; $cmp_x2p5 = $x2p5->cmp;
+
+# Totals in work table
+$cmp_EX = $EX->cmp;
+$cmp_EX2 = $EX2->cmp;
+
+# Var and sigma
+$cmp_var = $Var->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - $_[1]) < 1e-6 } =>
+ "Use Var(X) = E(X^2) - [E(X)]^2, using the two totals from your work table.",
+));
+
+$cmp_sig = $Sig->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - $_[1]) < 1e-6 } =>
+ "Standard deviation is sigma_X = sqrt(Var(X)).",
+));
+
+# P(X<=2)
+$cmp_Ple2 = $P_le2->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (24/36)) < 1e-6 } =>
+ "Good setup: P(X<=2)=P(0)+P(1)+P(2). You can simplify 24/36.",
+));
+
+# Final answers
+$cmp_final_EX = $EX->cmp;
+$cmp_final_sig = $Sig->cmp;
+$cmp_final_Ple2 = $P_le2->cmp;
+
+# =======================================================
+# Rating (1–5)
+# =======================================================
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = eval { $student->value };
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ansHash->{score} = 1;
+ $ansHash->{ans_message} = "Thanks!";
+ } else {
+ $ansHash->{score} = 0;
+ $ansHash->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+ return $ansHash->{score};
+ }
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin();
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A pair of fair dice is rolled. Let [`` X ``] denote the **positive difference** of the number of dots on the top faces.
+(For example, if the dice show 2 and 5, then [`` X=3 ``].)
+
+a) Construct the probability distribution of [`` X ``].
+b) Find [`` E(X) ``].
+c) Find [`` \sigma_X ``].
+d) Find [`` P(X \le 2) ``].
+END_PGML
+Section::End();
+
+Section::Begin("Outcomes and possible values of X");
+BEGIN_PGML
+When two dice are rolled, outcomes can be represented as ordered pairs [`` (i,j) ``] where
+[`` i ``] is the first die and [`` j ``] is the second die.
+
+1) How many equally likely outcomes are there?
+
+[____]{$cmp_n_outcomes}
+
+The random variable is:
+[`` X = |i-j| ``]
+
+2) What is the smallest possible value of [`` X ``]?
+
+[____]{$cmp_minX}
+
+3) What is the largest possible value of [`` X ``]?
+
+[____]{$cmp_maxX}
+
+4) How many possible values can [`` X ``] take?
+
+[____]{$cmp_kvals}
+END_PGML
+Section::End();
+
+Section::Begin("Construct the probability distribution (Part a)");
+BEGIN_PGML
+Fill in the probability distribution table for [`` X=|i-j| ``].
+
+(You can enter probabilities as fractions, like 10/36.)
+
+After you fill it in, you will check that the probabilities add to 1.
+END_PGML
+
+BEGIN_TEXT
+$BCENTER
+
+
+ | \(x\) |
+ \(P(X=x)\) |
+
+ | 0 | \{ NAMED_ANS_RULE("p0",12) \} |
+ | 1 | \{ NAMED_ANS_RULE("p1",12) \} |
+ | 2 | \{ NAMED_ANS_RULE("p2",12) \} |
+ | 3 | \{ NAMED_ANS_RULE("p3",12) \} |
+ | 4 | \{ NAMED_ANS_RULE("p4",12) \} |
+ | 5 | \{ NAMED_ANS_RULE("p5",12) \} |
+
+$ECENTER
+END_TEXT
+
+Section::End();
+
+NAMED_ANS("p0", $cmp_p0);
+NAMED_ANS("p1", $cmp_p1);
+NAMED_ANS("p2", $cmp_p2);
+NAMED_ANS("p3", $cmp_p3);
+NAMED_ANS("p4", $cmp_p4);
+NAMED_ANS("p5", $cmp_p5);
+
+Section::Begin("Check the probability distribution");
+BEGIN_PGML
+Check that the probabilities add to 1:
+
+[`` P(X=0)+P(X=1)+P(X=2)+P(X=3)+P(X=4)+P(X=5)= ``] [____]{$cmp_sumP}
+END_PGML
+Section::End();
+
+Section::Begin("Quick reminders");
+BEGIN_PGML
+Use these steps and formulas:
+
+**Mean (expected value):**
+Multiply each value by its probability, then add.
+[`` E(X)=\sum x\,P(X=x) ``]
+
+**Variance:**
+First compute [`` E(X^2) ``] by squaring each [`` x ``], multiplying by its probability, then adding.
+Then:
+[`` \mathrm{Var}(X)=E(X^2)-[E(X)]^2 ``]
+
+**Standard deviation:**
+Take the square root of the variance.
+[`` \sigma_X=\sqrt{\mathrm{Var}(X)} ``]
+END_PGML
+Section::End();
+
+Section::Begin("Work table (compute E(X) and E(X^2))");
+BEGIN_PGML
+Copy your probabilities from Part (a) into the second column. Then compute the two calculated columns.
+
+- Column 3: compute [`` xP(X=x) ``]
+- Column 4: compute [`` x^2P(X=x) ``]
+
+Finally, add each calculated column.
+The total of column 3 is [`` E(X) ``], and the total of column 4 is [`` E(X^2) ``].
+END_PGML
+
+BEGIN_TEXT
+$BCENTER
+
+
+ | \(x\) |
+ \(P(X=x)\) |
+ \(xP(X=x)\) |
+ \(x^2P(X=x)\) |
+
+
+
+ | 0 |
+ \{ NAMED_ANS_RULE("pw0",10) \} |
+ \{ NAMED_ANS_RULE("xp0",12) \} |
+ \{ NAMED_ANS_RULE("x2p0",12) \} |
+
+
+ | 1 |
+ \{ NAMED_ANS_RULE("pw1",10) \} |
+ \{ NAMED_ANS_RULE("xp1",12) \} |
+ \{ NAMED_ANS_RULE("x2p1",12) \} |
+
+
+ | 2 |
+ \{ NAMED_ANS_RULE("pw2",10) \} |
+ \{ NAMED_ANS_RULE("xp2",12) \} |
+ \{ NAMED_ANS_RULE("x2p2",12) \} |
+
+
+ | 3 |
+ \{ NAMED_ANS_RULE("pw3",10) \} |
+ \{ NAMED_ANS_RULE("xp3",12) \} |
+ \{ NAMED_ANS_RULE("x2p3",12) \} |
+
+
+ | 4 |
+ \{ NAMED_ANS_RULE("pw4",10) \} |
+ \{ NAMED_ANS_RULE("xp4",12) \} |
+ \{ NAMED_ANS_RULE("x2p4",12) \} |
+
+
+ | 5 |
+ \{ NAMED_ANS_RULE("pw5",10) \} |
+ \{ NAMED_ANS_RULE("xp5",12) \} |
+ \{ NAMED_ANS_RULE("x2p5",12) \} |
+
+
+
+ | Totals |
+
+ \{ NAMED_ANS_RULE("EX",12) \}
+ (this total is \(E(X)\))
+ |
+
+ \{ NAMED_ANS_RULE("EX2",12) \}
+ (this total is \(E(X^2)\))
+ |
+
+
+$ECENTER
+END_TEXT
+
+Section::End();
+
+# Grade the copied probabilities (prevents AnSwEr00xx warnings)
+NAMED_ANS("pw0", $cmp_pw0);
+NAMED_ANS("pw1", $cmp_pw1);
+NAMED_ANS("pw2", $cmp_pw2);
+NAMED_ANS("pw3", $cmp_pw3);
+NAMED_ANS("pw4", $cmp_pw4);
+NAMED_ANS("pw5", $cmp_pw5);
+
+# Grade computed columns + totals
+NAMED_ANS("xp0", $cmp_xp0); NAMED_ANS("x2p0", $cmp_x2p0);
+NAMED_ANS("xp1", $cmp_xp1); NAMED_ANS("x2p1", $cmp_x2p1);
+NAMED_ANS("xp2", $cmp_xp2); NAMED_ANS("x2p2", $cmp_x2p2);
+NAMED_ANS("xp3", $cmp_xp3); NAMED_ANS("x2p3", $cmp_x2p3);
+NAMED_ANS("xp4", $cmp_xp4); NAMED_ANS("x2p4", $cmp_x2p4);
+NAMED_ANS("xp5", $cmp_xp5); NAMED_ANS("x2p5", $cmp_x2p5);
+
+NAMED_ANS("EX", $cmp_EX);
+NAMED_ANS("EX2", $cmp_EX2);
+
+Section::Begin("Compute Var(X) and sigma_X");
+BEGIN_PGML
+Now compute:
+
+1) Variance:
+[`` \mathrm{Var}(X)=E(X^2)-[E(X)]^2 = ``] [____]{$cmp_var}
+
+2) Standard deviation:
+[`` \sigma_X=\sqrt{\mathrm{Var}(X)} = ``] [____]{$cmp_sig}
+END_PGML
+Section::End();
+
+Section::Begin("Compute P(X <= 2) (Part d)");
+BEGIN_PGML
+Use your probability distribution:
+
+[`` P(X \le 2)=P(X=0)+P(X=1)+P(X=2)= ``] [____]{$cmp_Ple2}
+END_PGML
+Section::End();
+
+Section::Begin("Final Answer");
+BEGIN_PGML
+Enter your final results.
+END_PGML
+
+BEGIN_TEXT
+$PAR
+$BR \(E(X)=\) \{ NAMED_ANS_RULE("finalEX",12) \}
+$BR \(\sigma_X=\) \{ NAMED_ANS_RULE("finalSig",12) \}
+$BR \(P(X\le 2)=\) \{ NAMED_ANS_RULE("finalP",12) \}
+END_TEXT
+
+Section::End();
+
+NAMED_ANS("finalEX", $cmp_final_EX);
+NAMED_ANS("finalSig", $cmp_final_sig);
+NAMED_ANS("finalP", $cmp_final_Ple2);
+
+# -------------------------------------------------------
+# Feedback (rating 1–5) (hidden in LB)
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning probability distributions and expected value?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_ExVar_GuidedProblem3.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_ExVar_GuidedProblem3.pg
new file mode 100644
index 0000000000..bc8eca7cde
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_ExVar_GuidedProblem3.pg
@@ -0,0 +1,387 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Number of Even Results on Two 4-Sided Dice: Distribution, Mean, Std Dev, and P(X<=1) (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Random Variables)
+## Level(2)
+## KEYWORDS('probability distribution','discrete random variable','four-sided dice','expected value','variance','standard deviation','even outcomes')
+## Static(1)
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser flag (hide rating in LB)
+# ----------------------------------------------------------------
+$inLibraryBrowser = $main::inLibraryBrowser || 0;
+
+# =======================================================
+# Context
+# =======================================================
+Context("Numeric");
+
+# =======================================================
+# True distribution for X = number of even results (2 or 4) on two fair 4-sided dice
+# Each die: P(even)=2/4=1/2, P(odd)=1/2
+# X in {0,1,2} with probabilities 1/4, 1/2, 1/4
+# =======================================================
+$P0 = Compute("1/4");
+$P1 = Compute("1/2");
+$P2 = Compute("1/4");
+
+$sumP = Compute("1");
+
+# Work-table columns (exact)
+$xp0 = Compute("0*(1/4)");
+$xp1 = Compute("1*(1/2)");
+$xp2 = Compute("2*(1/4)");
+
+$x2p0 = Compute("(0^2)*(1/4)");
+$x2p1 = Compute("(1^2)*(1/2)");
+$x2p2 = Compute("(2^2)*(1/4)");
+
+# Totals
+$EX = Compute("1"); # 0*1/4 + 1*1/2 + 2*1/4
+$EX2 = Compute("3/2"); # 0 + 1/2 + 1
+$Var = Compute("1/2"); # EX2 - EX^2
+$Sig = Compute("sqrt(2)/2");
+
+$P_le1 = Compute("3/4"); # P(0)+P(1)
+
+# =======================================================
+# Evaluators
+# =======================================================
+
+# Outcomes / values
+$cmp_n_outcomes = Real(16)->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 4) < 1e-6 } =>
+ "One 4-sided die has 4 outcomes. With two dice, think in ordered pairs (first die, second die).",
+));
+$cmp_minX = Real(0)->cmp;
+$cmp_maxX = Real(2)->cmp;
+$cmp_kvals = Real(3)->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 2) < 1e-6 } =>
+ "X can be 0, 1, or 2. That's 3 possible values.",
+));
+
+# Distribution entries (Part a) — conceptual hints (no numeric giveaways)
+$cmp_p0 = $P0->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (1/2)) < 1e-6 } =>
+ "1/2 is the probability a single die is even (or odd). Here X=0 means BOTH dice are odd.",
+));
+$cmp_p1 = $P1->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (1/4)) < 1e-6 } =>
+ "1/4 would be the probability of both dice odd OR both dice even. X=1 means one even and one odd.",
+));
+$cmp_p2 = $P2->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (1/2)) < 1e-6 } =>
+ "1/2 is not P(X=2). X=2 means BOTH dice are even (2 or 4).",
+));
+
+# Check sum to 1
+$cmp_sumP = $sumP->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (3/4)) < 1e-6 } =>
+ "3/4 is P(X<=1). Here you are checking that ALL probabilities add to 1.",
+));
+
+# Work-table: copied probabilities (graded so no AnSwEr warnings)
+$cmp_pw0 = $P0->cmp;
+$cmp_pw1 = $P1->cmp;
+$cmp_pw2 = $P2->cmp;
+
+# Work-table computed columns
+$cmp_xp0 = $xp0->cmp; $cmp_x2p0 = $x2p0->cmp;
+$cmp_xp1 = $xp1->cmp; $cmp_x2p1 = $x2p1->cmp;
+$cmp_xp2 = $xp2->cmp; $cmp_x2p2 = $x2p2->cmp;
+
+# Totals in work table
+$cmp_EX = $EX->cmp;
+$cmp_EX2 = $EX2->cmp;
+
+# Var and sigma
+$cmp_var = $Var->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - $_[1]) < 1e-6 } =>
+ "Use Var(X) = E(X^2) - [E(X)]^2, using the two totals from your work table.",
+));
+
+$cmp_sig = $Sig->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - $_[1]) < 1e-6 } =>
+ "Standard deviation is sigma_X = sqrt(Var(X)).",
+));
+
+# P(X<=1)
+$cmp_Ple1 = $P_le1->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (1/4)) < 1e-6 } =>
+ "1/4 is P(X=0) (both odd) or P(X=2) (both even). For X<=1 you need P(0)+P(1).",
+));
+
+# Final answers
+$cmp_final_EX = $EX->cmp;
+$cmp_final_sig = $Sig->cmp;
+$cmp_final_Ple1 = $P_le1->cmp;
+
+# =======================================================
+# Rating (1–5)
+# =======================================================
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = eval { $student->value };
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ansHash->{score} = 1;
+ $ansHash->{ans_message} = "Thanks!";
+ } else {
+ $ansHash->{score} = 0;
+ $ansHash->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+ return $ansHash->{score};
+ }
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin();
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+Two fair 4-sided dice are rolled. (Each die has faces [`` 1,2,3,4 ``].)
+
+Let [`` X ``] be the number of dice that show an even number.
+(Here “even” means [`` 2 ``] or [`` 4 ``].)
+
+a) Construct the probability distribution of [`` X ``].
+b) Find [`` E(X) ``].
+c) Find [`` \sigma_X ``].
+d) Find [`` P(X \le 1) ``].
+END_PGML
+Section::End();
+
+Section::Begin("Outcomes and possible values of X");
+BEGIN_PGML
+When two 4-sided dice are rolled, outcomes can be represented as ordered pairs [`` (i,j) ``] where
+[`` i ``] is the first die and [`` j ``] is the second die.
+
+1) How many equally likely outcomes are there?
+
+[____]{$cmp_n_outcomes}
+
+The random variable counts how many of the two dice are even:
+[`` X = \text{(number of even results among the two dice)} ``]
+
+2) What is the smallest possible value of [`` X ``]?
+
+[____]{$cmp_minX}
+
+3) What is the largest possible value of [`` X ``]?
+
+[____]{$cmp_maxX}
+
+4) How many possible values can [`` X ``] take?
+
+[____]{$cmp_kvals}
+END_PGML
+Section::End();
+
+Section::Begin("Construct the probability distribution (Part a)");
+BEGIN_PGML
+Fill in the probability distribution table for [`` X ``].
+
+(You can enter probabilities as fractions, like 1/4.)
+
+After you fill it in, you will check that the probabilities add to 1.
+END_PGML
+
+BEGIN_TEXT
+$BCENTER
+
+
+ | \(x\) |
+ \(P(X=x)\) |
+
+ | 0 | \{ NAMED_ANS_RULE("p0",12) \} |
+ | 1 | \{ NAMED_ANS_RULE("p1",12) \} |
+ | 2 | \{ NAMED_ANS_RULE("p2",12) \} |
+
+$ECENTER
+END_TEXT
+
+Section::End();
+
+NAMED_ANS("p0", $cmp_p0);
+NAMED_ANS("p1", $cmp_p1);
+NAMED_ANS("p2", $cmp_p2);
+
+Section::Begin("Check the probability distribution");
+BEGIN_PGML
+Check that the probabilities add to 1:
+
+[`` P(X=0)+P(X=1)+P(X=2)= ``] [____]{$cmp_sumP}
+END_PGML
+Section::End();
+
+Section::Begin("Quick reminders");
+BEGIN_PGML
+Use these steps and formulas:
+
+**Mean (expected value):**
+Multiply each value by its probability, then add.
+[`` E(X)=\sum x\,P(X=x) ``]
+
+**Variance:**
+First compute [`` E(X^2) ``] by squaring each [`` x ``], multiplying by its probability, then adding.
+Then:
+[`` \mathrm{Var}(X)=E(X^2)-[E(X)]^2 ``]
+
+**Standard deviation:**
+Take the square root of the variance.
+[`` \sigma_X=\sqrt{\mathrm{Var}(X)} ``]
+END_PGML
+Section::End();
+
+Section::Begin("Work table (compute E(X) and E(X^2))");
+BEGIN_PGML
+Copy your probabilities from Part (a) into the second column. Then compute the two calculated columns.
+
+- Column 3: compute [`` xP(X=x) ``]
+- Column 4: compute [`` x^2P(X=x) ``]
+
+Finally, add each calculated column.
+The total of column 3 is [`` E(X) ``], and the total of column 4 is [`` E(X^2) ``].
+END_PGML
+
+BEGIN_TEXT
+$BCENTER
+
+
+ | \(x\) |
+ \(P(X=x)\) |
+ \(xP(X=x)\) |
+ \(x^2P(X=x)\) |
+
+
+
+ | 0 |
+ \{ NAMED_ANS_RULE("pw0",10) \} |
+ \{ NAMED_ANS_RULE("xp0",12) \} |
+ \{ NAMED_ANS_RULE("x2p0",12) \} |
+
+
+ | 1 |
+ \{ NAMED_ANS_RULE("pw1",10) \} |
+ \{ NAMED_ANS_RULE("xp1",12) \} |
+ \{ NAMED_ANS_RULE("x2p1",12) \} |
+
+
+ | 2 |
+ \{ NAMED_ANS_RULE("pw2",10) \} |
+ \{ NAMED_ANS_RULE("xp2",12) \} |
+ \{ NAMED_ANS_RULE("x2p2",12) \} |
+
+
+
+ | Totals |
+
+ \{ NAMED_ANS_RULE("EX",12) \}
+ (this total is \(E(X)\))
+ |
+
+ \{ NAMED_ANS_RULE("EX2",12) \}
+ (this total is \(E(X^2)\))
+ |
+
+
+$ECENTER
+END_TEXT
+
+Section::End();
+
+# Grade copied probabilities (prevents AnSwEr warnings)
+NAMED_ANS("pw0", $cmp_pw0);
+NAMED_ANS("pw1", $cmp_pw1);
+NAMED_ANS("pw2", $cmp_pw2);
+
+# Grade computed columns + totals
+NAMED_ANS("xp0", $cmp_xp0); NAMED_ANS("x2p0", $cmp_x2p0);
+NAMED_ANS("xp1", $cmp_xp1); NAMED_ANS("x2p1", $cmp_x2p1);
+NAMED_ANS("xp2", $cmp_xp2); NAMED_ANS("x2p2", $cmp_x2p2);
+
+NAMED_ANS("EX", $cmp_EX);
+NAMED_ANS("EX2", $cmp_EX2);
+
+Section::Begin("Compute Var(X) and sigma_X");
+BEGIN_PGML
+Now compute:
+
+1) Variance:
+[`` \mathrm{Var}(X)=E(X^2)-[E(X)]^2 = ``] [____]{$cmp_var}
+
+2) Standard deviation:
+[`` \sigma_X=\sqrt{\mathrm{Var}(X)} = ``] [____]{$cmp_sig}
+END_PGML
+Section::End();
+
+Section::Begin("Compute P(X <= 1) (Part d)");
+BEGIN_PGML
+Use your probability distribution:
+
+[`` P(X \le 1)=P(X=0)+P(X=1)= ``] [____]{$cmp_Ple1}
+END_PGML
+Section::End();
+
+Section::Begin("Final Answer");
+BEGIN_PGML
+Enter your final results.
+END_PGML
+
+BEGIN_TEXT
+$PAR
+$BR \(E(X)=\) \{ NAMED_ANS_RULE("finalEX",12) \}
+$BR \(\sigma_X=\) \{ NAMED_ANS_RULE("finalSig",12) \}
+$BR \(P(X\le 1)=\) \{ NAMED_ANS_RULE("finalP",12) \}
+END_TEXT
+
+Section::End();
+
+NAMED_ANS("finalEX", $cmp_final_EX);
+NAMED_ANS("finalSig", $cmp_final_sig);
+NAMED_ANS("finalP", $cmp_final_Ple1);
+
+# -------------------------------------------------------
+# Feedback (rating 1–5) (hidden in LB)
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning probability distributions and expected value?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_ExVar_GuidedProblem4.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_ExVar_GuidedProblem4.pg
new file mode 100644
index 0000000000..2f00e21955
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_ExVar_GuidedProblem4.pg
@@ -0,0 +1,378 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Raffle: Probability Distribution, P(win), and Expected Value (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Random Variables)
+## Level(2)
+## KEYWORDS('probability distribution','expected value','net gain','raffle','discrete random variable')
+## Static(1)
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser flag (hide rating in LB)
+# ----------------------------------------------------------------
+$inLibraryBrowser = $main::inLibraryBrowser || 0;
+
+# =======================================================
+# Context & Data
+# =======================================================
+Context("Numeric");
+
+# Ticket + prizes
+$N = Real(1000);
+
+# Net gains (prize - cost)
+$x1 = Compute("300-1"); # 299
+$x2 = Compute("200-1"); # 199
+$x3 = Compute("100-1"); # 99
+$x0 = Compute("0-1"); # -1 (no prize)
+
+# Probabilities
+$p1 = Compute("1/1000");
+$p2 = Compute("1/1000");
+$p3 = Compute("1/1000");
+$p0 = Compute("997/1000");
+
+$Pwin = Compute("3/1000");
+$sumP = Compute("1");
+
+# Work-table xP values and expected value
+$xp1 = Compute("(300-1)*(1/1000)");
+$xp2 = Compute("(200-1)*(1/1000)");
+$xp3 = Compute("(100-1)*(1/1000)");
+$xp0 = Compute("(0-1)*(997/1000)");
+
+$EX = Compute("-2/5"); # -0.4
+$Loss = Compute("2/5"); # expected loss per ticket (positive amount)
+
+# =======================================================
+# Evaluators
+# =======================================================
+
+# Counts
+$cmp_N = $N->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 1000) < 1e-6 } =>
+ "There are 1000 tickets, and each ticket has an equal chance of being the one you bought.",
+));
+
+$cmp_winners = Real(3)->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 1) < 1e-6 } =>
+ "There are three prizes, so there are three winning tickets (one for each prize).",
+));
+
+# Net gains
+$cmp_x1 = $x1->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 300) < 1e-6 } =>
+ "Net gain means prize minus cost. You must subtract the $1 ticket cost.",
+));
+$cmp_x2 = $x2->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 200) < 1e-6 } =>
+ "Net gain means prize minus cost. Subtract 1 from the prize.",
+));
+$cmp_x3 = $x3->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 100) < 1e-6 } =>
+ "Net gain means prize minus cost. Subtract 1 from the prize.",
+));
+$cmp_x0 = $x0->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 0) < 1e-6 } =>
+ "If you win nothing, your net gain is not 0. You still paid $1 for the ticket.",
+));
+
+# Probabilities for distribution table
+$cmp_p1 = $p1->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (3/1000)) < 1e-6 } =>
+ "3/1000 is the probability of winning any prize. Here you need the probability of FIRST prize only.",
+));
+$cmp_p2 = $p2->cmp;
+$cmp_p3 = $p3->cmp;
+$cmp_p0 = $p0->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (997/1000)) < 1e-6 } =>
+ "There are 3 winning tickets out of 1000. The remaining tickets are not winners.",
+ sub { abs($_[0] - (1/1000)) < 1e-6 } =>
+ "1/1000 is the probability of a specific prize. For 'no prize' you need the complement.",
+));
+
+# Check sum to 1
+$cmp_sumP = $sumP->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (3/1000)) < 1e-6 } =>
+ "3/1000 is P(winning any money). Here you are checking that ALL probabilities add to 1.",
+));
+
+# Part (b)
+$cmp_Pwin = $Pwin->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (997/1000)) < 1e-6 } =>
+ "997/1000 is the probability of winning nothing (no prize). Here you want the probability of winning any prize.",
+));
+
+# Work-table copied probabilities (to avoid AnSwEr warnings)
+$cmp_pw1 = $p1->cmp;
+$cmp_pw2 = $p2->cmp;
+$cmp_pw3 = $p3->cmp;
+$cmp_pw0 = $p0->cmp;
+
+# Work-table xP entries
+$cmp_xp1 = $xp1->cmp;
+$cmp_xp2 = $xp2->cmp;
+$cmp_xp3 = $xp3->cmp;
+$cmp_xp0 = $xp0->cmp;
+
+# Expected value + interpretation numeric
+$cmp_EX = $EX->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (597/1000)) < 1e-6 } =>
+ "That adds the three winning net gains but forgets the big negative contribution from the 'no prize' outcome.",
+));
+$cmp_Loss = $Loss->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - $_[0]) < 0 } =>
+ "If E(X) is negative, the expected loss per ticket is -E(X).",
+));
+
+# Final answers (expression entries)
+$cmp_final_EX = $EX->cmp;
+$cmp_final_Pwin = $Pwin->cmp;
+
+# =======================================================
+# Rating (1–5)
+# =======================================================
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = eval { $student->value };
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ansHash->{score} = 1;
+ $ansHash->{ans_message} = "Thanks!";
+ } else {
+ $ansHash->{score} = 0;
+ $ansHash->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+ return $ansHash->{score};
+ }
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin();
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A service organization in a large town organizes a raffle each month.
+
+One thousand raffle tickets are sold for \$1 each. Each has an equal chance of winning.
+First prize is \$300, second prize is \$200, and third prize is \$100.
+
+Let [`` X ``] denote the **net gain** from the purchase of one ticket.
+
+a) Construct the probability distribution of [`` X ``].
+b) Find the probability of winning any money in the purchase of one ticket.
+c) Find the expected value of [`` X ``], and interpret its meaning.
+END_PGML
+Section::End();
+
+Section::Begin("Outcomes and possible values of X");
+BEGIN_PGML
+Think of the outcome as “which ticket number wins.”
+
+1) How many equally likely outcomes are there?
+
+[____]{$cmp_N}
+
+2) How many winning tickets are there in total?
+
+[____]{$cmp_winners}
+
+Now compute the possible values of [`` X ``] (net gain = prize minus the \$1 cost):
+
+First prize net gain: [`` 300-1 = ``] [____]{$cmp_x1}
+Second prize net gain: [`` 200-1 = ``] [____]{$cmp_x2}
+Third prize net gain: [`` 100-1 = ``] [____]{$cmp_x3}
+No prize net gain: [`` 0-1 = ``] [____]{$cmp_x0}
+END_PGML
+Section::End();
+
+Section::Begin("Construct the probability distribution (Part a)");
+BEGIN_PGML
+Each ticket has probability [`` 1/1000 ``] of being the one you bought.
+
+Fill in the probability distribution table for [`` X ``].
+END_PGML
+
+BEGIN_TEXT
+$BCENTER
+
+
+ | \(x\) |
+ \(P(X=x)\) |
+
+ | \(299\) | \{ NAMED_ANS_RULE("p1",12) \} |
+ | \(199\) | \{ NAMED_ANS_RULE("p2",12) \} |
+ | \(99\) | \{ NAMED_ANS_RULE("p3",12) \} |
+ | \(-1\) | \{ NAMED_ANS_RULE("p0",12) \} |
+
+$ECENTER
+END_TEXT
+
+Section::End();
+
+NAMED_ANS("p1", $cmp_p1);
+NAMED_ANS("p2", $cmp_p2);
+NAMED_ANS("p3", $cmp_p3);
+NAMED_ANS("p0", $cmp_p0);
+
+Section::Begin("Check the probability distribution");
+BEGIN_PGML
+Check that the probabilities add to 1:
+
+[`` P(X=299)+P(X=199)+P(X=99)+P(X=-1)= ``] [____]{$cmp_sumP}
+END_PGML
+Section::End();
+
+Section::Begin("Probability of winning any money (Part b)");
+BEGIN_PGML
+“Winning any money” means you win first prize, second prize, or third prize.
+
+Compute:
+[`` P(\text{win any money}) = P(X=299)+P(X=199)+P(X=99)= ``] [____]{$cmp_Pwin}
+END_PGML
+Section::End();
+
+Section::Begin("Quick reminders");
+BEGIN_PGML
+Use this formula:
+
+**Expected value (mean):**
+Multiply each value by its probability, then add.
+[`` E(X)=\sum x\,P(X=x) ``]
+END_PGML
+Section::End();
+
+Section::Begin("Work table (compute E(X))");
+BEGIN_PGML
+Copy your probabilities from Part (a) into the second column, then compute the third column.
+
+Finally, add the third column. That total is [`` E(X) ``].
+END_PGML
+
+BEGIN_TEXT
+$BCENTER
+
+
+ | \(x\) |
+ \(P(X=x)\) |
+ \(xP(X=x)\) |
+
+
+
+ | \(299\) |
+ \{ NAMED_ANS_RULE("pw1",10) \} |
+ \{ NAMED_ANS_RULE("xp1",12) \} |
+
+
+
+ | \(199\) |
+ \{ NAMED_ANS_RULE("pw2",10) \} |
+ \{ NAMED_ANS_RULE("xp2",12) \} |
+
+
+
+ | \(99\) |
+ \{ NAMED_ANS_RULE("pw3",10) \} |
+ \{ NAMED_ANS_RULE("xp3",12) \} |
+
+
+
+ | \(-1\) |
+ \{ NAMED_ANS_RULE("pw0",10) \} |
+ \{ NAMED_ANS_RULE("xp0",12) \} |
+
+
+
+ | Total |
+
+ \{ NAMED_ANS_RULE("EX",12) \}
+ (this total is \(E(X)\))
+ |
+
+
+$ECENTER
+END_TEXT
+
+Section::End();
+
+# Grade copied probabilities (prevents AnSwEr warnings)
+NAMED_ANS("pw1", $cmp_pw1);
+NAMED_ANS("pw2", $cmp_pw2);
+NAMED_ANS("pw3", $cmp_pw3);
+NAMED_ANS("pw0", $cmp_pw0);
+
+# Grade xP column + total
+NAMED_ANS("xp1", $cmp_xp1);
+NAMED_ANS("xp2", $cmp_xp2);
+NAMED_ANS("xp3", $cmp_xp3);
+NAMED_ANS("xp0", $cmp_xp0);
+NAMED_ANS("EX", $cmp_EX);
+
+Section::Begin("Interpret the expected value (Part c)");
+BEGIN_PGML
+If your expected value [`` E(X) ``] is negative, that means the raffle is unfavorable to the buyer.
+
+Compute the **expected loss per ticket** (a positive number):
+[`` \text{expected loss} = -E(X)= ``] [____]{$cmp_Loss}
+END_PGML
+Section::End();
+
+Section::Begin("Final Answer");
+BEGIN_PGML
+Enter the final results.
+END_PGML
+
+BEGIN_TEXT
+$PAR
+$BR \(P(\text{win any money})=\) \{ NAMED_ANS_RULE("finalPwin",12) \}
+$BR \(E(X)=\) \{ NAMED_ANS_RULE("finalEX",12) \}
+END_TEXT
+
+Section::End();
+
+NAMED_ANS("finalPwin", $cmp_final_Pwin);
+NAMED_ANS("finalEX", $cmp_final_EX);
+
+# -------------------------------------------------------
+# Feedback (rating 1–5) (hidden in LB)
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning expected value?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_ExVar_GuidedProblem5.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_ExVar_GuidedProblem5.pg
new file mode 100644
index 0000000000..6589104eac
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_ExVar_GuidedProblem5.pg
@@ -0,0 +1,319 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Life Insurance: Probability Distribution and Expected Value (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Random Variables)
+## Level(2)
+## KEYWORDS('expected value','probability distribution','net gain','life insurance','discrete random variable')
+## Static(1)
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser flag (hide rating in LB)
+# ----------------------------------------------------------------
+$inLibraryBrowser = $main::inLibraryBrowser || 0;
+
+# =======================================================
+# Context & Data
+# =======================================================
+Context("Numeric");
+
+# Given probabilities
+$p_survive = Compute("9997/10000"); # 0.9997
+$p_die = Compute("3/10000"); # 0.0003
+$sumP = Compute("1");
+
+# Net gain to the company:
+# - If survive: company keeps premium
+# - If die: company pays 200000 but still collected premium
+$x_survive = Compute("195"); # +195
+$x_die = Compute("195-200000"); # -199805
+
+# Expected value
+$xp_survive = Compute("195*(9997/10000)");
+$xp_die = Compute("(195-200000)*(3/10000)");
+$EX = Compute("135");
+
+# Interpretation helper (positive amount; profit if EX>0, loss if EX<0)
+$absEX = Compute("135");
+
+# =======================================================
+# Evaluators
+# =======================================================
+
+$cmp_p_die = $p_die->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 0.9997) < 1e-6 } =>
+ "0.9997 is the probability of surviving. The probability of dying is the complement.",
+ sub { abs($_[0] - 0.0003) < 1e-6 } =>
+ "Good. P(die) = 1 - P(survive).",
+));
+
+$cmp_x_survive = $x_survive->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 0) < 1e-6 } =>
+ "If the person survives, the company still collected the premium. Net gain is not 0.",
+ sub { abs($_[0] - 195) < 1e-6 } =>
+ "Good. If no claim is paid, the company keeps the premium.",
+));
+
+$cmp_x_die = $x_die->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (-200000)) < 1e-6 } =>
+ "You included the payout but forgot the company also collected the premium.",
+ sub { abs($_[0] - (-199805)) < 1e-6 } =>
+ "Good. Net gain = premium - payout.",
+));
+
+# Distribution-table probabilities
+$cmp_ps = $p_survive->cmp;
+$cmp_pd = $p_die->cmp;
+
+# Check sum
+$cmp_sumP = $sumP->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 0.9997) < 1e-6 } =>
+ "That is only P(survive). Here you are checking that BOTH probabilities add to 1.",
+));
+
+# Work-table copied probabilities (avoid AnSwEr warnings)
+$cmp_pws = $p_survive->cmp;
+$cmp_pwd = $p_die->cmp;
+
+# Work-table xP
+$cmp_xps = $xp_survive->cmp;
+$cmp_xpd = $xp_die->cmp;
+
+# Expected value
+$cmp_EX = $EX->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 195) < 1e-6 } =>
+ "That would be the gain if the person ALWAYS survived. You must weight by probabilities.",
+ sub { abs($_[0] - (-199805)) < 1e-6 } =>
+ "That would be the gain if the person ALWAYS died. You must weight by probabilities.",
+));
+
+# Interpretation numeric (positive amount)
+$cmp_absEX = $absEX->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 135) < 1e-6 } =>
+ "Good. If E(X) is positive, this is an expected profit. If E(X) were negative, this would be the expected loss = -E(X).",
+));
+
+# Final answers
+$cmp_final_EX = $EX->cmp;
+
+# =======================================================
+# Rating (1–5)
+# =======================================================
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = eval { $student->value };
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ansHash->{score} = 1;
+ $ansHash->{ans_message} = "Thanks!";
+ } else {
+ $ansHash->{score} = 0;
+ $ansHash->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+ return $ansHash->{score};
+ }
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin();
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A life insurance company will sell a \$200,000 one-year term life insurance policy to an individual in a particular risk group for a premium of \$195.
+
+A person in this risk group has a 99.97% chance of surviving one year.
+
+Let [`` X ``] be the **net gain to the company** from a single policy.
+
+a) Construct the probability distribution of [`` X ``].
+b) Find [`` E(X) ``].
+c) Interpret the meaning of [`` E(X) ``] for the company.
+END_PGML
+Section::End();
+
+Section::Begin("Outcomes and net gain values");
+BEGIN_PGML
+There are two outcomes for the year:
+
+- The person **survives** (no payout)
+- The person **dies** (the company pays \$200,000)
+
+You are given:
+[`` P(\text{survive})=0.9997 ``]
+
+1) Compute:
+[`` P(\text{die})=1-P(\text{survive})= ``] [____]{$cmp_p_die}
+
+Now compute the possible values of [`` X ``] (net gain to the company):
+
+2) If the person survives, the company keeps the premium:
+[`` X=\text{premium}= ``] [____]{$cmp_x_survive}
+
+3) If the person dies, the company pays \$200,000 but still collected the premium:
+[`` X=\text{premium}-200000= ``] [____]{$cmp_x_die}
+END_PGML
+Section::End();
+
+Section::Begin("Probability distribution of X (Part a)");
+BEGIN_PGML
+Fill in the probability distribution table for [`` X ``].
+(You may enter probabilities as decimals or fractions.)
+END_PGML
+
+BEGIN_TEXT
+$BCENTER
+
+
+ | \(x\) |
+ \(P(X=x)\) |
+
+
+ | \(195\) |
+ \{ NAMED_ANS_RULE("ps",12) \} |
+
+
+ | \(-199805\) |
+ \{ NAMED_ANS_RULE("pd",12) \} |
+
+
+$ECENTER
+END_TEXT
+
+Section::End();
+
+NAMED_ANS("ps", $cmp_ps);
+NAMED_ANS("pd", $cmp_pd);
+
+Section::Begin("Check the probability distribution");
+BEGIN_PGML
+Check that the probabilities add to 1:
+
+[`` P(X=195)+P(X=-199805)= ``] [____]{$cmp_sumP}
+END_PGML
+Section::End();
+
+Section::Begin("Quick reminders");
+BEGIN_PGML
+**Expected value (mean):**
+Multiply each value by its probability, then add.
+[`` E(X)=\sum x\,P(X=x) ``]
+END_PGML
+Section::End();
+
+Section::Begin("Work table (compute E(X))");
+BEGIN_PGML
+Copy your probabilities into column 2, compute column 3, then add column 3.
+
+The total of column 3 is [`` E(X) ``].
+END_PGML
+
+BEGIN_TEXT
+$BCENTER
+
+
+ | \(x\) |
+ \(P(X=x)\) |
+ \(xP(X=x)\) |
+
+
+ | \(195\) |
+ \{ NAMED_ANS_RULE("pws",12) \} |
+ \{ NAMED_ANS_RULE("xps",12) \} |
+
+
+ | \(-199805\) |
+ \{ NAMED_ANS_RULE("pwd",12) \} |
+ \{ NAMED_ANS_RULE("xpd",12) \} |
+
+
+ | Total |
+
+ \{ NAMED_ANS_RULE("EX",12) \}
+ (this total is \(E(X)\))
+ |
+
+
+$ECENTER
+END_TEXT
+
+Section::End();
+
+# Grade copied probabilities (avoid AnSwEr warnings)
+NAMED_ANS("pws", $cmp_pws);
+NAMED_ANS("pwd", $cmp_pwd);
+
+# Grade xP column + total
+NAMED_ANS("xps", $cmp_xps);
+NAMED_ANS("xpd", $cmp_xpd);
+NAMED_ANS("EX", $cmp_EX);
+
+Section::Begin("Interpretation (Part c)");
+BEGIN_PGML
+The expected value is the long-run average net gain **per policy** if the company sells many such policies.
+
+Enter the expected **profit or loss amount** as a positive number:
+- If your [`` E(X) ``] is positive, enter [`` E(X) ``].
+- If your [`` E(X) ``] is negative, enter [`` -E(X) ``].
+
+Expected profit/loss amount per policy:
+[____]{$cmp_absEX}
+END_PGML
+Section::End();
+
+Section::Begin("Final Answer");
+BEGIN_PGML
+Enter the expected value to the company:
+END_PGML
+
+BEGIN_TEXT
+$PAR
+$BR \(E(X)=\) \{ NAMED_ANS_RULE("finalEX",12) \}
+END_TEXT
+
+Section::End();
+
+NAMED_ANS("finalEX", $cmp_final_EX);
+
+# -------------------------------------------------------
+# Feedback (rating 1–5) (hidden in LB)
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning expected value?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_ExVar_GuidedProblem6.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_ExVar_GuidedProblem6.pg
new file mode 100644
index 0000000000..0907544a07
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_ExVar_GuidedProblem6.pg
@@ -0,0 +1,416 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Binomial RV: Number of Sixes in 4 Die Rolls (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Random Variables)
+## Level(2)
+## KEYWORDS('probability distribution','discrete random variable','binomial','expected value','variance','standard deviation','die rolls')
+## Static(1)
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser flag (hide rating in LB)
+# ----------------------------------------------------------------
+$inLibraryBrowser = $main::inLibraryBrowser || 0;
+
+# =======================================================
+# Context
+# =======================================================
+Context("Numeric");
+
+# =======================================================
+# Data
+# Experiment: roll a fair die 4 times, X = number of sixes.
+# X in {0,1,2,3,4}
+# p = 1/6, q = 5/6
+# P(X=k) = C(4,k) p^k q^(4-k)
+# =======================================================
+
+$p = Compute("1/6");
+$q = Compute("5/6");
+
+$P0 = Compute("(5/6)^4"); # 625/1296
+$P1 = Compute("4*(1/6)*(5/6)^3"); # 500/1296
+$P2 = Compute("6*(1/6)^2*(5/6)^2"); # 150/1296
+$P3 = Compute("4*(1/6)^3*(5/6)"); # 20/1296
+$P4 = Compute("(1/6)^4"); # 1/1296
+
+$sumP = Compute("1");
+
+# Work-table xP and x^2P
+$xp0 = Compute("0*(".$P0->string.")");
+$xp1 = Compute("1*(".$P1->string.")");
+$xp2 = Compute("2*(".$P2->string.")");
+$xp3 = Compute("3*(".$P3->string.")");
+$xp4 = Compute("4*(".$P4->string.")");
+
+$x2p0 = Compute("(0^2)*(".$P0->string.")");
+$x2p1 = Compute("(1^2)*(".$P1->string.")");
+$x2p2 = Compute("(2^2)*(".$P2->string.")");
+$x2p3 = Compute("(3^2)*(".$P3->string.")");
+$x2p4 = Compute("(4^2)*(".$P4->string.")");
+
+# Totals
+$EX = Compute("2/3"); # np = 4*(1/6)
+$EX2 = Compute("1"); # computed from distribution
+$Var = Compute("5/9"); # npq = 4*(1/6)*(5/6)
+$Sig = Compute("sqrt(5)/3");
+
+# Example probability question: P(X>=2)
+$Pge2 = Compute($P2->string . " + " . $P3->string . " + " . $P4->string); # 171/1296 = 19/144
+$Pge2_simplified = Compute("19/144");
+
+# =======================================================
+# Evaluators
+# =======================================================
+
+# Outcomes / values
+$cmp_n_outcomes = Real(1296)->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 6) < 1e-6 } =>
+ "One roll has 6 outcomes. For 4 rolls, use the multiplication rule (ordered outcomes).",
+));
+$cmp_minX = Real(0)->cmp;
+$cmp_maxX = Real(4)->cmp;
+$cmp_kvals = Real(5)->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 4) < 1e-6 } =>
+ "X counts sixes in 4 rolls. It can be 0,1,2,3,4 (that is 5 values).",
+));
+
+# Distribution entries
+$cmp_p0 = $P0->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (1/1296)) < 1e-6 } =>
+ "1/1296 is P(X=4) (four sixes). For X=0 you want no sixes: (5/6)^4.",
+));
+$cmp_p1 = $P1->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (625/1296)) < 1e-6 } =>
+ "That is P(X=0). For X=1 you need exactly one six: 4(1/6)(5/6)^3.",
+));
+$cmp_p2 = $P2->cmp;
+$cmp_p3 = $P3->cmp;
+$cmp_p4 = $P4->cmp;
+
+# Check sum
+$cmp_sumP = $sumP->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (19/144)) < 1e-6 } =>
+ "19/144 is P(X>=2). Here you are checking that ALL probabilities add to 1.",
+));
+
+# Work-table copied probabilities (avoid AnSwEr warnings)
+$cmp_pw0 = $P0->cmp;
+$cmp_pw1 = $P1->cmp;
+$cmp_pw2 = $P2->cmp;
+$cmp_pw3 = $P3->cmp;
+$cmp_pw4 = $P4->cmp;
+
+# Work-table computed columns
+$cmp_xp0 = $xp0->cmp; $cmp_x2p0 = $x2p0->cmp;
+$cmp_xp1 = $xp1->cmp; $cmp_x2p1 = $x2p1->cmp;
+$cmp_xp2 = $xp2->cmp; $cmp_x2p2 = $x2p2->cmp;
+$cmp_xp3 = $xp3->cmp; $cmp_x2p3 = $x2p3->cmp;
+$cmp_xp4 = $xp4->cmp; $cmp_x2p4 = $x2p4->cmp;
+
+$cmp_EX = $EX->cmp;
+$cmp_EX2 = $EX2->cmp;
+
+$cmp_var = $Var->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - $_[1]) < 1e-6 } =>
+ "Use Var(X) = E(X^2) - [E(X)]^2, using the two totals from your work table.",
+));
+$cmp_sig = $Sig->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - $_[1]) < 1e-6 } =>
+ "Standard deviation is sigma_X = sqrt(Var(X)).",
+));
+
+# Probability question
+$cmp_Pge2 = $Pge2_simplified->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (1 - (625/1296) - (500/1296))) < 1e-6 } =>
+ "Good strategy: P(X>=2) = 1 - P(0) - P(1).",
+));
+
+# Final answers
+$cmp_final_EX = $EX->cmp;
+$cmp_final_sig = $Sig->cmp;
+$cmp_final_Pge2 = $Pge2_simplified->cmp;
+
+# =======================================================
+# Rating (1–5)
+# =======================================================
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = eval { $student->value };
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ansHash->{score} = 1;
+ $ansHash->{ans_message} = "Thanks!";
+ } else {
+ $ansHash->{score} = 0;
+ $ansHash->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+ return $ansHash->{score};
+ }
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin();
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+An ordinary fair die is rolled 4 times. Let [`` X ``] be the number of times the result is 6.
+
+a) Construct the probability distribution of [`` X ``].
+b) Find [`` E(X) ``].
+c) Find [`` \sigma_X ``].
+d) Find [`` P(X \ge 2) ``].
+END_PGML
+Section::End();
+
+Section::Begin("Outcomes and possible values of X");
+BEGIN_PGML
+Think of an outcome as an ordered list of 4 results (like 6,2,1,6).
+
+1) How many equally likely outcomes are there?
+
+[____]{$cmp_n_outcomes}
+
+The random variable counts how many sixes occur in 4 rolls.
+
+2) Smallest possible value of [`` X ``]:
+
+[____]{$cmp_minX}
+
+3) Largest possible value of [`` X ``]:
+
+[____]{$cmp_maxX}
+
+4) How many possible values can [`` X ``] take?
+
+[____]{$cmp_kvals}
+END_PGML
+Section::End();
+
+Section::Begin("Construct the probability distribution (Part a)");
+BEGIN_PGML
+For each [`` k=0,1,2,3,4 ``], you can compute:
+
+[`` P(X=k)=\binom{4}{k}\left(\frac{1}{6}\right)^k\left(\frac{5}{6}\right)^{4-k} ``]
+
+Fill in the probability distribution table. (Fractions are fine.)
+END_PGML
+
+BEGIN_TEXT
+$BCENTER
+
+
+ | \(x\) |
+ \(P(X=x)\) |
+
+ | 0 | \{ NAMED_ANS_RULE("p0",12) \} |
+ | 1 | \{ NAMED_ANS_RULE("p1",12) \} |
+ | 2 | \{ NAMED_ANS_RULE("p2",12) \} |
+ | 3 | \{ NAMED_ANS_RULE("p3",12) \} |
+ | 4 | \{ NAMED_ANS_RULE("p4",12) \} |
+
+$ECENTER
+END_TEXT
+
+Section::End();
+
+NAMED_ANS("p0", $cmp_p0);
+NAMED_ANS("p1", $cmp_p1);
+NAMED_ANS("p2", $cmp_p2);
+NAMED_ANS("p3", $cmp_p3);
+NAMED_ANS("p4", $cmp_p4);
+
+Section::Begin("Check the probability distribution");
+BEGIN_PGML
+Check that the probabilities add to 1:
+
+[`` P(0)+P(1)+P(2)+P(3)+P(4)= ``] [____]{$cmp_sumP}
+END_PGML
+Section::End();
+
+Section::Begin("Quick reminders");
+BEGIN_PGML
+Use these steps and formulas:
+
+**Mean (expected value):**
+Multiply each value by its probability, then add.
+[`` E(X)=\sum x\,P(X=x) ``]
+
+**Variance:**
+First compute [`` E(X^2) ``] by squaring each [`` x ``], multiplying by its probability, then adding.
+Then:
+[`` \mathrm{Var}(X)=E(X^2)-[E(X)]^2 ``]
+
+**Standard deviation:**
+Take the square root of the variance.
+[`` \sigma_X=\sqrt{\mathrm{Var}(X)} ``]
+END_PGML
+Section::End();
+
+Section::Begin("Work table (compute E(X) and E(X^2))");
+BEGIN_PGML
+Copy your probabilities from Part (a) into the second column. Then compute the two calculated columns.
+
+- Column 3: compute [`` xP(X=x) ``]
+- Column 4: compute [`` x^2P(X=x) ``]
+
+Finally, add each calculated column.
+The total of column 3 is [`` E(X) ``], and the total of column 4 is [`` E(X^2) ``].
+END_PGML
+
+BEGIN_TEXT
+$BCENTER
+
+
+ | \(x\) |
+ \(P(X=x)\) |
+ \(xP(X=x)\) |
+ \(x^2P(X=x)\) |
+
+
+
+ | 0 |
+ \{ NAMED_ANS_RULE("pw0",10) \} |
+ \{ NAMED_ANS_RULE("xp0",12) \} |
+ \{ NAMED_ANS_RULE("x2p0",12) \} |
+
+
+ | 1 |
+ \{ NAMED_ANS_RULE("pw1",10) \} |
+ \{ NAMED_ANS_RULE("xp1",12) \} |
+ \{ NAMED_ANS_RULE("x2p1",12) \} |
+
+
+ | 2 |
+ \{ NAMED_ANS_RULE("pw2",10) \} |
+ \{ NAMED_ANS_RULE("xp2",12) \} |
+ \{ NAMED_ANS_RULE("x2p2",12) \} |
+
+
+ | 3 |
+ \{ NAMED_ANS_RULE("pw3",10) \} |
+ \{ NAMED_ANS_RULE("xp3",12) \} |
+ \{ NAMED_ANS_RULE("x2p3",12) \} |
+
+
+ | 4 |
+ \{ NAMED_ANS_RULE("pw4",10) \} |
+ \{ NAMED_ANS_RULE("xp4",12) \} |
+ \{ NAMED_ANS_RULE("x2p4",12) \} |
+
+
+
+ | Totals |
+
+ \{ NAMED_ANS_RULE("EX",12) \}
+ (this total is \(E(X)\))
+ |
+
+ \{ NAMED_ANS_RULE("EX2",12) \}
+ (this total is \(E(X^2)\))
+ |
+
+
+$ECENTER
+END_TEXT
+
+Section::End();
+
+# Grade copied probabilities (prevents AnSwEr warnings)
+NAMED_ANS("pw0", $cmp_pw0);
+NAMED_ANS("pw1", $cmp_pw1);
+NAMED_ANS("pw2", $cmp_pw2);
+NAMED_ANS("pw3", $cmp_pw3);
+NAMED_ANS("pw4", $cmp_pw4);
+
+# Grade computed columns + totals
+NAMED_ANS("xp0", $cmp_xp0); NAMED_ANS("x2p0", $cmp_x2p0);
+NAMED_ANS("xp1", $cmp_xp1); NAMED_ANS("x2p1", $cmp_x2p1);
+NAMED_ANS("xp2", $cmp_xp2); NAMED_ANS("x2p2", $cmp_x2p2);
+NAMED_ANS("xp3", $cmp_xp3); NAMED_ANS("x2p3", $cmp_x2p3);
+NAMED_ANS("xp4", $cmp_xp4); NAMED_ANS("x2p4", $cmp_x2p4);
+
+NAMED_ANS("EX", $cmp_EX);
+NAMED_ANS("EX2", $cmp_EX2);
+
+Section::Begin("Compute Var(X) and sigma_X");
+BEGIN_PGML
+Now compute:
+
+1) Variance:
+[`` \mathrm{Var}(X)=E(X^2)-[E(X)]^2 = ``] [____]{$cmp_var}
+
+2) Standard deviation:
+[`` \sigma_X=\sqrt{\mathrm{Var}(X)} = ``] [____]{$cmp_sig}
+END_PGML
+Section::End();
+
+Section::Begin("Compute P(X >= 2) (Part d)");
+BEGIN_PGML
+Use your probability distribution:
+
+[`` P(X \ge 2)=P(X=2)+P(X=3)+P(X=4)= ``] [____]{$cmp_Pge2}
+END_PGML
+Section::End();
+
+Section::Begin("Final Answer");
+BEGIN_PGML
+Enter your final results.
+END_PGML
+
+BEGIN_TEXT
+$PAR
+$BR \(E(X)=\) \{ NAMED_ANS_RULE("finalEX",12) \}
+$BR \(\sigma_X=\) \{ NAMED_ANS_RULE("finalSig",12) \}
+$BR \(P(X\ge 2)=\) \{ NAMED_ANS_RULE("finalP",12) \}
+END_TEXT
+
+Section::End();
+
+NAMED_ANS("finalEX", $cmp_final_EX);
+NAMED_ANS("finalSig", $cmp_final_sig);
+NAMED_ANS("finalP", $cmp_final_Pge2);
+
+# -------------------------------------------------------
+# Feedback (rating 1–5) (hidden in LB)
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning probability distributions and expected value?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_PD_GuidedProblem1.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_PD_GuidedProblem1.pg
new file mode 100644
index 0000000000..ba36db46de
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_PD_GuidedProblem1.pg
@@ -0,0 +1,372 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Probability Distribution of a Discrete Random Variable (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Random Variables)
+## Level(2)
+## KEYWORDS('probability distribution','discrete random variable','coin toss','probability table','at least one')
+## Static(1)
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Context & Data
+# =======================================================
+Context("Numeric");
+Context()->flags->set(implicitMultiplication => 1);
+
+$k_vals = Compute("3"); # X can be 0,1,2 (3 values)
+$P0 = Compute("1/4");
+$P1 = Compute("1/2");
+$P2 = Compute("1/4");
+$sumP = Compute("1");
+$Patleast = Compute("3/4");
+
+# =======================================================
+# Evaluators
+# =======================================================
+$cmp_k = $k_vals->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 2) < 1e-6 } =>
+ "If X is the number of heads in 2 tosses, it can be 0, 1, or 2 (that is 3 values).",
+));
+
+$cmp_P0 = $P0->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (1/2)) < 1e-6 } =>
+ "X=0 means no heads. That happens only for TT (one outcome out of 4).",
+));
+
+$cmp_P1 = $P1->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (1/4)) < 1e-6 } =>
+ "X=1 happens in HT and TH (two outcomes out of 4).",
+));
+
+$cmp_P2 = $P2->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (1/2)) < 1e-6 } =>
+ "X=2 means two heads. That happens only for HH (one outcome out of 4).",
+));
+
+$cmp_sumP = $sumP->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (3/4)) < 1e-6 } =>
+ "3/4 is P(at least one head). Here you are checking the sum P(X=0)+P(X=1)+P(X=2).",
+));
+
+$cmp_Patleast = $Patleast->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (1/4)) < 1e-6 } =>
+ "1/4 is P(X=0) (no heads). 'At least one head' is the complement of that.",
+ sub { abs($_[0] - (1/2)) < 1e-6 } =>
+ "1/2 is P(X=1). 'At least one head' means X=1 or X=2.",
+));
+
+# =======================================================
+# RadioButtons (fixed-looking random order, correct not always A)
+# =======================================================
+
+# Definition MC (correct is NOT A)
+$rb_def = RadioButtons(
+ [
+ "Only the possible values of X (without probabilities).",
+ "A list of each possible value of X together with the probability that X takes that value.",
+ "A list of outcomes like HH, HT, TH, TT.",
+ "Only the most likely value of X.",
+ "A formula that always looks the same for every experiment.",
+ ],
+ 1, # correct is option index 1
+ labels => "ABC",
+ displayLabels => 0,
+ checked => 0, # prevents empty submission (avoids parserRadioButtons warning)
+);
+
+# Section 3 MCs: Is this a probability distribution table?
+$rb_pd1 = RadioButtons(
+ [
+ "Yes",
+ "No, because the probabilities do not add to 1",
+ "No, because one probability is not between 0 and 1",
+ "No, because the table does not list probabilities for all possible values of X",
+ ],
+ 0, # Yes
+ labels => "ABC",
+ displayLabels => 0,
+ checked => 0,
+);
+
+$rb_pd2 = RadioButtons(
+ [
+ "Yes",
+ "No, because one probability is not between 0 and 1",
+ "No, because the table does not list probabilities for all possible values of X",
+ "No, because the probabilities do not add to 1",
+ ],
+ 3, # sum not 1
+ labels => "ABC",
+ displayLabels => 0,
+ checked => 0,
+);
+
+$rb_pd3 = RadioButtons(
+ [
+ "Yes",
+ "No, because one probability is not between 0 and 1",
+ "No, because the probabilities do not add to 1",
+ "No, because the table does not list probabilities for all possible values of X",
+ ],
+ 1, # prob outside [0,1]
+ labels => "ABC",
+ displayLabels => 0,
+ checked => 0,
+);
+
+$rb_pd4 = RadioButtons(
+ [
+ "Yes",
+ "No, because one probability is not between 0 and 1",
+ "No, because the probabilities do not add to 1",
+ "No, because the table does not list probabilities for all possible values of X",
+ ],
+ 3, # missing value(s) of X
+ labels => "ABC",
+ displayLabels => 0,
+ checked => 0,
+);
+
+# =======================================================
+# Rating (1–5)
+# =======================================================
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = eval { $student->value };
+
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ansHash->{score} = 1;
+ $ansHash->{ans_message} = "Thanks!";
+ } else {
+ $ansHash->{score} = 0;
+ $ansHash->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+ return $ansHash->{score};
+ }
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin();
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A fair coin is tossed twice. Let [`` X ``] be the number of heads that are observed.
+
+a. Construct the probability distribution of [`` X ``].
+b. Find the probability that at least one head is observed.
+END_PGML
+Section::End();
+
+Section::Begin("Definition");
+BEGIN_PGML
+The probability distribution of a discrete random variable [`` X ``] is a list of each possible value of [`` X ``] together with the probability that [`` X ``] takes that value in one trial of the experiment.
+
+**Checkpoint:** Which statement best matches the definition of a probability distribution?
+
+[@ $rb_def->buttons() @]*
+END_PGML
+ANS($rb_def->cmp);
+Section::End();
+
+Section::Begin("Two properties");
+BEGIN_PGML
+Any probability distribution for a discrete random variable must satisfy:
+
+1. Each probability [`` P(x) ``] must be between 0 and 1: [`` 0 \le P(x) \le 1 ``]
+2. The sum of all the probabilities is 1: [`` \sum P(x) = 1 ``]
+
+Now decide whether each table is a valid probability distribution table.
+
+**Table 1**
+
+[`` \begin{array}{c|ccc}
+x & 0 & 1 & 2 \\
+\hline
+P(X=x) & 0.25 & 0.50 & 0.25
+\end{array} ``]
+
+Does this represent a probability distribution table?
+
+[@ $rb_pd1->buttons() @]*
+
+---
+
+**Table 2**
+
+[`` \begin{array}{c|ccc}
+x & 0 & 1 & 2 \\
+\hline
+P(X=x) & 0.30 & 0.60 & 0.30
+\end{array} ``]
+
+Does this represent a probability distribution table?
+
+[@ $rb_pd2->buttons() @]*
+
+---
+
+**Table 3**
+
+[`` \begin{array}{c|ccc}
+x & 0 & 1 & 2 \\
+\hline
+P(X=x) & -0.10 & 0.60 & 0.50
+\end{array} ``]
+
+Does this represent a probability distribution table?
+
+[@ $rb_pd3->buttons() @]*
+
+---
+
+**Table 4**
+
+[`` \begin{array}{c|cc}
+x & 0 & 1 \\
+\hline
+P(X=x) & 0.25 & 0.75
+\end{array} ``]
+
+Assume [`` X ``] is supposed to have possible values [`` \{0,1,2\} ``].
+Does this represent a probability distribution table?
+
+[@ $rb_pd4->buttons() @]*
+END_PGML
+ANS($rb_pd1->cmp);
+ANS($rb_pd2->cmp);
+ANS($rb_pd3->cmp);
+ANS($rb_pd4->cmp);
+Section::End();
+
+Section::Begin("Outcomes and the random variable");
+BEGIN_PGML
+For two coin tosses, the outcomes are:
+[`` \{\text{HH},\text{HT},\text{TH},\text{TT}\} ``]
+and they are all equally likely.
+
+Now compute [`` X ``] (the number of heads) for each outcome:
+
+- [`` \text{HH} ``] gives [`` X=2 ``]
+- [`` \text{HT} ``] gives [`` X=1 ``]
+- [`` \text{TH} ``] gives [`` X=1 ``]
+- [`` \text{TT} ``] gives [`` X=0 ``]
+
+How many possible values can [`` X ``] take?
+
+[____]{$cmp_k}
+END_PGML
+Section::End();
+
+Section::Begin("Construct the probability distribution");
+BEGIN_PGML
+**How to build the table:**
+For each value of [`` X ``], count how many of the 4 equally likely outcomes produce that value, then divide by 4.
+
+Fill in the probability distribution table:
+END_PGML
+
+BEGIN_TEXT
+$BCENTER
+
+
+ | \(x\) |
+ \(P(X=x)\) |
+
+
+ | 0 |
+
+
+ \{ NAMED_ANS_RULE("p0",12) \}
+
+ |
+
+
+ | 1 |
+
+
+ \{ NAMED_ANS_RULE("p1",12) \}
+
+ |
+
+
+ | 2 |
+
+
+ \{ NAMED_ANS_RULE("p2",12) \}
+
+ |
+
+
+$ECENTER
+END_TEXT
+
+Section::End();
+
+# Register evaluators immediately after the table (top-to-bottom, left-to-right)
+NAMED_ANS("p0", $cmp_P0);
+NAMED_ANS("p1", $cmp_P1);
+NAMED_ANS("p2", $cmp_P2);
+
+Section::Begin("Check the two properties");
+BEGIN_PGML
+Now check the second property: the probabilities must add to 1.
+
+Compute:
+[`` P(X=0)+P(X=1)+P(X=2)= ``] [____]{$cmp_sumP}
+END_PGML
+Section::End();
+
+Section::Begin("At least one head (Part b)");
+BEGIN_PGML
+“At least one head” means [`` X \ge 1 ``], which means [`` X=1 ``] or [`` X=2 ``].
+
+Compute:
+[`` P(\text{at least one head}) = P(X=1)+P(X=2)= ``] [____]{$cmp_Patleast}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating 1–5)
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning combinations?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_PD_GuidedProblem2.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_PD_GuidedProblem2.pg
new file mode 100644
index 0000000000..d969e762f2
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_PD_GuidedProblem2.pg
@@ -0,0 +1,321 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Probability Distribution of the Sum of Two Dice (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Random Variables)
+## Level(2)
+## KEYWORDS('probability distribution','discrete random variable','two dice','sum','probability table')
+## Static(1)
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser detection (hide rating in LB)
+# ----------------------------------------------------------------
+$inLibraryBrowser = $main::inLibraryBrowser || 0;
+
+# =======================================================
+# Context & Data
+# =======================================================
+Context("Numeric");
+
+$n_outcomes = Compute("36");
+$min_sum = Compute("2");
+$max_sum = Compute("12");
+$k_vals = Compute("11"); # sums 2..12
+
+$P2 = Compute("1/36");
+$P3 = Compute("2/36");
+$P4 = Compute("3/36");
+$P5 = Compute("4/36");
+$P6 = Compute("5/36");
+$P7 = Compute("6/36");
+$P8 = Compute("5/36");
+$P9 = Compute("4/36");
+$P10 = Compute("3/36");
+$P11 = Compute("2/36");
+$P12 = Compute("1/36");
+
+$sumP = Compute("1");
+$Pge9 = Compute("5/18");
+$Peven = Compute("1/2");
+
+# =======================================================
+# Evaluators (keep them simple for LB stability)
+# =======================================================
+
+$cmp_n_outcomes = $n_outcomes->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 6) < 1e-6 } =>
+ "One die has 6 outcomes. With two dice, use ordered pairs (first die, second die).",
+));
+
+$cmp_min_sum = $min_sum->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 1) < 1e-6 } =>
+ "The smallest sum uses the smallest face on each die.",
+));
+
+$cmp_max_sum = $max_sum->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 6) < 1e-6 } =>
+ "The largest sum uses the largest face on each die.",
+));
+
+$cmp_k = $k_vals->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - 12) < 1e-6 } =>
+ "12 is the largest sum, not the number of possible sums.",
+));
+
+# Table probabilities: plain cmp (LB-safe)
+$cmp_P2 = $P2->cmp;
+$cmp_P3 = $P3->cmp;
+$cmp_P4 = $P4->cmp;
+$cmp_P5 = $P5->cmp;
+$cmp_P6 = $P6->cmp;
+$cmp_P7 = $P7->cmp;
+$cmp_P8 = $P8->cmp;
+$cmp_P9 = $P9->cmp;
+$cmp_P10 = $P10->cmp;
+$cmp_P11 = $P11->cmp;
+$cmp_P12 = $P12->cmp;
+
+$cmp_sumP = $sumP->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (5/18)) < 1e-6 } =>
+ "5/18 is P(X>=9), not the sum of all probabilities.",
+ sub { abs($_[0] - (1/2)) < 1e-6 } =>
+ "1/2 is P(X even), not the sum of all probabilities.",
+));
+
+$cmp_Pge9 = $Pge9->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (10/36)) < 1e-6 } =>
+ "Good: add P(9)+P(10)+P(11)+P(12), then simplify if you want.",
+ sub { abs($_[0] - (1/6)) < 1e-6 } =>
+ "1/6 is only P(X=12). For X>=9 you must add several values.",
+));
+
+$cmp_Peven = $Peven->cmp->withPostFilter(AnswerHints(
+ sub { abs($_[0] - (18/36)) < 1e-6 } =>
+ "Correct. You can simplify 18/36.",
+ sub { abs($_[0] - (1/4)) < 1e-6 } =>
+ "Even sum happens when both dice have the same parity (even+even or odd+odd).",
+));
+
+# =======================================================
+# Rating (1–5) (hidden in LB)
+# =======================================================
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = eval { $student->value };
+
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ansHash->{score} = 1;
+ $ansHash->{ans_message} = "Thanks!";
+ } else {
+ $ansHash->{score} = 0;
+ $ansHash->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+ return $ansHash->{score};
+ }
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin();
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A pair of fair dice is rolled. Let [`` X ``] denote the sum of the number of dots on the top faces.
+
+a. Construct the probability distribution of [`` X ``].
+b. Find [`` P(X \ge 9) ``].
+c. Find the probability that [`` X ``] takes an even value.
+END_PGML
+Section::End();
+
+Section::Begin("Outcomes and possible values of X");
+BEGIN_PGML
+When two dice are rolled, outcomes can be represented as ordered pairs [`` (i,j) ``].
+
+1) How many equally likely outcomes are there?
+
+[____]{$cmp_n_outcomes}
+
+2) Smallest possible value of [`` X ``]:
+
+[____]{$cmp_min_sum}
+
+3) Largest possible value of [`` X ``]:
+
+[____]{$cmp_max_sum}
+
+4) How many possible values can [`` X ``] take?
+
+[____]{$cmp_k}
+END_PGML
+Section::End();
+
+Section::Begin("Construct the probability distribution (Part a)");
+BEGIN_PGML
+**How to build the table:**
+For each sum [`` x ``], count how many ordered pairs [`` (i,j) ``] give that sum, then divide by 36.
+
+Fill in the probability distribution table (fractions like 4/36 are fine):
+END_PGML
+
+BEGIN_TEXT
+$BCENTER
+
+
+ | \(x\) |
+ \(P(X=x)\) |
+
+
+
+ | 2 |
+
+ \{ NAMED_ANS_RULE("p2",12) \}
+ |
+
+
+ | 3 |
+
+ \{ NAMED_ANS_RULE("p3",12) \}
+ |
+
+
+ | 4 |
+
+ \{ NAMED_ANS_RULE("p4",12) \}
+ |
+
+
+ | 5 |
+
+ \{ NAMED_ANS_RULE("p5",12) \}
+ |
+
+
+ | 6 |
+
+ \{ NAMED_ANS_RULE("p6",12) \}
+ |
+
+
+ | 7 |
+
+ \{ NAMED_ANS_RULE("p7",12) \}
+ |
+
+
+ | 8 |
+
+ \{ NAMED_ANS_RULE("p8",12) \}
+ |
+
+
+ | 9 |
+
+ \{ NAMED_ANS_RULE("p9",12) \}
+ |
+
+
+ | 10 |
+
+ \{ NAMED_ANS_RULE("p10",12) \}
+ |
+
+
+ | 11 |
+
+ \{ NAMED_ANS_RULE("p11",12) \}
+ |
+
+
+ | 12 |
+
+ \{ NAMED_ANS_RULE("p12",12) \}
+ |
+
+
+$ECENTER
+END_TEXT
+
+Section::End();
+
+# Register evaluators immediately after the table (top-to-bottom)
+NAMED_ANS("p2", $cmp_P2);
+NAMED_ANS("p3", $cmp_P3);
+NAMED_ANS("p4", $cmp_P4);
+NAMED_ANS("p5", $cmp_P5);
+NAMED_ANS("p6", $cmp_P6);
+NAMED_ANS("p7", $cmp_P7);
+NAMED_ANS("p8", $cmp_P8);
+NAMED_ANS("p9", $cmp_P9);
+NAMED_ANS("p10", $cmp_P10);
+NAMED_ANS("p11", $cmp_P11);
+NAMED_ANS("p12", $cmp_P12);
+
+Section::Begin("Check the probability distribution");
+BEGIN_PGML
+A valid probability distribution must have probabilities that add to 1.
+
+Compute:
+[`` P(X=2)+P(X=3)+\cdots+P(X=12)= ``] [____]{$cmp_sumP}
+END_PGML
+Section::End();
+
+Section::Begin("Compute P(X >= 9) (Part b)");
+BEGIN_PGML
+[`` X \ge 9 ``] means [`` X=9,10,11,12 ``].
+
+Compute:
+[`` P(X \ge 9)= ``] [____]{$cmp_Pge9}
+END_PGML
+Section::End();
+
+Section::Begin("Probability that X is even (Part c)");
+BEGIN_PGML
+[`` X ``] is even when [`` X \in \{2,4,6,8,10,12\} ``].
+
+Compute:
+[`` P(X \text{ is even})= ``] [____]{$cmp_Peven}
+END_PGML
+Section::End();
+
+# Feedback (hidden in LB)
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning probability distributions?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_TypesOfRVs_GuidedProblem1.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_TypesOfRVs_GuidedProblem1.pg
new file mode 100644
index 0000000000..8d8944c6ed
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_TypesOfRVs_GuidedProblem1.pg
@@ -0,0 +1,389 @@
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Context
+# =======================================================
+Context("Numeric");
+Context()->flags->set(implicitMultiplication => 1);
+
+# =======================================================
+# Step 2 MC: Not a random variable
+# =======================================================
+$rb_not_rv = RadioButtons(
+ [
+ 'Toss a coin 10 times and let \(X\) be the number of heads.',
+ 'Roll a die once and let \(X\) be the number shown.',
+ 'Toss a coin once and record the result as H or T.',
+ 'Measure the time (in seconds) until a website loads and let \(X\) be that time.',
+ 'Choose 3 students and let \(X\) be the number of left-handed students.',
+ ],
+ 2, # NOT numeric
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Practice: 8 NEW random variables (type + possible values)
+# NOTE: options are reordered so correct choices are NOT always A.
+# =======================================================
+
+# RV1: Die once (Discrete) --- values correct is B
+$rb_rv1_type = RadioButtons(
+ [ 'Discrete', 'Continuous' ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+$rb_rv1_vals = RadioButtons(
+ [
+ 'Possible values: \( \{0,1,2,3,4,5,6\} \)',
+ 'Possible values: \( \{1,2,3,4,5,6\} \)', # correct (B)
+ 'Possible values: \( [1,6] \)',
+ ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# RV2: # of sixes in 8 rolls (Discrete) --- type order swapped, values correct is C
+$rb_rv2_type = RadioButtons(
+ [ 'Continuous', 'Discrete' ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+$rb_rv2_vals = RadioButtons(
+ [
+ 'Possible values: \( [0,8] \)',
+ 'Possible values: \( \{1,2,3,4,5,6,7,8\} \)',
+ 'Possible values: \( \{0,1,2,3,4,5,6,7,8\} \)', # correct (C)
+ ],
+ 2,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# RV3: toss coin until tails, X = number of tosses (Discrete) --- values correct is B
+$rb_rv3_type = RadioButtons(
+ [ 'Discrete', 'Continuous' ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+$rb_rv3_vals = RadioButtons(
+ [
+ 'Possible values: \( \{0,1,2,3,\dots\} \)',
+ 'Possible values: \( \{1,2,3,4,\dots\} \)', # correct (B)
+ 'Possible values: \( (0,1) \)',
+ ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# RV4: customers in an hour (Discrete) --- type order swapped, values correct is C
+$rb_rv4_type = RadioButtons(
+ [ 'Continuous', 'Discrete' ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+$rb_rv4_vals = RadioButtons(
+ [
+ 'Possible values: \( \{1,2,3,4,\dots\} \)',
+ 'Possible values: \( [0,\infty) \)',
+ 'Possible values: \( \{0,1,2,3,\dots\} \)', # correct (C)
+ ],
+ 2,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# RV5: exam score out of 100 (Continuous) --- values correct is B
+$rb_rv5_type = RadioButtons(
+ [ 'Discrete', 'Continuous' ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+$rb_rv5_vals = RadioButtons(
+ [
+ 'Possible values: \( \{0,1,2,3,\dots,100\} \)',
+ 'Possible values: \( [0,100] \)', # correct (B)
+ 'Possible values: \( (0,100) \)',
+ ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# RV6: point strictly between ends of a 1-meter stick (Continuous) --- type order swapped, values correct is C
+$rb_rv6_type = RadioButtons(
+ [ 'Continuous', 'Discrete' ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+$rb_rv6_vals = RadioButtons(
+ [
+ 'Possible values: \( [0,1] \)',
+ 'Possible values: \( \{0,1\} \)',
+ 'Possible values: \( (0,1) \)', # correct (C)
+ ],
+ 2,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# RV7: waiting time until next bus arrives (Continuous) --- values correct is B
+$rb_rv7_type = RadioButtons(
+ [ 'Discrete', 'Continuous' ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+$rb_rv7_vals = RadioButtons(
+ [
+ 'Possible values: \( \{0,1,2,3,\dots\} \)',
+ 'Possible values: \( [0,\infty) \)', # correct (B)
+ 'Possible values: \( (0,\infty) \)',
+ ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# RV8: classroom temperature at noon, assume between 15 and 30 (Continuous) --- type order swapped, values correct is C
+$rb_rv8_type = RadioButtons(
+ [ 'Continuous', 'Discrete' ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+$rb_rv8_vals = RadioButtons(
+ [
+ 'Possible values: \( (15,30) \)',
+ 'Possible values: \( [0,100] \)',
+ 'Possible values: \( [15,30] \)', # correct (C)
+ ],
+ 2,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Rating (1–5)
+# =======================================================
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = eval { $student->value };
+
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ansHash->{score} = 1;
+ $ansHash->{ans_message} = "Thanks!";
+ } else {
+ $ansHash->{score} = 0;
+ $ansHash->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+ return $ansHash->{score};
+ }
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin();
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+In this guided problem, we learn what a **random variable** is and how to classify it as **discrete** or **continuous**.
+
+Then you will classify 8 random variables by:
+- the **type** (discrete or continuous)
+- the **set of possible values**
+END_PGML
+Section::End();
+
+Section::Begin("What is a random variable?");
+BEGIN_PGML
+A **random variable** is a **numerical** quantity that is generated by a random experiment.
+
+**Checkpoint:** Which one is **not** a random variable?
+
+[_]{$rb_not_rv}
+END_PGML
+Section::End();
+
+Section::Begin("Discrete vs Continuous");
+BEGIN_PGML
+A random variable is called **discrete** if it has either a **finite** or a **countable** number of possible values.
+
+A random variable is called **continuous** if its possible values contain a **whole interval** of numbers.
+
+Key ideas:
+
+- Discrete (finite): values can be listed and the list ends.
+- Discrete (countably infinite): values can be listed forever, like [`` \{1,2,3,4,\dots\} ``].
+- Continuous: values fill an interval like [`` [a,b] ``] or [`` (a,b) ``] or [`` [0,\infty) ``].
+END_PGML
+Section::End();
+
+Section::Begin("Examples (for learning the concept)");
+BEGIN_PGML
+Here are examples to model what we mean by “type” and “possible values.”
+
+**Example 1: Roll two fair dice**
+Let [`` X ``] be the sum of the dots on the top faces.
+Type: **Discrete (finite)**
+Possible values: [`` \{2,3,4,5,6,7,8,9,10,11,12\} ``]
+
+**Example 2: Flip a fair coin repeatedly**
+Let [`` X ``] be the number of tosses until the coin lands heads.
+Type: **Discrete (countably infinite)**
+Possible values: [`` \{1,2,3,4,\dots\} ``]
+
+**Example 3: Measure the voltage at an electrical outlet**
+Let [`` X ``] be the voltage measured.
+Type: **Continuous**
+Possible values (an interval): [`` [118,122] ``]
+
+**Example 4: Operate a light bulb until it burns out**
+Let [`` X ``] be the time until the bulb burns out.
+Type: **Continuous**
+Possible values: [`` [0,\infty) ``]
+END_PGML
+Section::End();
+
+Section::Begin("Practice 1 (Random Variables 1–2)");
+BEGIN_PGML
+**RV #1**
+Experiment: Roll a fair die once.
+Let [`` X ``] be the number rolled.
+
+Type:
+[_]{$rb_rv1_type}
+Possible values:
+[_]{$rb_rv1_vals}
+
+---
+
+**RV #2**
+Experiment: Roll a fair die 8 times.
+Let [`` X ``] be the number of sixes rolled.
+
+Type:
+[_]{$rb_rv2_type}
+Possible values:
+[_]{$rb_rv2_vals}
+END_PGML
+Section::End();
+
+Section::Begin("Practice 2 (Random Variables 3–4)");
+BEGIN_PGML
+**RV #3**
+Experiment: Toss a fair coin until you get tails.
+Let [`` X ``] be the number of tosses required.
+
+Type:
+[_]{$rb_rv3_type}
+Possible values:
+[_]{$rb_rv3_vals}
+
+---
+
+**RV #4**
+Experiment: Count the number of customers who enter a store between 12:00 and 1:00.
+Let [`` X ``] be the number of customers.
+
+Type:
+[_]{$rb_rv4_type}
+Possible values:
+[_]{$rb_rv4_vals}
+END_PGML
+Section::End();
+
+Section::Begin("Practice 3 (Random Variables 5–6)");
+BEGIN_PGML
+**RV #5**
+Experiment: Randomly pick a student and record their exam score out of 100 (as a percentage).
+Let [`` X ``] be the score.
+
+Type:
+[_]{$rb_rv5_type}
+Possible values:
+[_]{$rb_rv5_vals}
+
+---
+
+**RV #6**
+Experiment: Randomly choose a point strictly between the ends of a 1-meter stick.
+Let [`` X ``] be the distance from the left end (in meters).
+
+Type:
+[_]{$rb_rv6_type}
+Possible values:
+[_]{$rb_rv6_vals}
+END_PGML
+Section::End();
+
+Section::Begin("Practice 4 (Random Variables 7–8)");
+BEGIN_PGML
+**RV #7**
+Experiment: Measure the waiting time (in minutes) until the next bus arrives.
+Let [`` X ``] be the waiting time.
+
+Type:
+[_]{$rb_rv7_type}
+Possible values:
+[_]{$rb_rv7_vals}
+
+---
+
+**RV #8**
+Experiment: Measure the classroom temperature (in °C) at noon, assuming it stays between 15 and 30.
+Let [`` X ``] be the temperature.
+
+Type:
+[_]{$rb_rv8_type}
+Possible values:
+[_]{$rb_rv8_vals}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating 1–5)
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning combinations?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_TypesOfRVs_GuidedProblem2.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_TypesOfRVs_GuidedProblem2.pg
new file mode 100644
index 0000000000..619ef61d0d
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/DiscreteRandomVariables/DiscreteRandomVariables_TypesOfRVs_GuidedProblem2.pg
@@ -0,0 +1,402 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Random Variables: Discrete vs Continuous (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Random Variables)
+## Level(2)
+## KEYWORDS('random variable','discrete','continuous','possible values','countable','interval')
+## Static(1)
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# =======================================================
+# Context
+# =======================================================
+Context("Numeric");
+Context()->flags->set(implicitMultiplication => 1);
+
+# =======================================================
+# Step 2 MC: Not a random variable
+# =======================================================
+$rb_not_rv = RadioButtons(
+ [
+ 'Toss a coin 10 times and let \(X\) be the number of heads.',
+ 'Roll a die once and let \(X\) be the number shown.',
+ 'Toss a coin once and record the result as H or T.',
+ 'Measure the time (in seconds) until a website loads and let \(X\) be that time.',
+ 'Choose 3 students and let \(X\) be the number of left-handed students.',
+ ],
+ 2, # NOT numeric
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Practice: 8 NEW random variables (type + possible values)
+# NOTE: options are reordered so correct choices are NOT always A.
+# =======================================================
+
+# RV1: Roll two dice, X = absolute difference (Discrete) --- values correct is C
+$rb_rv1_type = RadioButtons(
+ [ 'Discrete', 'Continuous' ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+$rb_rv1_vals = RadioButtons(
+ [
+ 'Possible values: \( \{1,2,3,4,5,6\} \)',
+ 'Possible values: \( [0,5] \)',
+ 'Possible values: \( \{0,1,2,3,4,5\} \)', # correct (C)
+ ],
+ 2,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# RV2: Choose 5 items, X = number defective (Discrete) --- type swapped, values correct is B
+$rb_rv2_type = RadioButtons(
+ [ 'Continuous', 'Discrete' ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+$rb_rv2_vals = RadioButtons(
+ [
+ 'Possible values: \( \{1,2,3,4,5\} \)',
+ 'Possible values: \( \{0,1,2,3,4,5\} \)', # correct (B)
+ 'Possible values: \( [0,5] \)',
+ ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# RV3: Flip a coin until first tails, X = number of flips (Discrete) --- values correct is B
+$rb_rv3_type = RadioButtons(
+ [ 'Discrete', 'Continuous' ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+$rb_rv3_vals = RadioButtons(
+ [
+ 'Possible values: \( \{0,1,2,3,\dots\} \)',
+ 'Possible values: \( \{1,2,3,4,\dots\} \)', # correct (B)
+ 'Possible values: \( (0,1) \)',
+ ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# RV4: Number of emails received today (Discrete) --- values correct is C
+$rb_rv4_type = RadioButtons(
+ [ 'Discrete', 'Continuous' ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+$rb_rv4_vals = RadioButtons(
+ [
+ 'Possible values: \( \{1,2,3,4,\dots\} \)',
+ 'Possible values: \( [0,\infty) \)',
+ 'Possible values: \( \{0,1,2,3,\dots\} \)', # correct (C)
+ ],
+ 2,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# RV5: Amount of gasoline in a tank after filling (liters), assume between 0 and 60 (Continuous) --- values correct is C
+$rb_rv5_type = RadioButtons(
+ [ 'Discrete', 'Continuous' ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+$rb_rv5_vals = RadioButtons(
+ [
+ 'Possible values: \( \{0,1,2,\dots,60\} \)',
+ 'Possible values: \( (0,60) \)',
+ 'Possible values: \( [0,60] \)', # correct (C)
+ ],
+ 2,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# RV6: Choose a random time strictly during a 60-minute lecture, X = minutes after start (Continuous) --- values correct is B
+$rb_rv6_type = RadioButtons(
+ [ 'Continuous', 'Discrete' ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+$rb_rv6_vals = RadioButtons(
+ [
+ 'Possible values: \( [0,60] \)',
+ 'Possible values: \( (0,60) \)', # correct (B)
+ 'Possible values: \( \{0,1,2,\dots,60\} \)',
+ ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# RV7: Distance from home to school (km) for a randomly selected student (Continuous) --- values correct is A
+$rb_rv7_type = RadioButtons(
+ [ 'Discrete', 'Continuous' ],
+ 1,
+ labels => "ABC",
+ displayLabels => 0,
+);
+$rb_rv7_vals = RadioButtons(
+ [
+ 'Possible values: \( [0,\infty) \)', # correct (A)
+ 'Possible values: \( (0,\infty) \)',
+ 'Possible values: \( \{0,1,2,3,\dots\} \)',
+ ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# RV8: Temperature of coffee right after pouring (°C), assume strictly between 0 and 100 (Continuous) --- values correct is C
+$rb_rv8_type = RadioButtons(
+ [ 'Continuous', 'Discrete' ],
+ 0,
+ labels => "ABC",
+ displayLabels => 0,
+);
+$rb_rv8_vals = RadioButtons(
+ [
+ 'Possible values: \( [0,100] \)',
+ 'Possible values: \( \{0,1,2,\dots,100\} \)',
+ 'Possible values: \( (0,100) \)', # correct (C)
+ ],
+ 2,
+ labels => "ABC",
+ displayLabels => 0,
+);
+
+# =======================================================
+# Rating (1–5)
+# =======================================================
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ my $v = eval { $student->value };
+
+ if (defined($v) && $v == int($v) && $v >= 1 && $v <= 5) {
+ $ansHash->{score} = 1;
+ $ansHash->{ans_message} = "Thanks!";
+ } else {
+ $ansHash->{score} = 0;
+ $ansHash->{ans_message} = "Please enter an integer from 1 to 5.";
+ }
+ return $ansHash->{score};
+ }
+);
+
+# =======================================================
+# Scaffold
+# =======================================================
+Scaffold::Begin();
+
+Section::Begin("Problem Statement");
+BEGIN_PGML
+In this guided problem, we learn what a **random variable** is and how to classify it as **discrete** or **continuous**.
+
+Then you will classify 8 random variables by:
+- the **type** (discrete or continuous)
+- the **set of possible values**
+END_PGML
+Section::End();
+
+Section::Begin("What is a random variable?");
+BEGIN_PGML
+A **random variable** is a **numerical** quantity that is generated by a random experiment.
+
+**Checkpoint:** Which one is **not** a random variable?
+
+[_]{$rb_not_rv}
+END_PGML
+Section::End();
+
+Section::Begin("Discrete vs Continuous");
+BEGIN_PGML
+A random variable is called **discrete** if it has either a **finite** or a **countable** number of possible values.
+
+A random variable is called **continuous** if its possible values contain a **whole interval** of numbers.
+
+Key ideas:
+
+- Discrete (finite): values can be listed and the list ends.
+- Discrete (countably infinite): values can be listed forever, like [`` \{1,2,3,4,\dots\} ``].
+- Continuous: values fill an interval like [`` [a,b] ``] or [`` (a,b) ``] or [`` [0,\infty) ``].
+END_PGML
+Section::End();
+
+Section::Begin("Examples (for learning the concept)");
+BEGIN_PGML
+Here are examples to model what we mean by “type” and “possible values.”
+
+**Example 1: Spin a fair spinner labeled 1 through 8**
+Let [`` X ``] be the number you land on.
+Type: **Discrete (finite)**
+Possible values: [`` \{1,2,3,4,5,6,7,8\} ``]
+
+**Example 2: Roll a fair die repeatedly**
+Let [`` X ``] be the number of rolls until you get a 6.
+Type: **Discrete (countably infinite)**
+Possible values: [`` \{1,2,3,4,\dots\} ``]
+
+**Example 3: Measure the speed of a car in a school zone**
+Let [`` X ``] be the speed (km/h), assuming it stays between 30 and 50.
+Type: **Continuous**
+Possible values (a closed interval): [`` [30,50] ``]
+
+**Example 4: Choose a point strictly inside a circle of radius 1**
+Let [`` X ``] be the distance from the center.
+Type: **Continuous**
+Possible values (an open interval): [`` (0,1) ``]
+END_PGML
+Section::End();
+
+Section::Begin("Practice 1 (Random Variables 1–2)");
+BEGIN_PGML
+**RV #1**
+Experiment: Roll two fair dice and compute the absolute difference between the two numbers.
+Let [`` X ``] be the absolute difference.
+
+Type:
+[_]{$rb_rv1_type}
+Possible values:
+[_]{$rb_rv1_vals}
+
+---
+
+**RV #2**
+Experiment: Inspect 5 items and count how many are defective.
+Let [`` X ``] be the number of defective items.
+
+Type:
+[_]{$rb_rv2_type}
+Possible values:
+[_]{$rb_rv2_vals}
+END_PGML
+Section::End();
+
+Section::Begin("Practice 2 (Random Variables 3–4)");
+BEGIN_PGML
+**RV #3**
+Experiment: Flip a fair coin until you get tails.
+Let [`` X ``] be the number of flips required.
+
+Type:
+[_]{$rb_rv3_type}
+Possible values:
+[_]{$rb_rv3_vals}
+
+---
+
+**RV #4**
+Experiment: Count how many emails you receive in a day.
+Let [`` X ``] be the number of emails received.
+
+Type:
+[_]{$rb_rv4_type}
+Possible values:
+[_]{$rb_rv4_vals}
+END_PGML
+Section::End();
+
+Section::Begin("Practice 3 (Random Variables 5–6)");
+BEGIN_PGML
+**RV #5**
+Experiment: Measure the amount of gasoline in a car’s tank after filling (in liters), assuming it stays between 0 and 60.
+Let [`` X ``] be the amount of gasoline.
+
+Type:
+[_]{$rb_rv5_type}
+Possible values:
+[_]{$rb_rv5_vals}
+
+---
+
+**RV #6**
+Experiment: Choose a random time strictly during a 60-minute lecture.
+Let [`` X ``] be the number of minutes after the lecture starts.
+
+Type:
+[_]{$rb_rv6_type}
+Possible values:
+[_]{$rb_rv6_vals}
+END_PGML
+Section::End();
+
+Section::Begin("Practice 4 (Random Variables 7–8)");
+BEGIN_PGML
+**RV #7**
+Experiment: Randomly select a student and record the distance (in km) from their home to school.
+Let [`` X ``] be the distance.
+
+Type:
+[_]{$rb_rv7_type}
+Possible values:
+[_]{$rb_rv7_vals}
+
+---
+
+**RV #8**
+Experiment: Measure the temperature of coffee (in °C) right after it is poured, assuming it is strictly between 0 and 100.
+Let [`` X ``] be the temperature.
+
+Type:
+[_]{$rb_rv8_type}
+Possible values:
+[_]{$rb_rv8_vals}
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating 1–5)
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING) {
+ Section::Begin("Feedback");
+ BEGIN_PGML
+How useful was this guided problem for learning combinations?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (enter 1-5): [___]{$cmp_rating}
+END_PGML
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_LargeSample_GuidedProblem1.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_LargeSample_GuidedProblem1.pg
new file mode 100644
index 0000000000..2c1893b5cb
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_LargeSample_GuidedProblem1.pg
@@ -0,0 +1,435 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Large-Sample Confidence Intervals for the Mean (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Confidence Intervals)
+## DBsection(Confidence Interval for the Mean)
+## Level(2)
+## KEYWORDS('confidence interval','large sample','mean','known sigma','unknown sigma','confidence level','critical value','z alpha over 2','sample standard deviation')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser detection (LB stability)
+# ----------------------------------------------------------------
+$inLibraryBrowser = ($envir{isLibraryBrowser} || $envir{isLibrary} || 0);
+
+Context("Numeric");
+
+# =======================================================
+# Postfilter: add a hint ONLY when the answer is wrong
+# =======================================================
+sub HintIfWrong {
+ my $msg = shift;
+ return sub {
+ my $ans = shift;
+ if (defined($ans->{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+ return $ans;
+ };
+}
+
+# =======================================================
+# Data for sample standard deviation checkpoint
+# =======================================================
+$x1 = 8;
+$x2 = 10;
+$x3 = 12;
+$x4 = 14;
+$x5 = 16;
+
+# sample standard deviation = sqrt(40/4) = sqrt(10)
+$s_exact = 3.16227766016838;
+
+# =======================================================
+# Correct targets
+# =======================================================
+$alpha_98 = Real(0.02);
+
+$z_010 = Real(1.645);
+$z_005 = Real(1.960);
+$z_002 = Real(2.325);
+$z_001 = Real(2.575);
+
+# =======================================================
+# Tolerances
+# =======================================================
+$tol_alpha = 0.0005;
+$tol_s = 0.02;
+$tol_z = 0.01;
+
+# =======================================================
+# Comparators
+# =======================================================
+
+# Section B MC: correct choice = 2 (xbar)
+$cmp_point_est = Real(2)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+ return ($v == 2) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong("The appropriate point estimate for mu is the sample mean xbar.")
+);
+
+$cmp_alpha_98 = $alpha_98->cmp(
+ tolType => "absolute",
+ tolerance => $tol_alpha
+)->withPostFilter(
+ HintIfWrong("For a 98% confidence level, 1 - alpha = 0.98, so alpha = 0.02.")
+);
+
+# Section C MC: correct choice = 3
+$cmp_conf_meaning = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+ return ($v == 3) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong("The confidence level describes the long-run success rate of the method over many random samples.")
+);
+
+$cmp_s = Real($s_exact)->cmp(
+ tolType => "absolute",
+ tolerance => $tol_s
+)->withPostFilter(
+ HintIfWrong("Use the sample standard deviation on your calculator, not the population standard deviation.")
+);
+
+$cmp_z_010 = $z_010->cmp(
+ tolType => "absolute",
+ tolerance => $tol_z
+)->withPostFilter(
+ HintIfWrong("For alpha = 0.10, alpha/2 = 0.05, so the cutoff is z_(0.05) = 1.645.")
+);
+
+$cmp_z_005 = $z_005->cmp(
+ tolType => "absolute",
+ tolerance => $tol_z
+)->withPostFilter(
+ HintIfWrong("For alpha = 0.05, alpha/2 = 0.025, so the cutoff is z_(0.025) = 1.960.")
+);
+
+$cmp_z_002 = $z_002->cmp(
+ tolType => "absolute",
+ tolerance => $tol_z
+)->withPostFilter(
+ HintIfWrong("For alpha = 0.02, alpha/2 = 0.01, so the cutoff is z_(0.01) = 2.326.")
+);
+
+$cmp_z_001 = $z_001->cmp(
+ tolType => "absolute",
+ tolerance => $tol_z
+)->withPostFilter(
+ HintIfWrong("For alpha = 0.01, alpha/2 = 0.005, so the cutoff is z_(0.005) = 2.576.")
+);
+
+# Rating checker
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "always",
+ is_open => "always"
+ );
+} else {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect"
+ );
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+
+BEGIN_PGML
+In this Guided Problem, we introduce the idea of a large-sample confidence interval for the population mean [``\mu``].
+
+Assume a random sample of size [``n \ge 30``] is taken from a population. The goal is to estimate [``\mu``] using the sample data.
+
+In this GP, you will learn:
+
+- what a [``100(1-\alpha)\%``] confidence interval means,
+- what the confidence level represents,
+- the two large-sample formulas for a confidence interval for [``\mu``],
+- and the normal cutoffs [``z_{\alpha/2}``] for common values of [``\alpha``].
+
+Rounding: Round cutoff values to 3 decimals.
+END_PGML
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 2 — Section B
+# -------------------------------------------------------
+Section::Begin("Section B — Appropriate point estimate for mu");
+
+BEGIN_PGML
+A confidence interval for [``\mu``] has the form
+
+[``\text{estimate} \pm \text{margin of error}``]
+
+What is the appropriate point estimate for the population mean [``\mu``]?
+
+1) [``\mu``]
+2) [``\bar x``]
+3) [``\sigma``]
+4) [``s``]
+5) [``\alpha``]
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_point_est);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 3 — Section C
+# -------------------------------------------------------
+Section::Begin("Section C — Level of confidence");
+
+BEGIN_PGML
+When we build a confidence interval, we must consider the required level of confidence.
+
+Common values are usually [``90\%``] ([``\alpha = 0.10``]), [``95\%``] ([``\alpha = 0.05``]), and [``99\%``] ([``\alpha = 0.01``]).
+
+The confidence level describes how the method behaves over many random samples. For example, a [``95\%``] level of confidence means [``95\%``] of intervals built using this method, by repeatedly sampling the population, will capture the actual [``\mu``].
+
+1) If the confidence level is [``98\%``], enter the value of [``\alpha``]:
+
+[____]
+
+2) Choose the best interpretation of a [``100(1-\alpha)\%``] confidence interval:
+
+1) [``100(1-\alpha)\%``] of all sample means are equal to [``\mu``].
+2) There is a [``100(1-\alpha)\%``] chance that [``\mu``] changes from sample to sample.
+3) If we repeatedly took many random samples and built intervals the same way each time, about [``100(1-\alpha)\%``] of those intervals would contain [``\mu``].
+4) A [``100(1-\alpha)\%``] confidence interval always contains [``\mu``].
+5) The confidence level tells us that this particular sample must be correct.
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_alpha_98, $cmp_conf_meaning);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 4 — Section D
+# -------------------------------------------------------
+Section::Begin("Section D — Large-sample formulas and sample standard deviation");
+
+BEGIN_PGML
+For large samples, a confidence interval for [``\mu``] has the form
+
+[``\bar x \pm z_{\alpha/2}(\text{standard error})``]
+
+There are two common large-sample formulas:
+
+**Case 1: sigma known**
+[``\bar x \pm z_{\alpha/2}\dfrac{\sigma}{\sqrt{n}}``]
+
+**Case 2: sigma unknown, but n is large**
+[``\bar x \pm z_{\alpha/2}\dfrac{s}{\sqrt{n}}``]
+
+So when [``\sigma``] is unknown, we replace it with the sample standard deviation [``s``].
+
+Use your calculator to find the **sample standard deviation** of the following data:
+
+[``8,\ 10,\ 12,\ 14,\ 16``]
+
+Enter [``s``]: [____]
+END_PGML
+
+ANS($cmp_s);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 5 — Sections E
+# -------------------------------------------------------
+Section::Begin("Sections E — Cutoff values from the normal table");
+
+BEGIN_PGML
+For a [``100(1-\alpha)\%``] confidence interval:
+
+- the middle area is [``1-\alpha``]
+- the total area in the two tails is [``\alpha``]
+- each tail has area [``\alpha/2``]
+- the positive cutoff is [``z_{\alpha/2}``]
+
+[@ image("cutoff.jpg", width=>520) @]*
+
+Now use the normal table to find the positive cutoff [``z_{\alpha/2}``] for each value of [``\alpha``].
+
+For [``\alpha = 0.10``], enter [``z_{\alpha/2}``]: [____]
+
+For [``\alpha = 0.05``], enter [``z_{\alpha/2}``]: [____]
+
+For [``\alpha = 0.02``], enter [``z_{\alpha/2}``]: [____]
+
+For [``\alpha = 0.01``], enter [``z_{\alpha/2}``]: [____]
+
+Note that smaller [``\alpha``] means higher confidence level, which is desirable. However, smaller [``\alpha``] also means a bigger cutoff value that will result in a bigger margin of error for the confidence interval. This is a trade-off. Higher confidence level comes at the expense of a wider, and thus less precise, confidence interval.
+END_PGML
+
+ANS($cmp_z_010, $cmp_z_005, $cmp_z_002, $cmp_z_001);
+
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating) — hidden in Library Browser
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+ Section::Begin("Feedback");
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+BEGIN_PGML_SOLUTION
+**1. Appropriate point estimate**
+
+A confidence interval for [``\mu``] is centered at the sample mean.
+
+So the appropriate point estimate for the population mean [``\mu``] is
+
+[``\bar x``]
+
+**2. Confidence level and alpha**
+
+If the confidence level is [``98\%``], then
+
+[``1-\alpha = 0.98``]
+
+so
+
+[``\alpha = 0.02``]
+
+The confidence level describes the long-run success rate of the method. For example, a [``95\%``] confidence level means that if we repeatedly sample the population and build intervals the same way each time, about [``95\%``] of those intervals will capture the true [``\mu``].
+
+**3. Large-sample formulas**
+
+For large samples, the confidence interval for [``\mu``] has the form
+
+[``\bar x \pm z_{\alpha/2}(\text{standard error})``]
+
+If [``\sigma``] is known:
+
+[``\bar x \pm z_{\alpha/2}\dfrac{\sigma}{\sqrt{n}}``]
+
+If [``\sigma``] is unknown but the sample is large:
+
+[``\bar x \pm z_{\alpha/2}\dfrac{s}{\sqrt{n}}``]
+
+So when [``\sigma``] is unknown, we use the sample standard deviation [``s``].
+
+**4. Compute the sample standard deviation**
+
+For the data
+
+[``8,\ 10,\ 12,\ 14,\ 16``]
+
+the sample mean is
+
+[``\bar x = 12``]
+
+The deviations from the mean are
+
+[``-4,\ -2,\ 0,\ 2,\ 4``]
+
+Their squares are
+
+[``16,\ 4,\ 0,\ 4,\ 16``]
+
+The sum of squared deviations is
+
+[``40``]
+
+So the sample variance is
+
+[``s^2 = \dfrac{40}{5-1} = 10``]
+
+and the sample standard deviation is
+
+[``s = \sqrt{10} \approx 3.162``]
+
+**5. Cutoff values**
+
+For a [``100(1-\alpha)\%``] confidence interval, each tail has area [``\alpha/2``], and the positive cutoff is [``z_{\alpha/2}``].
+
+The common cutoff values are:
+
+- for [``\alpha = 0.10``]: [``z_{0.05} = 1.645``]
+- for [``\alpha = 0.05``]: [``z_{0.025} = 1.960``]
+- for [``\alpha = 0.02``]: [``z_{0.01} = 2.325``]
+- for [``\alpha = 0.01``]: [``z_{0.005} = 2.575``]
+
+These are the normal-table cutoffs commonly used for large-sample confidence intervals for the mean.
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_LargeSample_GuidedProblem2.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_LargeSample_GuidedProblem2.pg
new file mode 100644
index 0000000000..58b343e75b
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_LargeSample_GuidedProblem2.pg
@@ -0,0 +1,491 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Confidence Interval for the Mean:
+## Large Sample, Sigma Known (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Confidence Intervals)
+## DBsection(Confidence Interval for the Mean)
+## Level(2)
+## KEYWORDS(
+## 'confidence interval',
+## 'population mean',
+## 'large sample',
+## 'known sigma',
+## 'z critical value',
+## 'standard error',
+## 'margin of error'
+## )
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ============================================================
+# Settings
+# ============================================================
+
+# Pilot: usefulness rating toggle
+$ENABLE_GP_RATING = 1;
+
+# Library Browser detection
+$inLibraryBrowser = ($envir{isLibraryBrowser} || $envir{isLibrary} || 0);
+
+Context("Numeric");
+
+# ============================================================
+# Helper: show a hint only when the student's answer is wrong
+# ============================================================
+sub HintIfWrong {
+ my $msg = shift;
+
+ return sub {
+ my $ans = shift;
+
+ if (defined($ans->{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+
+ return $ans;
+ };
+}
+
+# ============================================================
+# Data
+# ============================================================
+$xbar = 483;
+$sigma = 12;
+$n = 64;
+$conf = 0.95;
+
+$alpha = Real(0.05);
+$z_cutoff = Real(1.96);
+$se = Real(1.5);
+$me = Real(2.94);
+$lcl = Real(480.06);
+$ucl = Real(485.94);
+
+# ============================================================
+# Tolerances
+# ============================================================
+$tol_alpha = 0.0005;
+$tol_z = 0.005;
+$tol_se = 0.005;
+$tol_me = 0.01;
+$tol_end = 0.02;
+
+# ============================================================
+# Comparators
+# ============================================================
+
+# ------------------------------------------------------------
+# Formula-selection multiple choice
+# Correct answer: 4
+# ------------------------------------------------------------
+$cmp_formula = Real(4)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ return 0 unless defined $student;
+
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+
+ return ($v == 4) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong(
+ "Because the sample is large and sigma is known, use xbar +/- z_(alpha/2)(sigma/sqrt(n))."
+ )
+);
+
+# ------------------------------------------------------------
+# Alpha
+# ------------------------------------------------------------
+$cmp_alpha = $alpha->cmp(
+ tolType => "absolute",
+ tolerance => $tol_alpha
+)->withPostFilter(
+ HintIfWrong("For a 95% confidence level, 1 - alpha = 0.95, so alpha = 0.05.")
+);
+
+# ------------------------------------------------------------
+# z cutoff
+# ------------------------------------------------------------
+$cmp_z = $z_cutoff->cmp(
+ tolType => "absolute",
+ tolerance => $tol_z
+)->withPostFilter(
+ HintIfWrong(
+ "For a 95% confidence interval, alpha = 0.05, so alpha/2 = 0.025 and z_(alpha/2) = 1.960."
+ )
+);
+
+# ------------------------------------------------------------
+# Standard error
+# ------------------------------------------------------------
+$cmp_se = $se->cmp(
+ tolType => "absolute",
+ tolerance => $tol_se
+)->withPostFilter(
+ HintIfWrong("The standard error here is sigma/sqrt(n).")
+);
+
+# ------------------------------------------------------------
+# Margin of error
+# ------------------------------------------------------------
+$cmp_me = $me->cmp(
+ tolType => "absolute",
+ tolerance => $tol_me
+)->withPostFilter(
+ HintIfWrong("The margin of error is z_(alpha/2)(sigma/sqrt(n)).")
+);
+
+# ------------------------------------------------------------
+# Lower endpoint
+# ------------------------------------------------------------
+$cmp_lcl = $lcl->cmp(
+ tolType => "absolute",
+ tolerance => $tol_end
+)->withPostFilter(
+ HintIfWrong("The lower endpoint is xbar minus the margin of error.")
+);
+
+# ------------------------------------------------------------
+# Upper endpoint
+# ------------------------------------------------------------
+$cmp_ucl = $ucl->cmp(
+ tolType => "absolute",
+ tolerance => $tol_end
+)->withPostFilter(
+ HintIfWrong("The upper endpoint is xbar plus the margin of error.")
+);
+
+# ------------------------------------------------------------
+# Interpretation multiple choice
+# Correct answer: 2
+# ------------------------------------------------------------
+$cmp_interp = Real(2)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ return 0 unless defined $student;
+
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+
+ return ($v == 2) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong(
+ "A confidence interval for mu is interpreted as a plausible range for the true population mean."
+ )
+);
+
+# ------------------------------------------------------------
+# Rating checker
+# Any integer 1 to 5 is accepted
+# ------------------------------------------------------------
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ return 0 unless defined $student;
+
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+
+ return 1;
+ }
+);
+
+# ============================================================
+# Scaffold setup
+# ============================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "always",
+ is_open => "always"
+ );
+}
+else {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect"
+ );
+}
+
+# ============================================================
+# Step 1 — Problem Statement
+# ============================================================
+Section::Begin("Problem Statement");
+
+BEGIN_PGML
+A beverage company wants to estimate the true mean amount of juice in its bottles.
+
+A random sample of [``n=64``] bottles is selected. The sample mean is [``\bar x = 483``] mL.
+The population standard deviation is known to be [``\sigma = 12``] mL.
+
+Construct a [``95\%``] confidence interval for the true population mean [``\mu``].
+
+Because the sample is large, according to the CLT, the sampling distribution of [``\bar X``] is approximately normal.
+
+Round the cutoff, standard error, margin of error, and interval endpoints to 3 decimals.
+END_PGML
+
+Section::End();
+
+# ============================================================
+# Step 2 — Choose the correct formula
+# ============================================================
+Section::Begin("Section B — Choose the correct formula");
+
+BEGIN_PGML
+Choose the correct confidence-interval formula for this problem, considering that the sample is large
+and the population standard deviation [``\sigma``] is known.
+
+1) [``\bar x \pm t_{\alpha/2}\dfrac{s}{\sqrt{n}}``]
+
+2) [``\hat p \pm z_{\alpha/2}\sqrt{\dfrac{\hat p(1-\hat p)}{n}}``]
+
+3) [``\bar x \pm z_{\alpha/2}\dfrac{s}{\sqrt{n}}``]
+
+4) [``\bar x \pm z_{\alpha/2}\dfrac{\sigma}{\sqrt{n}}``]
+
+5) [``\bar x \pm t_{\alpha/2}\dfrac{\sigma}{\sqrt{n}}``]
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_formula);
+
+Section::End();
+
+# ============================================================
+# Step 3 — Find alpha and the cutoff
+# ============================================================
+Section::Begin("Section C — Find alpha and the cutoff");
+
+BEGIN_PGML
+For a [``95\%``] confidence interval:
+
+- [``1-\alpha = 0.95``]
+- each tail has area [``\alpha/2``]
+
+1) Enter the value of [``\alpha``]:
+
+[____]
+
+[@ image("cutoff.jpg", width=>520) @]*
+
+2) Use the normal table to find the positive cutoff [``z_{\alpha/2}``].
+
+Enter [``z_{\alpha/2}``]: [____]
+END_PGML
+
+ANS($cmp_alpha, $cmp_z);
+
+Section::End();
+
+# ============================================================
+# Step 4 — Compute the standard error and margin of error
+# ============================================================
+Section::Begin("Section D — Compute the standard error and margin of error");
+
+BEGIN_PGML
+Compute the standard error:
+
+[``\dfrac{\sigma}{\sqrt{n}}``]
+
+For this problem,
+
+[``\dfrac{12}{\sqrt{64}} =``] [____]
+
+Now compute the margin of error:
+
+[``E = z_{\alpha/2}\dfrac{\sigma}{\sqrt{n}}``]
+
+For this problem,
+
+[``E = (1.960)\left(\dfrac{12}{\sqrt{64}}\right) =``] [____]
+END_PGML
+
+ANS($cmp_se, $cmp_me);
+
+Section::End();
+
+# ============================================================
+# Step 5 — Construct the confidence interval
+# ============================================================
+Section::Begin("Section E — Construct the confidence interval");
+
+BEGIN_PGML
+Now construct the confidence interval:
+
+[``\bar x \pm E``]
+
+Using [``\bar x = 483``] and your margin of error, enter the two endpoints.
+
+Lower endpoint: [____]
+
+Upper endpoint: [____]
+END_PGML
+
+ANS($cmp_lcl, $cmp_ucl);
+
+Section::End();
+
+# ============================================================
+# Step 6 — Interpretation
+# ============================================================
+Section::Begin("Section F — Interpret the confidence interval");
+
+BEGIN_PGML
+The [``95\%``] confidence interval is
+
+[``(480.060,\ 485.940)``]
+
+Choose the best interpretation.
+
+1) [``95\%``] of all bottles contain between [``480.060``] mL and [``485.940``] mL.
+
+2) We are [``95\%``] confident that the true mean amount of juice in all bottles is between
+[``480.060``] mL and [``485.940``] mL.
+
+3) There is a [``95\%``] chance that the sample mean [``\bar x``] is between
+[``480.060``] and [``485.940``].
+
+4) [``95\%``] of all possible sample means are exactly equal to [``\mu``].
+
+5) The interval proves that [``\mu = 483``] exactly.
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_interp);
+
+Section::End();
+
+# ============================================================
+# Feedback — hidden in Library Browser
+# ============================================================
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+ Section::Begin("Feedback");
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+# ============================================================
+# Solution
+# ============================================================
+BEGIN_PGML_SOLUTION
+**1. Choose the correct formula**
+
+Because the sample is large and the population standard deviation [``\sigma``] is known,
+the correct formula is
+
+[``\bar x \pm z_{\alpha/2}\dfrac{\sigma}{\sqrt{n}}``]
+
+**2. Find alpha and the cutoff**
+
+For a [``95\%``] confidence interval,
+
+[``1-\alpha = 0.95``]
+
+so
+
+[``\alpha = 0.05``]
+
+Then
+
+[``\alpha/2 = 0.025``]
+
+From the normal table,
+
+[``z_{\alpha/2} = z_{0.025} = 1.960``]
+
+**3. Compute the standard error**
+
+[``\dfrac{\sigma}{\sqrt{n}} = \dfrac{12}{\sqrt{64}} = \dfrac{12}{8} = 1.500``]
+
+So the standard error is [``1.500``].
+
+**4. Compute the margin of error**
+
+[``E = z_{\alpha/2}\dfrac{\sigma}{\sqrt{n}}``]
+
+So
+
+[``E = (1.960)(1.500) = 2.940``]
+
+**5. Construct the confidence interval**
+
+Use
+
+[``\bar x \pm E``]
+
+So
+
+[``483 \pm 2.940``]
+
+Lower endpoint:
+
+[``483 - 2.940 = 480.060``]
+
+Upper endpoint:
+
+[``483 + 2.940 = 485.940``]
+
+Therefore, the [``95\%``] confidence interval for [``\mu``] is
+
+[``(480.060,\ 485.940)``]
+
+**6. Interpret the confidence interval**
+
+The correct interpretation is:
+
+We are [``95\%``] confident that the true mean amount of juice in all bottles is between
+[``480.060``] mL and [``485.940``] mL.
+
+This interval gives a plausible range for the population mean [``\mu``].
+It does **not** mean that [``95\%``] of individual bottles must fall in this interval,
+and it does **not** mean that [``\bar x``] has a [``95\%``] chance of being in that range.
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_LargeSample_GuidedProblem3.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_LargeSample_GuidedProblem3.pg
new file mode 100644
index 0000000000..dcd02ff8bb
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_LargeSample_GuidedProblem3.pg
@@ -0,0 +1,425 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Confidence Interval for the Mean: Large Sample, Sigma Unknown (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Confidence Intervals)
+## DBsection(Confidence Interval for the Mean)
+## Level(2)
+## KEYWORDS('confidence interval','population mean','large sample','sigma unknown','sample standard deviation','z critical value','standard error','margin of error')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser detection (LB stability)
+# ----------------------------------------------------------------
+$inLibraryBrowser = ($envir{isLibraryBrowser} || $envir{isLibrary} || 0);
+
+Context("Numeric");
+
+# =======================================================
+# Postfilter: add a hint ONLY when the answer is wrong
+# =======================================================
+sub HintIfWrong {
+ my $msg = shift;
+ return sub {
+ my $ans = shift;
+ if (defined($ans->{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+ return $ans;
+ };
+}
+
+# =======================================================
+# Data
+# =======================================================
+$xbar = 72;
+$s = 15;
+$n = 100;
+$conf = 0.98;
+
+$alpha = Real(0.02);
+$z_cutoff = Real(2.325);
+$se = Real(1.5);
+$me = Real(3.4875);
+$lcl = Real(68.5125);
+$ucl = Real(75.4875);
+
+# =======================================================
+# Tolerances
+# =======================================================
+$tol_alpha = 0.0005;
+$tol_z = 0.005;
+$tol_se = 0.005;
+$tol_me = 0.01;
+$tol_end = 0.02;
+
+# =======================================================
+# Comparators
+# =======================================================
+
+# Formula-selection MC: correct choice = 3
+$cmp_formula = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+ return ($v == 3) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong("Because the sample is large and sigma is unknown, we use xbar +/- z_(alpha/2)(s/sqrt(n)).")
+);
+
+$cmp_alpha = $alpha->cmp(
+ tolType => "absolute",
+ tolerance => $tol_alpha
+)->withPostFilter(
+ HintIfWrong("For a 98% confidence level, 1 - alpha = 0.98, so alpha = 0.02.")
+);
+
+$cmp_z = $z_cutoff->cmp(
+ tolType => "absolute",
+ tolerance => $tol_z
+)->withPostFilter(
+ HintIfWrong("For a 98% confidence interval, alpha = 0.02, so alpha/2 = 0.01 and the table cutoff is 2.325.")
+);
+
+$cmp_se = $se->cmp(
+ tolType => "absolute",
+ tolerance => $tol_se
+)->withPostFilter(
+ HintIfWrong("The standard error here is s/sqrt(n).")
+);
+
+$cmp_me = $me->cmp(
+ tolType => "absolute",
+ tolerance => $tol_me
+)->withPostFilter(
+ HintIfWrong("The margin of error is z_(alpha/2)(s/sqrt(n)).")
+);
+
+$cmp_lcl = $lcl->cmp(
+ tolType => "absolute",
+ tolerance => $tol_end
+)->withPostFilter(
+ HintIfWrong("The lower endpoint is xbar minus the margin of error.")
+);
+
+$cmp_ucl = $ucl->cmp(
+ tolType => "absolute",
+ tolerance => $tol_end
+)->withPostFilter(
+ HintIfWrong("The upper endpoint is xbar plus the margin of error.")
+);
+
+# Interpretation MC: correct choice = 4
+$cmp_interp = Real(4)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+ return ($v == 4) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong("A confidence interval for mu is interpreted as a plausible range for the true population mean.")
+);
+
+# Rating checker
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "always",
+ is_open => "always"
+ );
+} else {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect"
+ );
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+
+BEGIN_PGML
+A streaming platform wants to estimate the true mean number of minutes users spend watching content in a session.
+
+A random sample of [``n=100``] users is selected. The sample mean is [``\bar x = 72``] minutes. The population standard deviation is unknown, but the sample standard deviation is [``s = 15``] minutes.
+
+Construct a [``98\%``] confidence interval for the true population mean [``\mu``].
+
+Because the sample is large, according to the CLT, the sampling distribution of [``\bar X``] is approximately normal.
+
+Round the cutoff, standard error, margin of error, and interval endpoints to 3 decimals.
+END_PGML
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 2 — Choose the correct formula
+# -------------------------------------------------------
+Section::Begin("Section B — Choose the correct formula");
+
+BEGIN_PGML
+Choose the correct confidence-interval formula for this problem, considering that the sample is large and the population standard deviation [``\sigma``] is unknown.
+
+1) [``\bar x \pm t_{\alpha/2}\dfrac{s}{\sqrt{n}}``]
+
+2) [``\hat p \pm z_{\alpha/2}\sqrt{\dfrac{\hat p(1-\hat p)}{n}}``]
+
+3) [``\bar x \pm z_{\alpha/2}\dfrac{s}{\sqrt{n}}``]
+
+4) [``\bar x \pm z_{\alpha/2}\dfrac{\sigma}{\sqrt{n}}``]
+
+5) [``\bar x \pm t_{\alpha/2}\dfrac{\sigma}{\sqrt{n}}``]
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_formula);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 3 — Find alpha and the cutoff
+# -------------------------------------------------------
+Section::Begin("Section C — Find alpha and the cutoff");
+
+BEGIN_PGML
+For a [``98\%``] confidence interval:
+
+- [``1-\alpha = 0.98``]
+- each tail has area [``\alpha/2``]
+
+1) Enter the value of [``\alpha``]:
+
+[____]
+
+[@ image("cutoff.jpg", width=>520) @]*
+
+2) Use the normal table to find the positive cutoff [``z_{\alpha/2}``].
+
+Enter [``z_{\alpha/2}``]: [____]
+END_PGML
+
+ANS($cmp_alpha, $cmp_z);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 4 — Compute the standard error and margin of error
+# -------------------------------------------------------
+Section::Begin("Section D — Compute the standard error and margin of error");
+
+BEGIN_PGML
+Compute the standard error:
+
+[``\dfrac{s}{\sqrt{n}}``]
+
+For this problem,
+
+[``\dfrac{15}{\sqrt{100}} =``] [____]
+
+Now compute the margin of error:
+
+[``E = z_{\alpha/2}\dfrac{s}{\sqrt{n}}``]
+
+For this problem,
+
+[``E = (2.325)\left(\dfrac{15}{\sqrt{100}}\right) =``] [____]
+END_PGML
+
+ANS($cmp_se, $cmp_me);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 5 — Construct the confidence interval
+# -------------------------------------------------------
+Section::Begin("Section E — Construct the confidence interval");
+
+BEGIN_PGML
+Now construct the confidence interval:
+
+[``\bar x \pm E``]
+
+Using [``\bar x = 72``] and your margin of error, enter the two endpoints.
+
+Lower endpoint: [____]
+
+Upper endpoint: [____]
+END_PGML
+
+ANS($cmp_lcl, $cmp_ucl);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 6 — Interpretation
+# -------------------------------------------------------
+Section::Begin("Section F — Interpret the confidence interval");
+
+BEGIN_PGML
+The [``98\%``] confidence interval is
+
+[``(68.513,\ 75.488)``]
+
+Choose the best interpretation.
+
+1) [``98\%``] of all user sessions last exactly between [``68.513``] and [``75.488``] minutes.
+
+2) There is a [``98\%``] chance that the sample mean [``\bar x``] is between [``68.513``] and [``75.488``].
+
+3) The interval proves that the true population mean is exactly [``72``] minutes.
+
+4) We are [``98\%``] confident that the true mean session time for all users is between [``68.513``] and [``75.488``] minutes.
+
+5) [``98\%``] of all possible sample means are exactly equal to [``\mu``].
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_interp);
+
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating) — hidden in Library Browser
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+ Section::Begin("Feedback");
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+BEGIN_PGML_SOLUTION
+**1. Choose the correct formula**
+
+Because the sample is large and the population standard deviation [``\sigma``] is unknown, we use the sample standard deviation [``s``]. The correct formula is
+
+[``\bar x \pm z_{\alpha/2}\dfrac{s}{\sqrt{n}}``]
+
+**2. Find alpha and the cutoff**
+
+For a [``98\%``] confidence interval,
+
+[``1-\alpha = 0.98``]
+
+so
+
+[``\alpha = 0.02``]
+
+Then
+
+[``\alpha/2 = 0.01``]
+
+From the normal table,
+
+[``z_{\alpha/2} = z_{0.01} = 2.325``]
+
+**3. Compute the standard error**
+
+[``\dfrac{s}{\sqrt{n}} = \dfrac{15}{\sqrt{100}} = \dfrac{15}{10} = 1.500``]
+
+So the standard error is [``1.500``].
+
+**4. Compute the margin of error**
+
+[``E = z_{\alpha/2}\dfrac{s}{\sqrt{n}}``]
+
+So
+
+[``E = (2.325)(1.500) = 3.488``]
+
+**5. Construct the confidence interval**
+
+Use
+
+[``\bar x \pm E``]
+
+So
+
+[``72 \pm 3.488``]
+
+Lower endpoint:
+
+[``72 - 3.488 = 68.513``]
+
+Upper endpoint:
+
+[``72 + 3.488 = 75.488``]
+
+Therefore, the [``98\%``] confidence interval for [``\mu``] is
+
+[``(68.513,\ 75.488)``]
+
+**6. Interpret the confidence interval**
+
+The correct interpretation is:
+
+We are [``98\%``] confident that the true mean session time for all users is between [``68.513``] and [``75.488``] minutes.
+
+This interval gives a plausible range for the population mean [``\mu``]. It does **not** describe where [``98\%``] of individual session times fall, and it does **not** mean that the sample mean has a [``98\%``] chance of being in that interval.
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SampleProportion_GuidedProblem1.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SampleProportion_GuidedProblem1.pg
new file mode 100644
index 0000000000..83c1d9a3ae
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SampleProportion_GuidedProblem1.pg
@@ -0,0 +1,508 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Confidence Intervals for a Population Proportion (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Confidence Intervals)
+## DBsection(Confidence Interval for a Population Proportion)
+## Level(2)
+## KEYWORDS('confidence interval','population proportion','sample proportion','normal approximation','success-failure condition','z critical value','confidence level')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser detection (LB stability)
+# ----------------------------------------------------------------
+$inLibraryBrowser = ($envir{isLibraryBrowser} || $envir{isLibrary} || 0);
+
+Context("Numeric");
+
+# =======================================================
+# Postfilter: add a hint ONLY when the answer is wrong
+# =======================================================
+sub HintIfWrong {
+ my $msg = shift;
+ return sub {
+ my $ans = shift;
+ if (defined($ans->{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+ return $ans;
+ };
+}
+
+# =======================================================
+# Data
+# =======================================================
+$n_sample = 80;
+$x_success = 52;
+$p_hat_val = 0.65;
+$q_hat_val = 0.35;
+
+$np_hat_val = 52;
+$nq_hat_val = 28;
+
+$alpha_98 = Real(0.02);
+
+$z_010 = Real(1.645);
+$z_005 = Real(1.960);
+$z_002 = Real(2.325);
+$z_001 = Real(2.575);
+
+# Approximate 95% CI for the example
+$se_95 = 0.053326; # sqrt(0.65*0.35/80)
+$me_95 = 0.104519; # 1.96 * se
+$lcl_95 = 0.545;
+$ucl_95 = 0.755;
+
+# =======================================================
+# Tolerances
+# =======================================================
+$tol_alpha = 0.0005;
+$tol_phat = 0.0005;
+$tol_count = 0.0005;
+$tol_z = 0.01;
+
+# =======================================================
+# Comparators
+# =======================================================
+
+# Section B MC: correct choice = 2 (phat)
+$cmp_point_est = Real(2)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+ return ($v == 2) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong("The appropriate point estimate for p is the sample proportion phat.")
+);
+
+$cmp_alpha_98 = $alpha_98->cmp(
+ tolType => "absolute",
+ tolerance => $tol_alpha
+)->withPostFilter(
+ HintIfWrong("For a 98% confidence level, 1 - alpha = 0.98, so alpha = 0.02.")
+);
+
+$cmp_phat = Real($p_hat_val)->cmp(
+ tolType => "absolute",
+ tolerance => $tol_phat
+)->withPostFilter(
+ HintIfWrong("Use phat = x/n = number of successes divided by the sample size.")
+);
+
+$cmp_np_hat = Real($np_hat_val)->cmp(
+ tolType => "absolute",
+ tolerance => $tol_count
+)->withPostFilter(
+ HintIfWrong("Compute n(phat) using your value of phat.")
+);
+
+$cmp_nq_hat = Real($nq_hat_val)->cmp(
+ tolType => "absolute",
+ tolerance => $tol_count
+)->withPostFilter(
+ HintIfWrong("Compute n(1-phat). Since phat = 0.65, 1-phat = 0.35.")
+);
+
+$cmp_z_010 = $z_010->cmp(
+ tolType => "absolute",
+ tolerance => $tol_z
+)->withPostFilter(
+ HintIfWrong("For alpha = 0.10, alpha/2 = 0.05, so the cutoff is z_(0.05) = 1.645.")
+);
+
+$cmp_z_005 = $z_005->cmp(
+ tolType => "absolute",
+ tolerance => $tol_z
+)->withPostFilter(
+ HintIfWrong("For alpha = 0.05, alpha/2 = 0.025, so the cutoff is z_(0.025) = 1.960.")
+);
+
+$cmp_z_002 = $z_002->cmp(
+ tolType => "absolute",
+ tolerance => $tol_z
+)->withPostFilter(
+ HintIfWrong("For alpha = 0.02, alpha/2 = 0.01, so the cutoff is z_(0.01) = 2.326.")
+);
+
+$cmp_z_001 = $z_001->cmp(
+ tolType => "absolute",
+ tolerance => $tol_z
+)->withPostFilter(
+ HintIfWrong("For alpha = 0.01, alpha/2 = 0.005, so the cutoff is z_(0.005) = 2.576.")
+);
+
+# Section G MC: correct choice = 3
+$cmp_interp = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+ return ($v == 3) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong("A confidence interval for p is interpreted as a plausible range for the true population proportion.")
+);
+
+# Rating checker
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "always",
+ is_open => "always"
+ );
+} else {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect"
+ );
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+
+BEGIN_PGML
+In this Guided Problem, we introduce the idea of a confidence interval for the population proportion [``p``].
+
+Suppose a random sample of size [``n``] is taken from a population, and each individual answers a yes/no question. For example, do you prefer this new product to the old one?
+
+The goal is to estimate the true population proportion [``p``] of the individuals who prefer the new product, using the sample proportion [``\hat p``].
+
+In this GP, you will learn:
+
+- what a [``100(1-\alpha)\%``] confidence interval means,
+- what the appropriate point estimate for [``p``] is,
+- the formula for a confidence interval for [``p``],
+- the expected success-failure conditions needed for the normal approximation,
+- the common cutoff values [``z_{\alpha/2}``],
+- and how to interpret a confidence interval in context.
+
+For confidence intervals for [``p``], the cutoff comes from the **normal table**.
+
+Rounding: Round cutoff values to 3 decimals.
+END_PGML
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 2 — Section B
+# -------------------------------------------------------
+Section::Begin("Section B — Appropriate point estimate for p");
+
+BEGIN_PGML
+A confidence interval for [``p``] has the form
+
+[``\text{estimate} \pm \text{margin of error}``]
+
+What is the appropriate point estimate for the population proportion [``p``]?
+
+1) [``p``]
+2) [``\hat p``]
+3) [``\sigma``]
+4) [``s``]
+5) [``\alpha``]
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_point_est);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 3 — Section C
+# -------------------------------------------------------
+Section::Begin("Section C — Level of confidence");
+
+BEGIN_PGML
+When we build a confidence interval, we must consider the required level of confidence.
+
+Common values are usually [``90\%``] ([``\alpha = 0.10``]), [``95\%``] ([``\alpha = 0.05``]), and [``99\%``] ([``\alpha = 0.01``]).
+
+The confidence level describes how the method behaves over many random samples. For example, a [``95\%``] level of confidence means [``95\%``] of intervals built using this method, by repeatedly sampling the population, will capture the actual [``p``].
+
+If the confidence level is [``98\%``], enter the value of [``\alpha``]:
+
+[____]
+END_PGML
+
+ANS($cmp_alpha_98);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 4 — Section D
+# -------------------------------------------------------
+Section::Begin("Section D — Formula and sample proportion");
+
+BEGIN_PGML
+The confidence interval formula for a population proportion is
+
+[``\hat p \pm z_{\alpha/2}\sqrt{\dfrac{\hat p(1-\hat p)}{n}}``]
+
+Here:
+
+- [``\hat p``], called the sample proportion, is the center of the interval,
+- [``z_{\alpha/2}``] is the cutoff from the **normal table**,
+- and [``\sqrt{\dfrac{\hat p(1-\hat p)}{n}}``] is the standard error.
+
+A survey of [``80``] customers found that [``52``] prefer a new product.
+
+Enter the sample proportion [``\hat p``]:
+
+[____]
+END_PGML
+
+ANS($cmp_phat);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 5 — Section E
+# -------------------------------------------------------
+Section::Begin("Section E — Expected success-failure conditions");
+
+BEGIN_PGML
+For the normal approximation to be reasonable when building a confidence interval for [``p``], we check the expected success-failure conditions:
+
+[``n\hat p \ge 5 \qquad \text{and} \qquad n(1-\hat p)\ge 5``]
+
+Using the same sample with [``n=80``] and your value of [``\hat p``], compute:
+
+1) [``n\hat p``] = [____]
+
+2) [``n(1-\hat p)``] = [____]
+
+If both values are at least [``5``], then the normal approximation is reasonable.
+END_PGML
+
+ANS($cmp_np_hat, $cmp_nq_hat);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 6 — Section F
+# -------------------------------------------------------
+Section::Begin("Section F — Cutoff values from the normal table");
+
+BEGIN_PGML
+For a [``100(1-\alpha)\%``] confidence interval:
+
+- the middle area is [``1-\alpha``]
+- the total area in the two tails is [``\alpha``]
+- each tail has area [``\alpha/2``]
+- the positive cutoff is [``z_{\alpha/2}``]
+
+[@ image("cutoff.jpg", width=>520) @]*
+
+Now use the normal table to find the positive cutoff [``z_{\alpha/2}``] for each value of [``\alpha``].
+
+For [``\alpha = 0.10``], enter [``z_{\alpha/2}``]: [____]
+
+For [``\alpha = 0.05``], enter [``z_{\alpha/2}``]: [____]
+
+For [``\alpha = 0.02``], enter [``z_{\alpha/2}``]: [____]
+
+For [``\alpha = 0.01``], enter [``z_{\alpha/2}``]: [____]
+
+Note that smaller [``\alpha``] means higher confidence level, which is desirable. However, smaller [``\alpha``] also means a bigger cutoff value that will result in a bigger margin of error for the confidence interval. This is a trade-off. Higher confidence level comes at the expense of a wider, and thus less precise, confidence interval.
+END_PGML
+
+ANS($cmp_z_010, $cmp_z_005, $cmp_z_002, $cmp_z_001);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 7 — Section G
+# -------------------------------------------------------
+Section::Begin("Section G — Interpretation in context");
+
+BEGIN_PGML
+Using the sample of [``80``] customers with [``52``] successes, a [``95\%``] confidence interval for the true population proportion [``p``] is approximately
+
+[``(0.545,\ 0.755)``]
+
+Choose the best interpretation.
+
+1) [``95\%``] of the customers in this sample prefer the new product.
+2) There is a [``95\%``] chance that [``p``] is exactly [``0.65``].
+3) We are [``95\%``] confident that the true proportion of all customers who prefer the new product is between [``0.545``] and [``0.755``].
+4) [``95\%``] of all possible sample proportions must lie between [``0.545``] and [``0.755``].
+5) The interval proves that exactly [``65\%``] of all customers prefer the new product.
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_interp);
+
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating) — hidden in Library Browser
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+ Section::Begin("Feedback");
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+BEGIN_PGML_SOLUTION
+**1. Appropriate point estimate**
+
+A confidence interval for [``p``] is centered at the sample proportion.
+
+So the appropriate point estimate for the population proportion [``p``] is
+
+[``\hat p``]
+
+**2. Confidence level and alpha**
+
+If the confidence level is [``98\%``], then
+
+[``1-\alpha = 0.98``]
+
+so
+
+[``\alpha = 0.02``]
+
+The confidence level describes the long-run success rate of the method. For example, a [``95\%``] confidence level means that if we repeatedly sample the population and build intervals the same way each time, about [``95\%``] of those intervals will capture the true [``p``].
+
+**3. Formula for a confidence interval for p**
+
+The formula is
+
+[``\hat p \pm z_{\alpha/2}\sqrt{\dfrac{\hat p(1-\hat p)}{n}}``]
+
+Here:
+
+- [``\hat p``] is the center,
+- [``z_{\alpha/2}``] is the cutoff from the normal table,
+- and [``\sqrt{\dfrac{\hat p(1-\hat p)}{n}}``] is the standard error.
+
+**4. Compute the sample proportion**
+
+In the sample, [``52``] out of [``80``] customers are successes.
+
+So
+
+[``\hat p = \dfrac{52}{80} = 0.65``]
+
+**5. Expected success-failure conditions**
+
+We check:
+
+[``n\hat p \ge 5 \qquad \text{and} \qquad n(1-\hat p)\ge 5``]
+
+Since [``\hat p=0.65``], we have
+
+[``n\hat p = 80(0.65)=52``]
+
+and
+
+[``n(1-\hat p)=80(0.35)=28``]
+
+Both values are at least [``5``], so the normal approximation is reasonable.
+
+**6. Cutoff values**
+
+For a [``100(1-\alpha)\%``] confidence interval, each tail has area [``\alpha/2``], and the positive cutoff is [``z_{\alpha/2}``].
+
+The common cutoff values are:
+
+- for [``\alpha = 0.10``]: [``z_{0.05} = 1.645``]
+- for [``\alpha = 0.05``]: [``z_{0.025} = 1.960``]
+- for [``\alpha = 0.02``]: [``z_{0.01} = 2.325``]
+- for [``\alpha = 0.01``]: [``z_{0.005} = 2.575``]
+
+**7. Approximate 95% confidence interval**
+
+Using [``\hat p=0.65``], [``n=80``], and [``z_{0.025}=1.96``]:
+
+First compute the standard error:
+
+[``\sqrt{\dfrac{(0.65)(0.35)}{80}} \approx 0.0533``]
+
+Then the margin of error is
+
+[``1.96(0.0533)\approx 0.1045``]
+
+So the confidence interval is
+
+[``0.65 \pm 0.1045``]
+
+which gives
+
+[``(0.545,\ 0.755)``]
+
+**8. Interpretation in context**
+
+The correct interpretation is:
+
+We are [``95\%``] confident that the true proportion of all customers who prefer the new product is between [``0.545``] and [``0.755``].
+
+That means this interval gives a plausible range for the population proportion [``p``]. It does **not** mean that [``95\%``] of the sample had to be successes, and it does **not** mean that [``p``] has a [``95\%``] chance of being a single exact value.
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SampleProportion_GuidedProblem2.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SampleProportion_GuidedProblem2.pg
new file mode 100644
index 0000000000..3a70bf1d73
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SampleProportion_GuidedProblem2.pg
@@ -0,0 +1,585 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Confidence Interval for a Population Proportion:
+## Raw Data, Normal Approximation Check (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Confidence Intervals)
+## DBsection(Confidence Interval for a Population Proportion)
+## Level(2)
+## KEYWORDS(
+## 'confidence interval',
+## 'population proportion',
+## 'sample proportion',
+## 'normal approximation',
+## 'z critical value',
+## 'margin of error'
+## )
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ============================================================
+# Settings
+# ============================================================
+
+$ENABLE_GP_RATING = 1;
+
+$inLibraryBrowser = 0;
+if ((defined($envir{isLibraryBrowser}) && $envir{isLibraryBrowser})
+ || (defined($envir{isLibrary}) && $envir{isLibrary})) {
+ $inLibraryBrowser = 1;
+}
+
+Context("Numeric");
+
+# ============================================================
+# Helper: show a hint only when the student's answer is wrong
+# ============================================================
+sub HintIfWrong {
+ my $msg = shift;
+
+ return sub {
+ my $ans = shift;
+
+ if (defined($ans->{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+
+ return $ans;
+ };
+}
+
+# ============================================================
+# Data
+# Context: library self-checkout use
+# ============================================================
+
+$n = 120;
+$x = 78;
+$not_x = 42;
+$conf = 0.97;
+
+$phat = Real(0.65);
+$alpha = Real(0.03);
+$z_cut = Real(2.170);
+$np = Real(78);
+$nq = Real(42);
+$se = Real(0.04354116896);
+$me = Real(0.09448433665);
+$lcl = Real(0.55551566335);
+$ucl = Real(0.74448433665);
+
+# ============================================================
+# Tolerances
+# ============================================================
+
+$tol_phat = 0.005;
+$tol_cond = 0.01;
+$tol_alpha = 0.0005;
+$tol_z = 0.005;
+$tol_se = 0.005;
+$tol_me = 0.01;
+$tol_end = 0.01;
+
+# ============================================================
+# Comparators
+# ============================================================
+
+# ------------------------------------------------------------
+# Formula-selection multiple choice
+# Correct answer: 2
+# ------------------------------------------------------------
+$cmp_formula = Real(2)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ return 0 unless defined $student;
+
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+
+ return ($v == 2) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong(
+ "For a confidence interval for a population proportion, use p-hat +/- z_(alpha/2) sqrt((p-hat(1-p-hat))/n)."
+ )
+);
+
+# ------------------------------------------------------------
+# Sample proportion
+# ------------------------------------------------------------
+$cmp_phat = $phat->cmp(
+ tolType => "absolute",
+ tolerance => $tol_phat
+)->withPostFilter(
+ HintIfWrong("Compute p-hat using x/n, where x is the number of successes and n is the sample size.")
+);
+
+# ------------------------------------------------------------
+# Normal approximation conditions
+# ------------------------------------------------------------
+$cmp_np = $np->cmp(
+ tolType => "absolute",
+ tolerance => $tol_cond
+)->withPostFilter(
+ HintIfWrong("Compute n(p-hat) using the sample size and your value of p-hat.")
+);
+
+$cmp_nq = $nq->cmp(
+ tolType => "absolute",
+ tolerance => $tol_cond
+)->withPostFilter(
+ HintIfWrong("Compute n(1-p-hat) using the sample size and your value of p-hat.")
+);
+
+# ------------------------------------------------------------
+# Alpha
+# ------------------------------------------------------------
+$cmp_alpha = $alpha->cmp(
+ tolType => "absolute",
+ tolerance => $tol_alpha
+)->withPostFilter(
+ HintIfWrong("For a 97% confidence level, 1 - alpha = 0.97, so alpha = 0.03.")
+);
+
+# ------------------------------------------------------------
+# z cutoff
+# ------------------------------------------------------------
+$cmp_z = $z_cut->cmp(
+ tolType => "absolute",
+ tolerance => $tol_z
+)->withPostFilter(
+ HintIfWrong(
+ "For a 97% confidence interval, alpha = 0.03, so alpha/2 = 0.015. Use the normal table to find z_(alpha/2)."
+ )
+);
+
+# ------------------------------------------------------------
+# Standard error
+# ------------------------------------------------------------
+$cmp_se = $se->cmp(
+ tolType => "absolute",
+ tolerance => $tol_se
+)->withPostFilter(
+ HintIfWrong("For a proportion, the standard error is sqrt((p-hat(1-p-hat))/n).")
+);
+
+# ------------------------------------------------------------
+# Margin of error
+# ------------------------------------------------------------
+$cmp_me = $me->cmp(
+ tolType => "absolute",
+ tolerance => $tol_me
+)->withPostFilter(
+ HintIfWrong("The margin of error is z_(alpha/2) times the standard error.")
+);
+
+# ------------------------------------------------------------
+# Lower endpoint
+# ------------------------------------------------------------
+$cmp_lcl = $lcl->cmp(
+ tolType => "absolute",
+ tolerance => $tol_end
+)->withPostFilter(
+ HintIfWrong("The lower endpoint is p-hat minus the margin of error.")
+);
+
+# ------------------------------------------------------------
+# Upper endpoint
+# ------------------------------------------------------------
+$cmp_ucl = $ucl->cmp(
+ tolType => "absolute",
+ tolerance => $tol_end
+)->withPostFilter(
+ HintIfWrong("The upper endpoint is p-hat plus the margin of error.")
+);
+
+# ------------------------------------------------------------
+# Interpretation multiple choice
+# Correct answer: 4
+# ------------------------------------------------------------
+$cmp_interp = Real(4)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ return 0 unless defined $student;
+
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+
+ return ($v == 4) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong(
+ "A confidence interval for p is interpreted as a plausible range for the true population proportion."
+ )
+);
+
+# ------------------------------------------------------------
+# Rating checker
+# Any integer 1 to 5 is accepted
+# ------------------------------------------------------------
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ return 0 unless defined $student;
+
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+
+ return 1;
+ }
+);
+
+# ============================================================
+# Scaffold setup
+# ============================================================
+
+if ($inLibraryBrowser) {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "always",
+ is_open => "always"
+ );
+}
+else {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect"
+ );
+}
+
+# ============================================================
+# Step 1 — Problem Statement
+# ============================================================
+Section::Begin("Problem Statement");
+
+BEGIN_PGML
+A public library wants to estimate the true proportion of its members who regularly use the self-checkout kiosk.
+
+A random sample of [``120``] members is selected. The results are:
+
+- [``78``] members said they regularly use the self-checkout kiosk.
+- [``42``] members said they do not.
+
+Construct a [``97\%``] confidence interval for the true population proportion [``p``].
+
+Round [``\hat p``], the cutoff, the standard error, the margin of error, and the interval endpoints to 3 decimals.
+END_PGML
+
+Section::End();
+
+# ============================================================
+# Step 2 — Choose the correct formula
+# ============================================================
+Section::Begin("Section B — Choose the correct formula");
+
+BEGIN_PGML
+Choose the correct confidence-interval formula for this problem.
+
+1) [``\bar x \pm z_{\alpha/2}\dfrac{\sigma}{\sqrt{n}}``]
+
+2) [``\hat p \pm z_{\alpha/2}\sqrt{\dfrac{\hat p(1-\hat p)}{n}}``]
+
+3) [``\hat p \pm t_{\alpha/2}\sqrt{\dfrac{\hat p(1-\hat p)}{n}}``]
+
+4) [``\bar x \pm t_{\alpha/2}\dfrac{s}{\sqrt{n}}``]
+
+5) [``\hat p \pm z_{\alpha/2}\dfrac{\hat p(1-\hat p)}{n}``]
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_formula);
+
+Section::End();
+
+# ============================================================
+# Step 3 — Compute p-hat from the sample data
+# ============================================================
+Section::Begin("Section C — Compute the sample proportion");
+
+BEGIN_PGML
+For this problem, a "success" means a sampled member regularly uses the self-checkout kiosk.
+
+Compute the sample proportion:
+
+[``\hat p = \dfrac{x}{n}``]
+
+For this sample,
+
+[``\hat p = \dfrac{78}{120} =``] [____]
+END_PGML
+
+ANS($cmp_phat);
+
+Section::End();
+
+# ============================================================
+# Step 4 — Check the normal approximation conditions
+# ============================================================
+Section::Begin("Section D — Check the normal approximation conditions");
+
+BEGIN_PGML
+To use the normal approximation for a confidence interval for [``p``], we check that
+
+[``n\hat p \ge 10``] and [``n(1-\hat p)\ge 10``]
+
+Using your value of [``\hat p``], compute:
+
+[``n\hat p =``] [____]
+
+[``n(1-\hat p) =``] [____]
+
+Since both values are at least [``5``], the normal approximation is appropriate for this problem.
+END_PGML
+
+ANS($cmp_np, $cmp_nq);
+
+Section::End();
+
+# ============================================================
+# Step 5 — Find alpha and the cutoff
+# ============================================================
+Section::Begin("Section E — Find alpha and the cutoff");
+
+BEGIN_PGML
+For a [``97\%``] confidence interval:
+
+- [``1-\alpha = 0.97``]
+- each tail has area [``\alpha/2``]
+
+1) Enter the value of [``\alpha``]:
+
+[____]
+
+[@ image("cutoff.jpg", width=>520) @]*
+
+2) Use the normal table to find the positive cutoff [``z_{\alpha/2}``].
+
+Enter [``z_{\alpha/2}``]: [____]
+END_PGML
+
+ANS($cmp_alpha, $cmp_z);
+
+Section::End();
+
+# ============================================================
+# Step 6 — Compute the standard error and margin of error
+# ============================================================
+Section::Begin("Section F — Compute the standard error and margin of error");
+
+BEGIN_PGML
+Compute the standard error:
+
+[``\sqrt{\dfrac{\hat p(1-\hat p)}{n}}``]
+
+For this problem,
+
+[``\sqrt{\dfrac{(0.650)(0.350)}{120}} =``] [____]
+
+Now compute the margin of error:
+
+[``E = z_{\alpha/2}\sqrt{\dfrac{\hat p(1-\hat p)}{n}}``]
+
+For this problem,
+
+[``E = (2.170)\sqrt{\dfrac{(0.650)(0.350)}{120}} =``] [____]
+END_PGML
+
+ANS($cmp_se, $cmp_me);
+
+Section::End();
+
+# ============================================================
+# Step 7 — Construct the confidence interval
+# ============================================================
+Section::Begin("Section G — Construct the confidence interval");
+
+BEGIN_PGML
+Now construct the confidence interval:
+
+[``\hat p \pm E``]
+
+Using your values of [``\hat p``] and [``E``], enter the two endpoints.
+
+Lower endpoint: [____]
+
+Upper endpoint: [____]
+END_PGML
+
+ANS($cmp_lcl, $cmp_ucl);
+
+Section::End();
+
+# ============================================================
+# Step 8 — Interpretation
+# ============================================================
+Section::Begin("Section H — Interpret the confidence interval");
+
+BEGIN_PGML
+Choose the best interpretation of the confidence interval you constructed for [``p``].
+
+1) [``97\%``] of all individual library members must lie inside the interval.
+
+2) There is a [``97\%``] chance that the sample proportion [``\hat p``] lies inside the interval.
+
+3) The interval proves that the true population proportion is exactly equal to [``\hat p``].
+
+4) We are [``97\%``] confident that the true proportion of all library members who regularly use the self-checkout kiosk lies between the two endpoints of the interval.
+
+5) [``97\%``] of all possible samples will produce exactly the same value of [``\hat p``].
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_interp);
+
+Section::End();
+
+# ============================================================
+# Feedback — hidden in Library Browser
+# ============================================================
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+ Section::Begin("Feedback");
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+# ============================================================
+# Solution
+# ============================================================
+BEGIN_PGML_SOLUTION
+**1. Choose the correct formula**
+
+Because this is a confidence interval for a population proportion, the correct formula is
+
+[``\hat p \pm z_{\alpha/2}\sqrt{\dfrac{\hat p(1-\hat p)}{n}}``]
+
+**2. Compute the sample proportion**
+
+A success means the sampled member regularly uses the self-checkout kiosk.
+
+So
+
+[``\hat p = \dfrac{x}{n} = \dfrac{78}{120} = 0.650``]
+
+**3. Check the normal approximation conditions**
+
+We compute
+
+[``n\hat p = (120)(0.650) = 78``]
+
+and
+
+[``n(1-\hat p) = (120)(0.350) = 42``]
+
+Since both values are at least [``10``], the normal approximation is appropriate.
+
+**4. Find alpha and the cutoff**
+
+For a [``97\%``] confidence interval,
+
+[``1-\alpha = 0.97``]
+
+so
+
+[``\alpha = 0.03``]
+
+Then
+
+[``\alpha/2 = 0.015``]
+
+From the normal table,
+
+[``z_{\alpha/2} = z_{0.015} = 2.170``]
+
+**5. Compute the standard error**
+
+[``\sqrt{\dfrac{\hat p(1-\hat p)}{n}} = \sqrt{\dfrac{(0.650)(0.350)}{120}}``]
+
+So
+
+[``\sqrt{\dfrac{0.2275}{120}} = \sqrt{0.0018958333} \approx 0.044``]
+
+More precisely, the standard error is about [``0.043541``].
+
+**6. Compute the margin of error**
+
+[``E = z_{\alpha/2}\sqrt{\dfrac{\hat p(1-\hat p)}{n}}``]
+
+So
+
+[``E = (2.170)(0.043541) \approx 0.094``]
+
+More precisely, [``E \approx 0.094484``].
+
+**7. Construct the confidence interval**
+
+Use
+
+[``\hat p \pm E``]
+
+So
+
+[``0.650 \pm 0.094``]
+
+Lower endpoint:
+
+[``0.650 - 0.094484 \approx 0.556``]
+
+Upper endpoint:
+
+[``0.650 + 0.094484 \approx 0.744``]
+
+Therefore, the [``97\%``] confidence interval for [``p``] is
+
+[``(0.556,\ 0.744)``]
+
+**8. Interpret the confidence interval**
+
+The correct interpretation is:
+
+We are [``97\%``] confident that the true proportion of all library members who regularly use the self-checkout kiosk lies between [``0.556``] and [``0.744``].
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SampleSize_GuidedProblem1.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SampleSize_GuidedProblem1.pg
new file mode 100644
index 0000000000..899e3fb703
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SampleSize_GuidedProblem1.pg
@@ -0,0 +1,463 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Sample Size for Estimating a Mean:
+## Estimate for Sigma Given (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Confidence Intervals)
+## DBsection(Sample Size for Estimating a Mean)
+## Level(2)
+## KEYWORDS(
+## 'sample size',
+## 'margin of error',
+## 'confidence interval',
+## 'population mean',
+## 'estimate for sigma',
+## 'z critical value'
+## )
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ============================================================
+# Settings
+# ============================================================
+
+$ENABLE_GP_RATING = 1;
+
+$inLibraryBrowser = 0;
+if ((defined($envir{isLibraryBrowser}) && $envir{isLibraryBrowser})
+ || (defined($envir{isLibrary}) && $envir{isLibrary})) {
+ $inLibraryBrowser = 1;
+}
+
+Context("Numeric");
+
+# ============================================================
+# Helper: show a hint only when the student's answer is wrong
+# ============================================================
+sub HintIfWrong {
+ my $msg = shift;
+
+ return sub {
+ my $ans = shift;
+
+ if (defined($ans->{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+
+ return $ans;
+ };
+}
+
+# ============================================================
+# Data
+# Context: coffee shop waiting time during lunch rush
+# ============================================================
+
+$conf = 0.95;
+$sigma_est = Real(4.8);
+$E = Real(1.5);
+$alpha = Real(0.05);
+$z_cut = Real(1.96);
+$n_raw = Real(39.337984);
+$n_final = 40;
+
+# ============================================================
+# Tolerances
+# ============================================================
+
+$tol_basic = 0.0005;
+$tol_z = 0.005;
+$tol_raw = 0.02;
+
+# ============================================================
+# Comparators
+# ============================================================
+
+# ------------------------------------------------------------
+# Formula-selection multiple choice
+# Correct answer: 1
+# ------------------------------------------------------------
+$cmp_formula = Real(1)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ return 0 unless defined $student;
+
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+
+ return ($v == 1) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong(
+ "For planning sample size for a mean using an estimate of sigma, use n = (z_(alpha/2) sigma / E)^2."
+ )
+);
+
+# ------------------------------------------------------------
+# Identify ingredients
+# ------------------------------------------------------------
+$cmp_sigma = $sigma_est->cmp(
+ tolType => "absolute",
+ tolerance => $tol_basic
+)->withPostFilter(
+ HintIfWrong("Use the previous estimate of the population standard deviation given in the problem.")
+);
+
+$cmp_E = $E->cmp(
+ tolType => "absolute",
+ tolerance => $tol_basic
+)->withPostFilter(
+ HintIfWrong("Use the desired margin of error from the problem statement.")
+);
+
+$cmp_alpha = $alpha->cmp(
+ tolType => "absolute",
+ tolerance => $tol_basic
+)->withPostFilter(
+ HintIfWrong("For a 95% confidence level, 1 - alpha = 0.95, so alpha = 0.05.")
+);
+
+# ------------------------------------------------------------
+# z cutoff
+# ------------------------------------------------------------
+$cmp_z = $z_cut->cmp(
+ tolType => "absolute",
+ tolerance => $tol_z
+)->withPostFilter(
+ HintIfWrong(
+ "For a 95% confidence level, alpha = 0.05, so alpha/2 = 0.025 and z_(alpha/2) = 1.960."
+ )
+);
+
+# ------------------------------------------------------------
+# Raw sample size
+# ------------------------------------------------------------
+$cmp_n_raw = $n_raw->cmp(
+ tolType => "absolute",
+ tolerance => $tol_raw
+)->withPostFilter(
+ HintIfWrong("Substitute into n = (z_(alpha/2) sigma / E)^2 and compute before rounding.")
+);
+
+# ------------------------------------------------------------
+# Final sample size
+# ------------------------------------------------------------
+$cmp_n_final = Real($n_final)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ return 0 unless defined $student;
+
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+
+ return ($v == $n_final) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong("Always round the required sample size up to the next whole number.")
+);
+
+# ------------------------------------------------------------
+# Interpretation multiple choice
+# Correct answer: 2
+# ------------------------------------------------------------
+$cmp_interp = Real(2)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ return 0 unless defined $student;
+
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+
+ return ($v == 2) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong(
+ "The final answer is the minimum whole-number sample size needed so the margin of error is at most the target value."
+ )
+);
+
+# ------------------------------------------------------------
+# Rating checker
+# Any integer 1 to 5 is accepted
+# ------------------------------------------------------------
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ return 0 unless defined $student;
+
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+
+ return 1;
+ }
+);
+
+# ============================================================
+# Scaffold setup
+# ============================================================
+
+if ($inLibraryBrowser) {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "always",
+ is_open => "always"
+ );
+}
+else {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect"
+ );
+}
+
+# ============================================================
+# Step 1 — Problem Statement
+# ============================================================
+Section::Begin("Problem Statement");
+
+BEGIN_PGML
+A coffee shop wants to estimate the true mean waiting time for customers during the lunch rush.
+
+A previous study suggests that the population standard deviation is about [``4.8``] minutes.
+
+The manager wants to estimate the true mean waiting time with a margin of error of at most [``1.5``] minutes at the [``95\%``] confidence level.
+
+Find the minimum sample size [``n``] required.
+
+Round the raw calculator value of [``n``] to 3 decimals, then round the final sample size up to the next whole number.
+END_PGML
+
+Section::End();
+
+# ============================================================
+# Step 2 — Choose the correct formula
+# ============================================================
+Section::Begin("Section B — Choose the correct formula");
+
+BEGIN_PGML
+Choose the correct sample-size formula for this problem.
+
+1) [``n=\left(\dfrac{z_{\alpha/2}\sigma}{E}\right)^2``]
+
+2) [``n=\left(\dfrac{t_{\alpha/2}s}{E}\right)^2``]
+
+3) [``n=\dfrac{z_{\alpha/2}\sigma}{E}``]
+
+4) [``n=\dfrac{z_{\alpha/2}^2\hat p(1-\hat p)}{E^2}``]
+
+5) [``n=\left(\dfrac{z_{\alpha/2}E}{\sigma}\right)^2``]
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_formula);
+
+Section::End();
+
+# ============================================================
+# Step 3 — Identify the ingredients
+# ============================================================
+Section::Begin("Section C — Identify the ingredients");
+
+BEGIN_PGML
+For this problem, identify the values you will substitute into the formula.
+
+Estimated [``\sigma``]: [____]
+
+Desired margin of error [``E``]: [____]
+
+Value of [``\alpha``]: [____]
+END_PGML
+
+ANS($cmp_sigma, $cmp_E, $cmp_alpha);
+
+Section::End();
+
+# ============================================================
+# Step 4 — Find the cutoff
+# ============================================================
+Section::Begin("Section D — Find the cutoff");
+
+BEGIN_PGML
+For a [``95\%``] confidence level, use the normal table to find [``z_{\alpha/2}``].
+
+[@ image("cutoff.jpg", width=>520) @]*
+
+Enter [``z_{\alpha/2}``]: [____]
+END_PGML
+
+ANS($cmp_z);
+
+Section::End();
+
+# ============================================================
+# Step 5 — Compute the raw sample size
+# ============================================================
+Section::Begin("Section E — Compute the raw sample size");
+
+BEGIN_PGML
+Substitute into the sample-size formula:
+
+[``n=\left(\dfrac{z_{\alpha/2}\sigma}{E}\right)^2``]
+
+For this problem,
+
+[``n=\left(\dfrac{(1.960)(4.8)}{1.5}\right)^2 =``] [____]
+END_PGML
+
+ANS($cmp_n_raw);
+
+Section::End();
+
+# ============================================================
+# Step 6 — Round up to get the required sample size
+# ============================================================
+Section::Begin("Section F — Round up");
+
+BEGIN_PGML
+The raw calculator value of [``n``] is not a whole number.
+
+To guarantee that the margin of error is at most [``1.5``] minutes, we must round up.
+
+Enter the minimum whole-number sample size required: [____]
+END_PGML
+
+ANS($cmp_n_final);
+
+Section::End();
+
+# ============================================================
+# Step 7 — Interpretation
+# ============================================================
+Section::Begin("Section G — Interpret the answer");
+
+BEGIN_PGML
+Choose the best interpretation of your answer.
+
+1) The coffee shop should sample exactly [``39.338``] customers.
+
+2) The coffee shop must sample at least [``40``] customers so that a [``95\%``] confidence interval for the true mean waiting time has a margin of error of at most [``1.5``] minutes, using the estimate [``\sigma \approx 4.8``].
+
+3) The sample size [``40``] guarantees that the true mean waiting time will be found exactly.
+
+4) The answer means that [``95\%``] of all customers will wait less than [``1.5``] minutes.
+
+5) The answer means that the population mean waiting time is [``40``] minutes.
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_interp);
+
+Section::End();
+
+# ============================================================
+# Feedback — hidden in Library Browser
+# ============================================================
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+ Section::Begin("Feedback");
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+# ============================================================
+# Solution
+# ============================================================
+BEGIN_PGML_SOLUTION
+**1. Choose the correct formula**
+
+For planning a sample size for estimating a population mean, using an estimate of [``\sigma``], the formula is
+
+[``n=\left(\dfrac{z_{\alpha/2}\sigma}{E}\right)^2``]
+
+**2. Identify the ingredients**
+
+From the problem:
+
+- estimated [``\sigma = 4.8``]
+- desired margin of error [``E = 1.5``]
+- confidence level [``95\%``], so [``\alpha = 0.05``]
+
+**3. Find the cutoff**
+
+Since [``\alpha = 0.05``], we have
+
+[``\alpha/2 = 0.025``]
+
+From the normal table,
+
+[``z_{\alpha/2} = 1.960``]
+
+**4. Compute the raw sample size**
+
+Substitute into the formula:
+
+[``n=\left(\dfrac{z_{\alpha/2}\sigma}{E}\right)^2``]
+
+So
+
+[``n=\left(\dfrac{(1.960)(4.8)}{1.5}\right)^2``]
+
+[``n=\left(\dfrac{9.408}{1.5}\right)^2``]
+
+[``n=(6.272)^2``]
+
+[``n=39.338``]
+
+**5. Round up**
+
+Since sample size must be a whole number and must guarantee the desired margin of error, we round up:
+
+[``n=40``]
+
+**6. Interpretation**
+
+The correct interpretation is:
+
+The coffee shop must sample at least [``40``] customers so that a [``95\%``] confidence interval for the true mean waiting time has a margin of error of at most [``1.5``] minutes, using the estimate [``\sigma \approx 4.8``].
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SampleSize_GuidedProblem2.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SampleSize_GuidedProblem2.pg
new file mode 100644
index 0000000000..0d1711e3a8
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SampleSize_GuidedProblem2.pg
@@ -0,0 +1,465 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Sample Size for Estimating a Proportion:
+## Estimate for p-hat Given (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Confidence Intervals)
+## DBsection(Sample Size for Estimating a Proportion)
+## Level(2)
+## KEYWORDS(
+## 'sample size',
+## 'margin of error',
+## 'confidence interval',
+## 'population proportion',
+## 'sample proportion',
+## 'z critical value'
+## )
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ============================================================
+# Settings
+# ============================================================
+
+$ENABLE_GP_RATING = 1;
+
+$inLibraryBrowser = 0;
+if ((defined($envir{isLibraryBrowser}) && $envir{isLibraryBrowser})
+ || (defined($envir{isLibrary}) && $envir{isLibrary})) {
+ $inLibraryBrowser = 1;
+}
+
+Context("Numeric");
+
+# ============================================================
+# Helper: show a hint only when the student's answer is wrong
+# ============================================================
+sub HintIfWrong {
+ my $msg = shift;
+
+ return sub {
+ my $ans = shift;
+
+ if (defined($ans->{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+
+ return $ans;
+ };
+}
+
+# ============================================================
+# Data
+# Context: transit app usage
+# ============================================================
+
+$conf = 0.98;
+$phat_est = Real(0.38);
+$qhat_est = Real(0.62);
+$E = Real(0.05);
+$alpha = Real(0.02);
+$z_cut = Real(2.325);
+$n_raw = Real(509.26612);
+$n_final = 510;
+
+# ============================================================
+# Tolerances
+# ============================================================
+
+$tol_basic = 0.0005;
+$tol_z = 0.005;
+$tol_raw = 0.05;
+
+# ============================================================
+# Comparators
+# ============================================================
+
+# ------------------------------------------------------------
+# Formula-selection multiple choice
+# Correct answer: 2
+# ------------------------------------------------------------
+$cmp_formula = Real(2)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ return 0 unless defined $student;
+
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+
+ return ($v == 2) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong(
+ "For planning a sample size for a proportion using an estimate for p-hat, use n = z_(alpha/2)^2 p-hat(1-p-hat) / E^2."
+ )
+);
+
+# ------------------------------------------------------------
+# Identify ingredients
+# ------------------------------------------------------------
+$cmp_phat = $phat_est->cmp(
+ tolType => "absolute",
+ tolerance => $tol_basic
+)->withPostFilter(
+ HintIfWrong("Use the estimated sample proportion from the previous survey.")
+);
+
+$cmp_E = $E->cmp(
+ tolType => "absolute",
+ tolerance => $tol_basic
+)->withPostFilter(
+ HintIfWrong("Use the desired margin of error from the problem statement.")
+);
+
+$cmp_alpha = $alpha->cmp(
+ tolType => "absolute",
+ tolerance => $tol_basic
+)->withPostFilter(
+ HintIfWrong("For a 98% confidence level, 1 - alpha = 0.98, so alpha = 0.02.")
+);
+
+# ------------------------------------------------------------
+# z cutoff
+# ------------------------------------------------------------
+$cmp_z = $z_cut->cmp(
+ tolType => "absolute",
+ tolerance => $tol_z
+)->withPostFilter(
+ HintIfWrong(
+ "For a 98% confidence level, alpha = 0.02, so alpha/2 = 0.01 and z_(alpha/2) = 2.325."
+ )
+);
+
+# ------------------------------------------------------------
+# Raw sample size
+# ------------------------------------------------------------
+$cmp_n_raw = $n_raw->cmp(
+ tolType => "absolute",
+ tolerance => $tol_raw
+)->withPostFilter(
+ HintIfWrong("Substitute into n = z_(alpha/2)^2 p-hat(1-p-hat) / E^2 and compute before rounding.")
+);
+
+# ------------------------------------------------------------
+# Final sample size
+# ------------------------------------------------------------
+$cmp_n_final = Real($n_final)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ return 0 unless defined $student;
+
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+
+ return ($v == $n_final) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong("Always round the required sample size up to the next whole number.")
+);
+
+# ------------------------------------------------------------
+# Interpretation multiple choice
+# Correct answer: 3
+# ------------------------------------------------------------
+$cmp_interp = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ return 0 unless defined $student;
+
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+
+ return ($v == 3) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong(
+ "The final answer is the minimum whole-number sample size needed so the margin of error is at most the target value."
+ )
+);
+
+# ------------------------------------------------------------
+# Rating checker
+# Any integer 1 to 5 is accepted
+# ------------------------------------------------------------
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ return 0 unless defined $student;
+
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+
+ return 1;
+ }
+);
+
+# ============================================================
+# Scaffold setup
+# ============================================================
+
+if ($inLibraryBrowser) {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "always",
+ is_open => "always"
+ );
+}
+else {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect"
+ );
+}
+
+# ============================================================
+# Step 1 — Problem Statement
+# ============================================================
+Section::Begin("Problem Statement");
+
+BEGIN_PGML
+A city transit department wants to estimate the true proportion of commuters who use its mobile transit app at least once per week.
+
+A previous survey suggests that about [``38\%``] of commuters use the app weekly.
+
+The department wants to estimate the true population proportion with a margin of error of at most [``0.05``] at the [``98\%``] confidence level.
+
+Find the minimum sample size [``n``] required.
+
+Round the raw calculator value of [``n``] to 3 decimals, then round the final sample size up to the next whole number.
+END_PGML
+
+Section::End();
+
+# ============================================================
+# Step 2 — Choose the correct formula
+# ============================================================
+Section::Begin("Section B — Choose the correct formula");
+
+BEGIN_PGML
+Choose the correct sample-size formula for this problem.
+
+1) [``n=\left(\dfrac{z_{\alpha/2}\sigma}{E}\right)^2``]
+
+2) [``n=\dfrac{z_{\alpha/2}^{2}\hat p(1-\hat p)}{E^{2}}``]
+
+3) [``n=\dfrac{t_{\alpha/2}^{2}\hat p(1-\hat p)}{E^{2}}``]
+
+4) [``n=\dfrac{z_{\alpha/2}\hat p(1-\hat p)}{E}``]
+
+5) [``n=\left(\dfrac{z_{\alpha/2}E}{\hat p}\right)^2``]
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_formula);
+
+Section::End();
+
+# ============================================================
+# Step 3 — Identify the ingredients
+# ============================================================
+Section::Begin("Section C — Identify the ingredients");
+
+BEGIN_PGML
+For this problem, identify the values you will substitute into the formula.
+
+Estimated [``\hat p``]: [____]
+
+Desired margin of error [``E``]: [____]
+
+Value of [``\alpha``]: [____]
+END_PGML
+
+ANS($cmp_phat, $cmp_E, $cmp_alpha);
+
+Section::End();
+
+# ============================================================
+# Step 4 — Find the cutoff
+# ============================================================
+Section::Begin("Section D — Find the cutoff");
+
+BEGIN_PGML
+For a [``98\%``] confidence level, use the normal table to find [``z_{\alpha/2}``].
+
+[@ image("cutoff.jpg", width=>520) @]*
+
+Enter [``z_{\alpha/2}``]: [____]
+END_PGML
+
+ANS($cmp_z);
+
+Section::End();
+
+# ============================================================
+# Step 5 — Compute the raw sample size
+# ============================================================
+Section::Begin("Section E — Compute the raw sample size");
+
+BEGIN_PGML
+Substitute into the sample-size formula:
+
+[``n=\dfrac{z_{\alpha/2}^{2}\hat p(1-\hat p)}{E^{2}}``]
+
+For this problem,
+
+[``n=\dfrac{(2.325)^2(0.38)(0.62)}{(0.05)^2} =``] [____]
+END_PGML
+
+ANS($cmp_n_raw);
+
+Section::End();
+
+# ============================================================
+# Step 6 — Round up to get the required sample size
+# ============================================================
+Section::Begin("Section F — Round up");
+
+BEGIN_PGML
+The raw calculator value of [``n``] is not a whole number.
+
+To guarantee that the margin of error is at most [``0.05``], we must round up.
+
+Enter the minimum whole-number sample size required: [____]
+END_PGML
+
+ANS($cmp_n_final);
+
+Section::End();
+
+# ============================================================
+# Step 7 — Interpretation
+# ============================================================
+Section::Begin("Section G — Interpret the answer");
+
+BEGIN_PGML
+Choose the best interpretation of your answer.
+
+1) The department should survey exactly [``509.266``] commuters.
+
+2) The answer means that [``98\%``] of commuters use the app.
+
+3) The department must survey at least [``510``] commuters so that a [``98\%``] confidence interval for the true proportion of weekly app users has a margin of error of at most [``0.05``], using the estimate [``\hat p \approx 0.38``].
+
+4) The sample size [``510``] guarantees that the true population proportion will be found exactly.
+
+5) The answer means that the true proportion is [``0.510``].
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_interp);
+
+Section::End();
+
+# ============================================================
+# Feedback — hidden in Library Browser
+# ============================================================
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+ Section::Begin("Feedback");
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+# ============================================================
+# Solution
+# ============================================================
+BEGIN_PGML_SOLUTION
+**1. Choose the correct formula**
+
+For planning a sample size for estimating a population proportion, when an estimate for [``\hat p``] is available, the formula is
+
+[``n=\dfrac{z_{\alpha/2}^{2}\hat p(1-\hat p)}{E^{2}}``]
+
+**2. Identify the ingredients**
+
+From the problem:
+
+- estimated [``\hat p = 0.38``]
+- so [``1-\hat p = 0.62``]
+- desired margin of error [``E = 0.05``]
+- confidence level [``98\%``], so [``\alpha = 0.02``]
+
+**3. Find the cutoff**
+
+Since [``\alpha = 0.02``], we have
+
+[``\alpha/2 = 0.01``]
+
+From the normal table,
+
+[``z_{\alpha/2} = 2.325``]
+
+**4. Compute the raw sample size**
+
+Substitute into the formula:
+
+[``n=\dfrac{z_{\alpha/2}^{2}\hat p(1-\hat p)}{E^{2}}``]
+
+So
+
+[``n=\dfrac{(2.325)^2(0.38)(0.62)}{(0.05)^2}``]
+
+[``n=\dfrac{5.405625(0.2356)}{0.0025}``]
+
+[``n=\dfrac{1.27316525}{0.0025}``]
+
+[``n=509.266``]
+
+**5. Round up**
+
+Since sample size must be a whole number and must guarantee the desired margin of error, we round up:
+
+[``n=510``]
+
+**6. Interpretation**
+
+The correct interpretation is:
+
+The department must survey at least [``510``] commuters so that a [``98\%``] confidence interval for the true proportion of weekly app users has a margin of error of at most [``0.05``], using the estimate [``\hat p \approx 0.38``].
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SampleSize_GuidedProblem3.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SampleSize_GuidedProblem3.pg
new file mode 100644
index 0000000000..15bbbfdf5b
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SampleSize_GuidedProblem3.pg
@@ -0,0 +1,488 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Sample Size for Estimating a Proportion:
+## No Estimate for p-hat Given (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Confidence Intervals)
+## DBsection(Sample Size for Estimating a Proportion)
+## Level(2)
+## KEYWORDS(
+## 'sample size',
+## 'margin of error',
+## 'confidence interval',
+## 'population proportion',
+## 'no estimate for p-hat',
+## 'z critical value'
+## )
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ============================================================
+# Settings
+# ============================================================
+
+$ENABLE_GP_RATING = 1;
+
+$inLibraryBrowser = 0;
+if ((defined($envir{isLibraryBrowser}) && $envir{isLibraryBrowser})
+ || (defined($envir{isLibrary}) && $envir{isLibrary})) {
+ $inLibraryBrowser = 1;
+}
+
+Context("Numeric");
+
+# ============================================================
+# Helper: show a hint only when the student's answer is wrong
+# ============================================================
+sub HintIfWrong {
+ my $msg = shift;
+
+ return sub {
+ my $ans = shift;
+
+ if (defined($ans->{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+
+ return $ans;
+ };
+}
+
+# ============================================================
+# Data
+# Context: sunscreen use among young adults
+# ============================================================
+
+$conf = 0.90;
+$phat_est = Real(0.5);
+$qhat_est = Real(0.5);
+$E = Real(0.03);
+$alpha = Real(0.10);
+$z_cut = Real(1.645);
+$n_raw = Real(751.6736111111);
+$n_final = 752;
+
+# ============================================================
+# Tolerances
+# ============================================================
+
+$tol_basic = 0.0005;
+$tol_z = 0.005;
+$tol_raw = 0.05;
+
+# ============================================================
+# Comparators
+# ============================================================
+
+# ------------------------------------------------------------
+# Concept multiple choice: why use p-hat = 0.5?
+# Correct answer: 2
+# ------------------------------------------------------------
+$cmp_why_half = Real(2)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ return 0 unless defined $student;
+
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+
+ return ($v == 2) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong(
+ "When no estimate for p-hat is available, using 0.5 makes p-hat(1-p-hat) as large as possible, which gives the largest and safest sample size."
+ )
+);
+
+# ------------------------------------------------------------
+# Identify ingredients
+# ------------------------------------------------------------
+$cmp_phat = $phat_est->cmp(
+ tolType => "absolute",
+ tolerance => $tol_basic
+)->withPostFilter(
+ HintIfWrong("When no estimate for p-hat is available, use p-hat = 0.5 for planning.")
+);
+
+$cmp_E = $E->cmp(
+ tolType => "absolute",
+ tolerance => $tol_basic
+)->withPostFilter(
+ HintIfWrong("Three percentage points means a margin of error of 0.03.")
+);
+
+$cmp_alpha = $alpha->cmp(
+ tolType => "absolute",
+ tolerance => $tol_basic
+)->withPostFilter(
+ HintIfWrong("For a 90% confidence level, 1 - alpha = 0.90, so alpha = 0.10.")
+);
+
+# ------------------------------------------------------------
+# z cutoff
+# ------------------------------------------------------------
+$cmp_z = $z_cut->cmp(
+ tolType => "absolute",
+ tolerance => $tol_z
+)->withPostFilter(
+ HintIfWrong(
+ "For a 90% confidence level, alpha = 0.10, so alpha/2 = 0.05 and z_(alpha/2) = 1.645."
+ )
+);
+
+# ------------------------------------------------------------
+# Raw sample size
+# ------------------------------------------------------------
+$cmp_n_raw = $n_raw->cmp(
+ tolType => "absolute",
+ tolerance => $tol_raw
+)->withPostFilter(
+ HintIfWrong("Substitute into n = z_(alpha/2)^2 p-hat(1-p-hat) / E^2 using p-hat = 0.5, then compute before rounding.")
+);
+
+# ------------------------------------------------------------
+# Final sample size
+# ------------------------------------------------------------
+$cmp_n_final = Real($n_final)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ return 0 unless defined $student;
+
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+
+ return ($v == $n_final) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong("Always round the required sample size up to the next whole number.")
+);
+
+# ------------------------------------------------------------
+# Interpretation multiple choice
+# Correct answer: 4
+# ------------------------------------------------------------
+$cmp_interp = Real(4)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ return 0 unless defined $student;
+
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+
+ return ($v == 4) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong(
+ "The final answer is the minimum whole-number sample size needed so the margin of error is at most the target value."
+ )
+);
+
+# ------------------------------------------------------------
+# Rating checker
+# Any integer 1 to 5 is accepted
+# ------------------------------------------------------------
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ return 0 unless defined $student;
+
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+
+ return 1;
+ }
+);
+
+# ============================================================
+# Scaffold setup
+# ============================================================
+
+if ($inLibraryBrowser) {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "always",
+ is_open => "always"
+ );
+}
+else {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect"
+ );
+}
+
+# ============================================================
+# Step 1 — Problem Statement
+# ============================================================
+Section::Begin("Problem Statement");
+
+BEGIN_PGML
+A dermatologist wishes to estimate the proportion of young adults who apply sunscreen regularly before going out in the sun in the summer.
+
+Find the minimum sample size required to estimate the population proportion to within [``3``] percentage points at the [``90\%``] confidence level.
+
+Assume that no previous estimate of the population proportion is available.
+
+Round the raw calculator value of [``n``] to 3 decimals, then round the final sample size up to the next whole number.
+END_PGML
+
+Section::End();
+
+# ============================================================
+# Step 2 — Formula
+# ============================================================
+Section::Begin("Section B — Formula");
+
+BEGIN_PGML
+For planning sample size for a population proportion, we use
+
+[``n=\dfrac{z_{\alpha/2}^{2}\hat p(1-\hat p)}{E^{2}}``]
+
+When no estimate for [``\hat p``] is available, we use [``\hat p=0.5``].
+END_PGML
+
+Section::End();
+
+# ============================================================
+# Step 3 — Why do we use p-hat = 0.5?
+# ============================================================
+Section::Begin("Section C — Why use p-hat = 0.5?");
+
+BEGIN_PGML
+Why do we use [``\hat p = 0.5``] when no prior estimate is available?
+
+1) Because [``0.5``] is always the true population proportion.
+
+2) Because [``\hat p(1-\hat p)``] is largest when [``\hat p=0.5``], so this gives the largest and safest required sample size.
+
+3) Because [``0.5``] makes the margin of error equal to [``0``].
+
+4) Because the confidence level is [``90\%``].
+
+5) Because [``0.5``] makes the cutoff [``z_{\alpha/2}``] equal to [``1.645``].
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_why_half);
+
+Section::End();
+
+# ============================================================
+# Step 4 — Identify the ingredients
+# ============================================================
+Section::Begin("Section D — Identify the ingredients");
+
+BEGIN_PGML
+For this problem, identify the values you will substitute into the formula.
+
+Value of [``\hat p``]: [____]
+
+Desired margin of error [``E``]: [____]
+
+Value of [``\alpha``]: [____]
+END_PGML
+
+ANS($cmp_phat, $cmp_E, $cmp_alpha);
+
+Section::End();
+
+# ============================================================
+# Step 5 — Find the cutoff
+# ============================================================
+Section::Begin("Section E — Find the cutoff");
+
+BEGIN_PGML
+For a [``90\%``] confidence level, use the normal table to find [``z_{\alpha/2}``].
+
+[@ image("cutoff.jpg", width=>520) @]*
+
+Enter [``z_{\alpha/2}``]: [____]
+END_PGML
+
+ANS($cmp_z);
+
+Section::End();
+
+# ============================================================
+# Step 6 — Compute the raw sample size
+# ============================================================
+Section::Begin("Section F — Compute the raw sample size");
+
+BEGIN_PGML
+Substitute into the sample-size formula:
+
+[``n=\dfrac{z_{\alpha/2}^{2}\hat p(1-\hat p)}{E^{2}}``]
+
+For this problem,
+
+[``n=\dfrac{(1.645)^2(0.5)(0.5)}{(0.03)^2} =``] [____]
+END_PGML
+
+ANS($cmp_n_raw);
+
+Section::End();
+
+# ============================================================
+# Step 7 — Round up to get the required sample size
+# ============================================================
+Section::Begin("Section G — Round up");
+
+BEGIN_PGML
+The raw calculator value of [``n``] is not a whole number.
+
+To guarantee that the margin of error is at most [``0.03``], we must round up.
+
+Enter the minimum whole-number sample size required: [____]
+END_PGML
+
+ANS($cmp_n_final);
+
+Section::End();
+
+# ============================================================
+# Step 8 — Interpretation
+# ============================================================
+Section::Begin("Section H — Interpret the answer");
+
+BEGIN_PGML
+Choose the best interpretation of your answer.
+
+1) The dermatologist should survey exactly [``751.674``] young adults.
+
+2) The answer means that [``90\%``] of young adults use sunscreen regularly.
+
+3) The sample size [``752``] guarantees that the true population proportion will be found exactly.
+
+4) The dermatologist must survey at least [``752``] young adults so that a [``90\%``] confidence interval for the true proportion has a margin of error of at most [``0.03``], using [``\hat p = 0.5``] for planning.
+
+5) The answer means that the true population proportion is [``0.752``].
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_interp);
+
+Section::End();
+
+# ============================================================
+# Feedback — hidden in Library Browser
+# ============================================================
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+ Section::Begin("Feedback");
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+# ============================================================
+# Solution
+# ============================================================
+BEGIN_PGML_SOLUTION
+**1. Use the formula**
+
+For planning a sample size for estimating a population proportion, we use
+
+[``n=\dfrac{z_{\alpha/2}^{2}\hat p(1-\hat p)}{E^{2}}``]
+
+Since no estimate for [``\hat p``] is available, we use
+
+[``\hat p=0.5``]
+
+**2. Why do we use [``0.5``]?**
+
+We use [``0.5``] because [``\hat p(1-\hat p)``] is largest when [``\hat p=0.5``].
+
+That gives the largest and most conservative required sample size.
+
+**3. Identify the ingredients**
+
+From the problem:
+
+- [``\hat p = 0.5``]
+- [``1-\hat p = 0.5``]
+- desired margin of error [``E = 0.03``]
+- confidence level [``90\%``], so [``\alpha = 0.10``]
+
+**4. Find the cutoff**
+
+Since [``\alpha = 0.10``], we have
+
+[``\alpha/2 = 0.05``]
+
+From the normal table,
+
+[``z_{\alpha/2} = 1.645``]
+
+**5. Compute the raw sample size**
+
+Substitute into the formula:
+
+[``n=\dfrac{z_{\alpha/2}^{2}\hat p(1-\hat p)}{E^{2}}``]
+
+So
+
+[``n=\dfrac{(1.645)^2(0.5)(0.5)}{(0.03)^2}``]
+
+[``n=\dfrac{2.706025(0.25)}{0.0009}``]
+
+[``n=\dfrac{0.67650625}{0.0009}``]
+
+[``n=751.674``]
+
+**6. Round up**
+
+Since sample size must be a whole number and must guarantee the desired margin of error, we round up:
+
+[``n=752``]
+
+**7. Interpretation**
+
+The correct interpretation is:
+
+The dermatologist must survey at least [``752``] young adults so that a [``90\%``] confidence interval for the true proportion has a margin of error of at most [``0.03``], using [``\hat p = 0.5``] for planning.
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SmallSample_GuidedProblem1.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SmallSample_GuidedProblem1.pg
new file mode 100644
index 0000000000..742559a657
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SmallSample_GuidedProblem1.pg
@@ -0,0 +1,529 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Small-Sample Confidence Intervals for the Mean (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Confidence Intervals)
+## DBsection(Confidence Interval for the Mean)
+## Level(2)
+## KEYWORDS('confidence interval','small sample','mean','known sigma','unknown sigma','normal population','t distribution','degrees of freedom','confidence level','critical value')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser detection (LB stability)
+# ----------------------------------------------------------------
+$inLibraryBrowser = ($envir{isLibraryBrowser} || $envir{isLibrary} || 0);
+
+Context("Numeric");
+
+# =======================================================
+# Postfilter: add a hint ONLY when the answer is wrong
+# =======================================================
+sub HintIfWrong {
+ my $msg = shift;
+ return sub {
+ my $ans = shift;
+ if (defined($ans->{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+ return $ans;
+ };
+}
+
+# =======================================================
+# Data for sample standard deviation checkpoint
+# =======================================================
+$x1 = 6;
+$x2 = 9;
+$x3 = 11;
+$x4 = 13;
+$x5 = 14;
+$x6 = 18;
+$x7 = 20;
+
+$s_exact = 4.89897948556636;
+
+# =======================================================
+# Correct targets
+# =======================================================
+$alpha_98 = Real(0.02);
+
+$df_10 = Real(9);
+
+# z critical values
+$z_010 = Real(1.645);
+$z_005 = Real(1.960);
+$z_002 = Real(2.325);
+$z_001 = Real(2.575);
+
+# t critical values for df = 9
+$t_010 = Real(1.833);
+$t_005 = Real(2.262);
+$t_002 = Real(2.821);
+$t_001 = Real(3.250);
+
+# =======================================================
+# Tolerances
+# =======================================================
+$tol_alpha = 0.0005;
+$tol_s = 0.02;
+$tol_z = 0.01;
+$tol_t = 0.02;
+
+# =======================================================
+# Comparators
+# =======================================================
+
+# Section B MC: correct choice = 2 (xbar)
+$cmp_point_est = Real(2)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+ return ($v == 2) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong("The appropriate point estimate for mu is the sample mean xbar.")
+);
+
+$cmp_alpha_98 = $alpha_98->cmp(
+ tolType => "absolute",
+ tolerance => $tol_alpha
+)->withPostFilter(
+ HintIfWrong("For a 98% confidence level, 1 - alpha = 0.98, so alpha = 0.02.")
+);
+
+# Section C MC: correct choice = 3
+$cmp_conf_meaning = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+ return ($v == 3) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong("The confidence level describes the long-run success rate of the method over many random samples.")
+);
+
+$cmp_s = Real($s_exact)->cmp(
+ tolType => "absolute",
+ tolerance => $tol_s
+)->withPostFilter(
+ HintIfWrong("Use the sample standard deviation on your calculator, not the population standard deviation.")
+);
+
+$cmp_df_10 = $df_10->cmp(
+ tolType => "absolute",
+ tolerance => 0
+)->withPostFilter(
+ HintIfWrong("For the t distribution, the degrees of freedom are n - 1.")
+);
+
+$cmp_z_010 = $z_010->cmp(
+ tolType => "absolute",
+ tolerance => $tol_z
+)->withPostFilter(
+ HintIfWrong("For alpha = 0.10, alpha/2 = 0.05, so the cutoff is z_(0.05) = 1.645.")
+);
+
+$cmp_z_005 = $z_005->cmp(
+ tolType => "absolute",
+ tolerance => $tol_z
+)->withPostFilter(
+ HintIfWrong("For alpha = 0.05, alpha/2 = 0.025, so the cutoff is z_(0.025) = 1.960.")
+);
+
+$cmp_z_002 = $z_002->cmp(
+ tolType => "absolute",
+ tolerance => $tol_z
+)->withPostFilter(
+ HintIfWrong("For alpha = 0.02, alpha/2 = 0.01, so the cutoff is z_(0.01) = 2.326.")
+);
+
+$cmp_z_001 = $z_001->cmp(
+ tolType => "absolute",
+ tolerance => $tol_z
+)->withPostFilter(
+ HintIfWrong("For alpha = 0.01, alpha/2 = 0.005, so the cutoff is z_(0.005) = 2.576.")
+);
+
+$cmp_t_010 = $t_010->cmp(
+ tolType => "absolute",
+ tolerance => $tol_t
+)->withPostFilter(
+ HintIfWrong("For df = 9 and alpha = 0.10, use t_(0.05,9) = 1.833.")
+);
+
+$cmp_t_005 = $t_005->cmp(
+ tolType => "absolute",
+ tolerance => $tol_t
+)->withPostFilter(
+ HintIfWrong("For df = 9 and alpha = 0.05, use t_(0.025,9) = 2.262.")
+);
+
+$cmp_t_002 = $t_002->cmp(
+ tolType => "absolute",
+ tolerance => $tol_t
+)->withPostFilter(
+ HintIfWrong("For df = 9 and alpha = 0.02, use t_(0.01,9) = 2.821.")
+);
+
+$cmp_t_001 = $t_001->cmp(
+ tolType => "absolute",
+ tolerance => $tol_t
+)->withPostFilter(
+ HintIfWrong("For df = 9 and alpha = 0.01, use t_(0.005,9) = 3.250.")
+);
+
+# Rating checker
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "always",
+ is_open => "always"
+ );
+} else {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect"
+ );
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+
+BEGIN_PGML
+In this Guided Problem, we introduce the idea of a small-sample confidence interval for the population mean [``\mu``].
+
+Assume a random sample of size [``n < 30``] is taken from a population.
+
+For the small-sample methods introduced here to be valid, the population must be normally distributed.
+
+In this GP, you will learn:
+
+- what a [``100(1-\alpha)\%``] confidence interval means,
+- what the confidence level represents,
+- the two small-sample formulas for a confidence interval for [``\mu``],
+- why normality of the population matters for small samples,
+- what degrees of freedom mean,
+- and how to find the correct cutoff using either the normal table or the t table.
+
+Rounding: Round cutoff values to 3 decimals.
+END_PGML
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 2 — Section B
+# -------------------------------------------------------
+Section::Begin("Section B — Appropriate point estimate for mu");
+
+BEGIN_PGML
+A confidence interval for [``\mu``] has the form
+
+[``\text{estimate} \pm \text{margin of error}``]
+
+What is the appropriate point estimate for the population mean [``\mu``]?
+
+1) [``\mu``]
+2) [``\bar x``]
+3) [``\sigma``]
+4) [``s``]
+5) [``\alpha``]
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_point_est);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 3 — Section C
+# -------------------------------------------------------
+Section::Begin("Section C — Level of confidence");
+
+BEGIN_PGML
+When we build a confidence interval, we must consider the required level of confidence.
+
+Common values are usually [``90\%``] ([``\alpha = 0.10``]), [``95\%``] ([``\alpha = 0.05``]), and [``99\%``] ([``\alpha = 0.01``]).
+
+The confidence level describes how the method behaves over many random samples. For example, a [``95\%``] level of confidence means [``95\%``] of intervals built using this method, by repeatedly sampling the population, will capture the actual [``\mu``].
+
+1) If the confidence level is [``98\%``], enter the value of [``\alpha``]:
+
+[____]
+
+2) Choose the best interpretation of a [``100(1-\alpha)\%``] confidence interval:
+
+1) [``100(1-\alpha)\%``] of all sample means are equal to [``\mu``].
+2) There is a [``100(1-\alpha)\%``] chance that [``\mu``] changes from sample to sample.
+3) If we repeatedly took many random samples and built intervals the same way each time, about [``100(1-\alpha)\%``] of those intervals would contain [``\mu``].
+4) A [``100(1-\alpha)\%``] confidence interval always contains [``\mu``].
+5) The confidence level tells us that this particular sample must be correct.
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_alpha_98, $cmp_conf_meaning);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 4 — Section D
+# -------------------------------------------------------
+Section::Begin("Section D — Small-sample formulas and sample standard deviation");
+
+BEGIN_PGML
+For small samples, the Central Limit Theorem does not apply. If the population is normally distributed, [``\bar X``] follows the normal distribution for known [``\sigma``] and the t-student distribution for unknown [``\sigma``].
+
+There are two common small-sample formulas for a confidence interval for [``\mu``]:
+
+**Case 1: sigma known**
+If the population is normal and [``\sigma``] is known, use
+
+[``\bar x \pm z_{\alpha/2}\dfrac{\sigma}{\sqrt{n}}``]
+
+So in this case, the cutoff comes from the **normal table**.
+
+**Case 2: sigma unknown**
+If the population is normal and [``\sigma``] is unknown, use
+
+[``\bar x \pm t_{\alpha/2}\dfrac{s}{\sqrt{n}}``]
+
+So in this case, the cutoff comes from the **t table**.
+
+For the t distribution, we also need the degrees of freedom:
+
+[``df = n - 1``]
+
+Use your calculator to find the **sample standard deviation** of the following data:
+
+[``6,\ 9,\ 11,\ 13,\ 14,\ 18,\ 20``]
+
+Enter [``s``]: [____]
+END_PGML
+
+ANS($cmp_s);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 5 — Sections E
+# -------------------------------------------------------
+Section::Begin("Sections E — Degrees of freedom and cutoff values");
+
+BEGIN_PGML
+For a [``100(1-\alpha)\%``] confidence interval:
+
+- the middle area is [``1-\alpha``]
+- the total area in the two tails is [``\alpha``]
+- each tail has area [``\alpha/2``]
+
+For **small samples**, remember:
+
+- if [``\sigma``] is known, use the **normal table** and the cutoff [``z_{\alpha/2}``]
+- if [``\sigma``] is unknown, use the **t table** and the cutoff [``t_{\alpha/2}``]
+- for the t distribution, [``df=n-1``]
+
+In this section, assume sample size [``n=10``].
+
+[@ image("cutoff_t.jpg", width=>520) @]*
+
+1) If [``n=10``], enter the degrees of freedom:
+
+[____]
+
+2) Assume [``\sigma``] is known. Use the **normal table** to find the positive cutoff [``z_{\alpha/2}``] for each value of [``\alpha``]:
+
+For [``\alpha = 0.10``], enter [``z_{\alpha/2}``]: [____]
+
+For [``\alpha = 0.05``], enter [``z_{\alpha/2}``]: [____]
+
+For [``\alpha = 0.02``], enter [``z_{\alpha/2}``]: [____]
+
+For [``\alpha = 0.01``], enter [``z_{\alpha/2}``]: [____]
+
+3) Assume [``\sigma``] is unknown. Use the **t table** with your degrees of freedom to find the positive cutoff [``t_{\alpha/2}``] for each value of [``\alpha``]:
+
+For [``\alpha = 0.10``], enter [``t_{\alpha/2}``]: [____]
+
+For [``\alpha = 0.05``], enter [``t_{\alpha/2}``]: [____]
+
+For [``\alpha = 0.02``], enter [``t_{\alpha/2}``]: [____]
+
+For [``\alpha = 0.01``], enter [``t_{\alpha/2}``]: [____]
+
+Note that smaller [``\alpha``] means higher confidence level, which is desirable. However, smaller [``\alpha``] also means a bigger cutoff value that will result in a bigger margin of error for the confidence interval. This is a trade-off. Higher confidence level comes at the expense of a wider, and thus less precise, confidence interval.
+END_PGML
+
+ANS(
+ $cmp_df_10,
+ $cmp_z_010, $cmp_z_005, $cmp_z_002, $cmp_z_001,
+ $cmp_t_010, $cmp_t_005, $cmp_t_002, $cmp_t_001
+);
+
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating) — hidden in Library Browser
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+ Section::Begin("Feedback");
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+BEGIN_PGML_SOLUTION
+**1. Appropriate point estimate**
+
+A confidence interval for [``\mu``] is centered at the sample mean.
+
+So the appropriate point estimate for the population mean [``\mu``] is
+
+[``\bar x``]
+
+**2. Confidence level and alpha**
+
+If the confidence level is [``98\%``], then
+
+[``1-\alpha = 0.98``]
+
+so
+
+[``\alpha = 0.02``]
+
+The confidence level describes the long-run success rate of the method. For example, a [``95\%``] confidence level means that if we repeatedly sample the population and build intervals the same way each time, about [``95\%``] of those intervals will capture the true [``\mu``].
+
+**3. Small-sample formulas**
+
+For small samples, the population should be normally distributed.
+
+If [``\sigma``] is known, use
+
+[``\bar x \pm z_{\alpha/2}\dfrac{\sigma}{\sqrt{n}}``]
+
+So the cutoff comes from the normal table.
+
+If [``\sigma``] is unknown, use
+
+[``\bar x \pm t_{\alpha/2}\dfrac{s}{\sqrt{n}}``]
+
+So the cutoff comes from the t table.
+
+This second formula uses the t distribution because [``\sigma``] is unknown and we replace it with [``s``].
+
+**4. Degrees of freedom**
+
+For the t distribution,
+
+[``df = n - 1``]
+
+So if [``n=10``], then
+
+[``df = 10 - 1 = 9``]
+
+**5. Compute the sample standard deviation**
+
+For the data
+
+[``6,\ 9,\ 11,\ 13,\ 14,\ 18,\ 20``]
+
+the sample mean is
+
+[``\bar x = 13``]
+
+So the sample variance is
+
+[``s^2 = \dfrac{144}{7-1} = 24``]
+
+and the sample standard deviation is
+
+[``s = \sqrt{24} \approx 4.899``]
+
+**6. Cutoff values when sigma is known**
+
+If [``\sigma``] is known, we use the normal table.
+
+The common positive cutoffs are:
+
+- for [``\alpha = 0.10``]: [``z_{0.05} = 1.645``]
+- for [``\alpha = 0.05``]: [``z_{0.025} = 1.960``]
+- for [``\alpha = 0.02``]: [``z_{0.01} = 2.325``]
+- for [``\alpha = 0.01``]: [``z_{0.005} = 2.575``]
+
+**7. Cutoff values when sigma is unknown**
+
+If [``\sigma``] is unknown and [``n=10``], then [``df=9``] and we use the t table.
+
+The common positive cutoffs are:
+
+- for [``\alpha = 0.10``]: [``t_{0.05,9} = 1.833``]
+- for [``\alpha = 0.05``]: [``t_{0.025,9} = 2.262``]
+- for [``\alpha = 0.02``]: [``t_{0.01,9} = 2.821``]
+- for [``\alpha = 0.01``]: [``t_{0.005,9} = 3.250``]
+
+These t cutoffs are larger than the corresponding z cutoffs because small samples with unknown [``\sigma``] involve more uncertainty.
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SmallSample_GuidedProblem2.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SmallSample_GuidedProblem2.pg
new file mode 100644
index 0000000000..8465ea99bb
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SmallSample_GuidedProblem2.pg
@@ -0,0 +1,426 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Confidence Interval for the Mean: Small Sample, Sigma Known (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Confidence Intervals)
+## DBsection(Confidence Interval for the Mean)
+## Level(2)
+## KEYWORDS('confidence interval','population mean','small sample','sigma known','normal population','z critical value','standard error','margin of error')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser detection (LB stability)
+# ----------------------------------------------------------------
+$inLibraryBrowser = ($envir{isLibraryBrowser} || $envir{isLibrary} || 0);
+
+Context("Numeric");
+
+# =======================================================
+# Postfilter: add a hint ONLY when the answer is wrong
+# =======================================================
+sub HintIfWrong {
+ my $msg = shift;
+ return sub {
+ my $ans = shift;
+ if (defined($ans->{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+ return $ans;
+ };
+}
+
+# =======================================================
+# Data
+# =======================================================
+$xbar = 38;
+$sigma = 6;
+$n = 16;
+$conf = 0.90;
+
+$alpha = Real(0.10);
+$z_cutoff = Real(1.645);
+$se = Real(1.5);
+$me = Real(2.4675);
+$lcl = Real(35.5325);
+$ucl = Real(40.4675);
+
+# =======================================================
+# Tolerances
+# =======================================================
+$tol_alpha = 0.0005;
+$tol_z = 0.005;
+$tol_se = 0.005;
+$tol_me = 0.01;
+$tol_end = 0.02;
+
+# =======================================================
+# Comparators
+# =======================================================
+
+# Formula-selection MC: correct choice = 4
+$cmp_formula = Real(4)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+ return ($v == 4) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong("Because the population is normal and sigma is known, use xbar +/- z_(alpha/2)(sigma/sqrt(n)).")
+);
+
+$cmp_alpha = $alpha->cmp(
+ tolType => "absolute",
+ tolerance => $tol_alpha
+)->withPostFilter(
+ HintIfWrong("For a 90% confidence level, 1 - alpha = 0.90, so alpha = 0.10.")
+);
+
+$cmp_z = $z_cutoff->cmp(
+ tolType => "absolute",
+ tolerance => $tol_z
+)->withPostFilter(
+ HintIfWrong("For a 90% confidence interval, alpha = 0.10, so alpha/2 = 0.05 and the table cutoff is 1.645.")
+);
+
+$cmp_se = $se->cmp(
+ tolType => "absolute",
+ tolerance => $tol_se
+)->withPostFilter(
+ HintIfWrong("The standard error here is sigma/sqrt(n).")
+);
+
+$cmp_me = $me->cmp(
+ tolType => "absolute",
+ tolerance => $tol_me
+)->withPostFilter(
+ HintIfWrong("The margin of error is z_(alpha/2)(sigma/sqrt(n)).")
+);
+
+$cmp_lcl = $lcl->cmp(
+ tolType => "absolute",
+ tolerance => $tol_end
+)->withPostFilter(
+ HintIfWrong("The lower endpoint is xbar minus the margin of error.")
+);
+
+$cmp_ucl = $ucl->cmp(
+ tolType => "absolute",
+ tolerance => $tol_end
+)->withPostFilter(
+ HintIfWrong("The upper endpoint is xbar plus the margin of error.")
+);
+
+# Interpretation MC: correct choice = 2
+$cmp_interp = Real(2)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+ return ($v == 2) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong("A confidence interval for mu is interpreted as a plausible range for the true population mean.")
+);
+
+# Rating checker
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "always",
+ is_open => "always"
+ );
+} else {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect"
+ );
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+
+BEGIN_PGML
+A university parking office wants to estimate the true mean morning commute time for students who drive to campus.
+
+A random sample of [``n=16``] students is selected. The sample mean commute time is [``\bar x = 38``] minutes.
+The population standard deviation is known to be [``\sigma = 6``] minutes.
+
+Assume the population of commute times is normally distributed.
+
+Construct a [``90\%``] confidence interval for the true population mean [``\mu``].
+
+Round the cutoff, standard error, margin of error, and interval endpoints to 3 decimals.
+END_PGML
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 2 — Choose the correct formula
+# -------------------------------------------------------
+Section::Begin("Section B — Choose the correct formula");
+
+BEGIN_PGML
+Choose the correct confidence-interval formula for this problem, considering that the sample is small, the population is normal, and the population standard deviation [``\sigma``] is known.
+
+1) [``\bar x \pm t_{\alpha/2}\dfrac{s}{\sqrt{n}}``]
+
+2) [``\hat p \pm z_{\alpha/2}\sqrt{\dfrac{\hat p(1-\hat p)}{n}}``]
+
+3) [``\bar x \pm z_{\alpha/2}\dfrac{s}{\sqrt{n}}``]
+
+4) [``\bar x \pm z_{\alpha/2}\dfrac{\sigma}{\sqrt{n}}``]
+
+5) [``\bar x \pm t_{\alpha/2}\dfrac{\sigma}{\sqrt{n}}``]
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_formula);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 3 — Find alpha and the cutoff
+# -------------------------------------------------------
+Section::Begin("Section C — Find alpha and the cutoff");
+
+BEGIN_PGML
+For a [``90\%``] confidence interval:
+
+- [``1-\alpha = 0.90``]
+- each tail has area [``\alpha/2``]
+
+1) Enter the value of [``\alpha``]:
+
+[____]
+
+[@ image("cutoff.jpg", width=>520) @]*
+
+2) Use the normal table to find the positive cutoff [``z_{\alpha/2}``].
+
+Enter [``z_{\alpha/2}``]: [____]
+END_PGML
+
+ANS($cmp_alpha, $cmp_z);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 4 — Compute the standard error and margin of error
+# -------------------------------------------------------
+Section::Begin("Section D — Compute the standard error and margin of error");
+
+BEGIN_PGML
+Compute the standard error:
+
+[``\dfrac{\sigma}{\sqrt{n}}``]
+
+For this problem,
+
+[``\dfrac{6}{\sqrt{16}} =``] [____]
+
+Now compute the margin of error:
+
+[``E = z_{\alpha/2}\dfrac{\sigma}{\sqrt{n}}``]
+
+For this problem,
+
+[``E = (1.645)\left(\dfrac{6}{\sqrt{16}}\right) =``] [____]
+END_PGML
+
+ANS($cmp_se, $cmp_me);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 5 — Construct the confidence interval
+# -------------------------------------------------------
+Section::Begin("Section E — Construct the confidence interval");
+
+BEGIN_PGML
+Now construct the confidence interval:
+
+[``\bar x \pm E``]
+
+Using [``\bar x = 38``] and your margin of error, enter the two endpoints.
+
+Lower endpoint: [____]
+
+Upper endpoint: [____]
+END_PGML
+
+ANS($cmp_lcl, $cmp_ucl);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 6 — Interpretation
+# -------------------------------------------------------
+Section::Begin("Section F — Interpret the confidence interval");
+
+BEGIN_PGML
+The [``90\%``] confidence interval is
+
+[``(35.533,\ 40.468)``]
+
+Choose the best interpretation.
+
+1) [``90\%``] of all commuting students take between [``35.533``] and [``40.468``] minutes to get to campus.
+
+2) We are [``90\%``] confident that the true mean commute time for all students who drive to campus is between [``35.533``] and [``40.468``] minutes.
+
+3) There is a [``90\%``] chance that the sample mean [``\bar x``] is between [``35.533``] and [``40.468``].
+
+4) The interval proves that the true population mean is exactly [``38``] minutes.
+
+5) [``90\%``] of all possible sample means are exactly equal to [``\mu``].
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_interp);
+
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating) — hidden in Library Browser
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+ Section::Begin("Feedback");
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+BEGIN_PGML_SOLUTION
+**1. Choose the correct formula**
+
+Because the population is normal and the population standard deviation [``\sigma``] is known, the correct formula is
+
+[``\bar x \pm z_{\alpha/2}\dfrac{\sigma}{\sqrt{n}}``]
+
+**2. Find alpha and the cutoff**
+
+For a [``90\%``] confidence interval,
+
+[``1-\alpha = 0.90``]
+
+so
+
+[``\alpha = 0.10``]
+
+Then
+
+[``\alpha/2 = 0.05``]
+
+From the normal table,
+
+[``z_{\alpha/2} = z_{0.05} = 1.645``]
+
+**3. Compute the standard error**
+
+[``\dfrac{\sigma}{\sqrt{n}} = \dfrac{6}{\sqrt{16}} = \dfrac{6}{4} = 1.500``]
+
+So the standard error is [``1.500``].
+
+**4. Compute the margin of error**
+
+[``E = z_{\alpha/2}\dfrac{\sigma}{\sqrt{n}}``]
+
+So
+
+[``E = (1.645)(1.500) = 2.468``]
+
+**5. Construct the confidence interval**
+
+Use
+
+[``\bar x \pm E``]
+
+So
+
+[``38 \pm 2.468``]
+
+Lower endpoint:
+
+[``38 - 2.468 = 35.533``]
+
+Upper endpoint:
+
+[``38 + 2.468 = 40.468``]
+
+Therefore, the [``90\%``] confidence interval for [``\mu``] is
+
+[``(35.533,\ 40.468)``]
+
+**6. Interpret the confidence interval**
+
+The correct interpretation is:
+
+We are [``90\%``] confident that the true mean commute time for all students who drive to campus is between [``35.533``] and [``40.468``] minutes.
+
+This interval gives a plausible range for the population mean [``\mu``]. It does **not** describe where [``90\%``] of individual commute times fall, and it does **not** mean that the sample mean has a [``90\%``] chance of being in that interval.
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SmallSample_GuidedProblem3.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SmallSample_GuidedProblem3.pg
new file mode 100644
index 0000000000..754ad499bf
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SmallSample_GuidedProblem3.pg
@@ -0,0 +1,432 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Confidence Interval for the Mean: Small Sample, Sigma Unknown (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Confidence Intervals)
+## DBsection(Confidence Interval for the Mean)
+## Level(2)
+## KEYWORDS('confidence interval','population mean','small sample','sigma unknown','normal population','t critical value','standard error','margin of error')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser detection (LB stability)
+# ----------------------------------------------------------------
+$inLibraryBrowser = ($envir{isLibraryBrowser} || $envir{isLibrary} || 0);
+
+Context("Numeric");
+
+# =======================================================
+# Postfilter: add a hint ONLY when the answer is wrong
+# =======================================================
+sub HintIfWrong {
+ my $msg = shift;
+ return sub {
+ my $ans = shift;
+ if (defined($ans->{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+ return $ans;
+ };
+}
+
+# =======================================================
+# Data
+# =======================================================
+$xbar = 68;
+$s = 5.4;
+$n = 9;
+$df = 8;
+$conf = 0.95;
+
+$alpha = Real(0.05);
+$t_cutoff = Real(2.306);
+$se = Real(1.8);
+$me = Real(4.1508);
+$lcl = Real(63.8492);
+$ucl = Real(72.1508);
+
+# =======================================================
+# Tolerances
+# =======================================================
+$tol_alpha = 0.0005;
+$tol_t = 0.005;
+$tol_se = 0.005;
+$tol_me = 0.01;
+$tol_end = 0.02;
+
+# =======================================================
+# Comparators
+# =======================================================
+
+# Formula-selection MC: correct choice = 1
+$cmp_formula = Real(1)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+ return ($v == 1) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong("Because the sample is small, the population is normal, and sigma is unknown, use xbar +/- t_(alpha/2)(s/sqrt(n)).")
+);
+
+$cmp_alpha = $alpha->cmp(
+ tolType => "absolute",
+ tolerance => $tol_alpha
+)->withPostFilter(
+ HintIfWrong("For a 95% confidence level, 1 - alpha = 0.95, so alpha = 0.05.")
+);
+
+$cmp_t = $t_cutoff->cmp(
+ tolType => "absolute",
+ tolerance => $tol_t
+)->withPostFilter(
+ HintIfWrong("For a 95% confidence interval, alpha = 0.05, so alpha/2 = 0.025. With n = 9, the degrees of freedom are 8, so use t_(0.025,8) = 2.306.")
+);
+
+$cmp_se = $se->cmp(
+ tolType => "absolute",
+ tolerance => $tol_se
+)->withPostFilter(
+ HintIfWrong("The standard error here is s/sqrt(n).")
+);
+
+$cmp_me = $me->cmp(
+ tolType => "absolute",
+ tolerance => $tol_me
+)->withPostFilter(
+ HintIfWrong("The margin of error is t_(alpha/2)(s/sqrt(n)).")
+);
+
+$cmp_lcl = $lcl->cmp(
+ tolType => "absolute",
+ tolerance => $tol_end
+)->withPostFilter(
+ HintIfWrong("The lower endpoint is xbar minus the margin of error.")
+);
+
+$cmp_ucl = $ucl->cmp(
+ tolType => "absolute",
+ tolerance => $tol_end
+)->withPostFilter(
+ HintIfWrong("The upper endpoint is xbar plus the margin of error.")
+);
+
+# Interpretation MC: correct choice = 2
+$cmp_interp = Real(2)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+ return ($v == 2) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong("A confidence interval for mu is interpreted as a plausible range for the true population mean.")
+);
+
+# Rating checker
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "always",
+ is_open => "always"
+ );
+} else {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect"
+ );
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+
+BEGIN_PGML
+A museum wants to estimate the true mean amount of time visitors spend inside a special exhibition.
+
+A random sample of [``n=9``] visitors is selected. The sample mean time is [``\bar x = 68``] minutes.
+The sample standard deviation is [``s = 5.4``] minutes.
+
+Assume the population of visit times is normally distributed.
+
+Construct a [``95\%``] confidence interval for the true population mean [``\mu``].
+
+Round the cutoff, standard error, margin of error, and interval endpoints to 3 decimals.
+END_PGML
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 2 — Choose the correct formula
+# -------------------------------------------------------
+Section::Begin("Section B — Choose the correct formula");
+
+BEGIN_PGML
+Choose the correct confidence-interval formula for this problem, considering that the sample is small, the population is normal, and the population standard deviation [``\sigma``] is unknown.
+
+1) [``\bar x \pm t_{\alpha/2}\dfrac{s}{\sqrt{n}}``]
+
+2) [``\hat p \pm z_{\alpha/2}\sqrt{\dfrac{\hat p(1-\hat p)}{n}}``]
+
+3) [``\bar x \pm z_{\alpha/2}\dfrac{s}{\sqrt{n}}``]
+
+4) [``\bar x \pm z_{\alpha/2}\dfrac{\sigma}{\sqrt{n}}``]
+
+5) [``\bar x \pm t_{\alpha/2}\dfrac{\sigma}{\sqrt{n}}``]
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_formula);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 3 — Find alpha and the cutoff
+# -------------------------------------------------------
+Section::Begin("Section C — Find alpha and the cutoff");
+
+BEGIN_PGML
+For a [``95\%``] confidence interval:
+
+- [``1-\alpha = 0.95``]
+- each tail has area [``\alpha/2``]
+- since [``n=9``], the degrees of freedom are [``df = 8``]
+
+1) Enter the value of [``\alpha``]:
+
+[____]
+
+[@ image("cutoff_t.jpg", width=>520) @]*
+
+2) Use the t table to find the positive cutoff [``t_{\alpha/2}``].
+
+Enter [``t_{\alpha/2}``]: [____]
+END_PGML
+
+ANS($cmp_alpha, $cmp_t);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 4 — Compute the standard error and margin of error
+# -------------------------------------------------------
+Section::Begin("Section D — Compute the standard error and margin of error");
+
+BEGIN_PGML
+Compute the standard error:
+
+[``\dfrac{s}{\sqrt{n}}``]
+
+For this problem,
+
+[``\dfrac{5.4}{\sqrt{9}} =``] [____]
+
+Now compute the margin of error:
+
+[``E = t_{\alpha/2}\dfrac{s}{\sqrt{n}}``]
+
+For this problem,
+
+[``E = (2.306)\left(\dfrac{5.4}{\sqrt{9}}\right) =``] [____]
+END_PGML
+
+ANS($cmp_se, $cmp_me);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 5 — Construct the confidence interval
+# -------------------------------------------------------
+Section::Begin("Section E — Construct the confidence interval");
+
+BEGIN_PGML
+Now construct the confidence interval:
+
+[``\bar x \pm E``]
+
+Using [``\bar x = 68``] and your margin of error, enter the two endpoints.
+
+Lower endpoint: [____]
+
+Upper endpoint: [____]
+END_PGML
+
+ANS($cmp_lcl, $cmp_ucl);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 6 — Interpretation
+# -------------------------------------------------------
+Section::Begin("Section F — Interpret the confidence interval");
+
+BEGIN_PGML
+The [``95\%``] confidence interval is
+
+[``(63.849,\ 72.151)``]
+
+Choose the best interpretation.
+
+1) [``95\%``] of all museum visitors spend between [``63.849``] and [``72.151``] minutes in the special exhibition.
+
+2) We are [``95\%``] confident that the true mean time all visitors spend in the special exhibition is between [``63.849``] and [``72.151``] minutes.
+
+3) There is a [``95\%``] chance that the sample mean [``\bar x``] is between [``63.849``] and [``72.151``].
+
+4) The interval proves that the true population mean is exactly [``68``] minutes.
+
+5) [``95\%``] of all possible sample means are exactly equal to [``\mu``].
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_interp);
+
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating) — hidden in Library Browser
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+ Section::Begin("Feedback");
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+BEGIN_PGML_SOLUTION
+**1. Choose the correct formula**
+
+Because the sample is small, the population is normal, and the population standard deviation [``\sigma``] is unknown, the correct formula is
+
+[``\bar x \pm t_{\alpha/2}\dfrac{s}{\sqrt{n}}``]
+
+**2. Find alpha and the cutoff**
+
+For a [``95\%``] confidence interval,
+
+[``1-\alpha = 0.95``]
+
+so
+
+[``\alpha = 0.05``]
+
+Then
+
+[``\alpha/2 = 0.025``]
+
+Since [``n=9``], the degrees of freedom are
+
+[``df = n-1 = 8``]
+
+From the t table,
+
+[``t_{\alpha/2} = t_{0.025,8} = 2.306``]
+
+**3. Compute the standard error**
+
+[``\dfrac{s}{\sqrt{n}} = \dfrac{5.4}{\sqrt{9}} = \dfrac{5.4}{3} = 1.800``]
+
+So the standard error is [``1.800``].
+
+**4. Compute the margin of error**
+
+[``E = t_{\alpha/2}\dfrac{s}{\sqrt{n}}``]
+
+So
+
+[``E = (2.306)(1.800) = 4.151``]
+
+**5. Construct the confidence interval**
+
+Use
+
+[``\bar x \pm E``]
+
+So
+
+[``68 \pm 4.151``]
+
+Lower endpoint:
+
+[``68 - 4.151 = 63.849``]
+
+Upper endpoint:
+
+[``68 + 4.151 = 72.151``]
+
+Therefore, the [``95\%``] confidence interval for [``\mu``] is
+
+[``(63.849,\ 72.151)``]
+
+**6. Interpret the confidence interval**
+
+The correct interpretation is:
+
+We are [``95\%``] confident that the true mean time all visitors spend in the special exhibition is between [``63.849``] and [``72.151``] minutes.
+
+This interval gives a plausible range for the population mean [``\mu``]. It does **not** describe where [``95\%``] of individual visit times fall, and it does **not** mean that the sample mean has a [``95\%``] chance of being in that interval.
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SmallSample_GuidedProblem4.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SmallSample_GuidedProblem4.pg
new file mode 100644
index 0000000000..2f401117da
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/ConfidenceInterval_SmallSample_GuidedProblem4.pg
@@ -0,0 +1,548 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Confidence Interval for the Mean:
+## Small Sample, Sigma Unknown, Raw Data Given (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Confidence Intervals)
+## DBsection(Confidence Interval for the Mean)
+## Level(2)
+## KEYWORDS(
+## 'confidence interval',
+## 'population mean',
+## 'small sample',
+## 'sigma unknown',
+## 'sample standard deviation',
+## 't critical value',
+## 'standard error',
+## 'margin of error'
+## )
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ============================================================
+# Settings
+# ============================================================
+
+$ENABLE_GP_RATING = 1;
+
+$inLibraryBrowser = 0;
+if ((defined($envir{isLibraryBrowser}) && $envir{isLibraryBrowser})
+ || (defined($envir{isLibrary}) && $envir{isLibrary})) {
+ $inLibraryBrowser = 1;
+}
+
+Context("Numeric");
+
+# ============================================================
+# Helper: show a hint only when the student's answer is wrong
+# ============================================================
+sub HintIfWrong {
+ my $msg = shift;
+
+ return sub {
+ my $ans = shift;
+
+ if (defined($ans->{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+
+ return $ans;
+ };
+}
+
+# ============================================================
+# Data
+# Context: large poster printing times (in minutes)
+# ============================================================
+
+$n = 10;
+$conf = 0.99;
+
+# Raw data:
+# 18.2, 20.1, 19.5, 21.0, 20.4, 18.9, 19.8, 20.7, 21.3, 19.1
+
+$xbar = Real(19.9);
+$s = Real(0.9888264649);
+$alpha = Real(0.01);
+$df = 9;
+$t_cut = Real(3.250);
+$se = Real(0.3126890567);
+$me = Real(1.0162394342);
+$lcl = Real(18.8837605658);
+$ucl = Real(20.9162394342);
+
+# ============================================================
+# Tolerances
+# ============================================================
+
+$tol_xbar = 0.005;
+$tol_s = 0.005;
+$tol_alpha = 0.0005;
+$tol_t = 0.005;
+$tol_se = 0.005;
+$tol_me = 0.01;
+$tol_end = 0.02;
+
+# ============================================================
+# Comparators
+# ============================================================
+
+# ------------------------------------------------------------
+# Formula-selection multiple choice
+# Correct answer: 3
+# ------------------------------------------------------------
+$cmp_formula = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ return 0 unless defined $student;
+
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+
+ return ($v == 3) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong(
+ "Because the sample is small, the population is normal, and sigma is unknown, use xbar +/- t_(alpha/2)(s/sqrt(n))."
+ )
+);
+
+# ------------------------------------------------------------
+# Sample mean
+# ------------------------------------------------------------
+$cmp_xbar = $xbar->cmp(
+ tolType => "absolute",
+ tolerance => $tol_xbar
+)->withPostFilter(
+ HintIfWrong("Use your calculator's 1-variable statistics and enter the sample mean xbar.")
+);
+
+# ------------------------------------------------------------
+# Sample standard deviation
+# ------------------------------------------------------------
+$cmp_s = $s->cmp(
+ tolType => "absolute",
+ tolerance => $tol_s
+)->withPostFilter(
+ HintIfWrong("Be sure to use the sample standard deviation s, not the population standard deviation.")
+);
+
+# ------------------------------------------------------------
+# Alpha
+# ------------------------------------------------------------
+$cmp_alpha = $alpha->cmp(
+ tolType => "absolute",
+ tolerance => $tol_alpha
+)->withPostFilter(
+ HintIfWrong("For a 99% confidence level, 1 - alpha = 0.99, so alpha = 0.01.")
+);
+
+# ------------------------------------------------------------
+# t cutoff
+# ------------------------------------------------------------
+$cmp_t = $t_cut->cmp(
+ tolType => "absolute",
+ tolerance => $tol_t
+)->withPostFilter(
+ HintIfWrong(
+ "For a 99% confidence interval with n = 10, use df = 9 and alpha/2 = 0.005. Then read t_(0.005,9) from the t table."
+ )
+);
+
+# ------------------------------------------------------------
+# Standard error
+# ------------------------------------------------------------
+$cmp_se = $se->cmp(
+ tolType => "absolute",
+ tolerance => $tol_se
+)->withPostFilter(
+ HintIfWrong("The standard error here is s/sqrt(n).")
+);
+
+# ------------------------------------------------------------
+# Margin of error
+# ------------------------------------------------------------
+$cmp_me = $me->cmp(
+ tolType => "absolute",
+ tolerance => $tol_me
+)->withPostFilter(
+ HintIfWrong("The margin of error is t_(alpha/2) times s/sqrt(n).")
+);
+
+# ------------------------------------------------------------
+# Lower endpoint
+# ------------------------------------------------------------
+$cmp_lcl = $lcl->cmp(
+ tolType => "absolute",
+ tolerance => $tol_end
+)->withPostFilter(
+ HintIfWrong("The lower endpoint is xbar minus the margin of error.")
+);
+
+# ------------------------------------------------------------
+# Upper endpoint
+# ------------------------------------------------------------
+$cmp_ucl = $ucl->cmp(
+ tolType => "absolute",
+ tolerance => $tol_end
+)->withPostFilter(
+ HintIfWrong("The upper endpoint is xbar plus the margin of error.")
+);
+
+# ------------------------------------------------------------
+# Interpretation multiple choice
+# Correct answer: 4
+# ------------------------------------------------------------
+$cmp_interp = Real(4)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ return 0 unless defined $student;
+
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+
+ return ($v == 4) ? 1 : 0;
+ }
+)->withPostFilter(
+ HintIfWrong(
+ "A confidence interval for mu is interpreted as a plausible range for the true population mean."
+ )
+);
+
+# ------------------------------------------------------------
+# Rating checker
+# Any integer 1 to 5 is accepted
+# ------------------------------------------------------------
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+
+ return 0 unless defined $student;
+
+ my $v = $student->value;
+ return 0 unless defined $v;
+ return 0 unless $v == int($v);
+ return 0 unless ($v >= 1 && $v <= 5);
+
+ return 1;
+ }
+);
+
+# ============================================================
+# Scaffold setup
+# ============================================================
+
+if ($inLibraryBrowser) {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "always",
+ is_open => "always"
+ );
+}
+else {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect"
+ );
+}
+
+# ============================================================
+# Step 1 — Problem Statement
+# ============================================================
+Section::Begin("Problem Statement");
+
+BEGIN_PGML
+A university print shop wants to estimate the true mean time required to print a large conference poster.
+
+A random sample of [``n=10``] poster-printing jobs is selected. The printing times, in minutes, are:
+
+[``18.2,\ 20.1,\ 19.5,\ 21.0,\ 20.4,\ 18.9,\ 19.8,\ 20.7,\ 21.3,\ 19.1``]
+
+Assume the population of printing times is normally distributed.
+
+Construct a [``99\%``] confidence interval for the true population mean [``\mu``].
+
+Round [``\bar x``], [``s``], the cutoff, the standard error, the margin of error, and the interval endpoints to 3 decimals.
+END_PGML
+
+Section::End();
+
+# ============================================================
+# Step 2 — Choose the correct formula
+# ============================================================
+Section::Begin("Section B — Choose the correct formula");
+
+BEGIN_PGML
+Choose the correct confidence-interval formula for this problem.
+
+1) [``\bar x \pm z_{\alpha/2}\dfrac{\sigma}{\sqrt{n}}``]
+
+2) [``\bar x \pm t_{\alpha/2}\dfrac{\sigma}{\sqrt{n}}``]
+
+3) [``\bar x \pm t_{\alpha/2}\dfrac{s}{\sqrt{n}}``]
+
+4) [``\hat p \pm z_{\alpha/2}\sqrt{\dfrac{\hat p(1-\hat p)}{n}}``]
+
+5) [``\bar x \pm z_{\alpha/2}\dfrac{s}{\sqrt{n}}``]
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_formula);
+
+Section::End();
+
+# ============================================================
+# Step 3 — Use a calculator to find xbar and s
+# ============================================================
+Section::Begin("Section C — Use a calculator to find xbar and s");
+
+BEGIN_PGML
+Use your calculator's 1-variable statistics on the 10 printing times.
+
+Enter the sample mean [``\bar x``]: [____]
+
+Enter the sample standard deviation [``s``]: [____]
+END_PGML
+
+ANS($cmp_xbar, $cmp_s);
+
+Section::End();
+
+# ============================================================
+# Step 4 — Find alpha and the t cutoff
+# ============================================================
+Section::Begin("Section D — Find alpha and the cutoff");
+
+BEGIN_PGML
+For a [``99\%``] confidence interval:
+
+- [``1-\alpha = 0.99``]
+- each tail has area [``\alpha/2``]
+- the degrees of freedom are [``n-1 = 9``]
+
+1) Enter the value of [``\alpha``]:
+
+[____]
+
+[@ image("cutoff_t.jpg", width=>520) @]*
+
+2) Use the [``t``] table to find the positive cutoff [``t_{\alpha/2}``] for [``df=9``].
+
+Enter [``t_{\alpha/2}``]: [____]
+END_PGML
+
+ANS($cmp_alpha, $cmp_t);
+
+Section::End();
+
+# ============================================================
+# Step 5 — Compute the standard error and margin of error
+# ============================================================
+Section::Begin("Section E — Compute the standard error and margin of error");
+
+BEGIN_PGML
+Compute the standard error:
+
+[``\dfrac{s}{\sqrt{n}}``]
+
+For this problem,
+
+[``\dfrac{s}{\sqrt{10}} =``] [____]
+
+Now compute the margin of error:
+
+[``E = t_{\alpha/2}\dfrac{s}{\sqrt{n}}``]
+
+For this problem,
+
+[``E = t_{\alpha/2}\left(\dfrac{s}{\sqrt{10}}\right) =``] [____]
+END_PGML
+
+ANS($cmp_se, $cmp_me);
+
+Section::End();
+
+# ============================================================
+# Step 6 — Construct the confidence interval
+# ============================================================
+Section::Begin("Section F — Construct the confidence interval");
+
+BEGIN_PGML
+Now construct the confidence interval:
+
+[``\bar x \pm E``]
+
+Using your values of [``\bar x``] and [``E``], enter the two endpoints.
+
+Lower endpoint: [____]
+
+Upper endpoint: [____]
+END_PGML
+
+ANS($cmp_lcl, $cmp_ucl);
+
+Section::End();
+
+# ============================================================
+# Step 7 — Interpretation
+# ============================================================
+Section::Begin("Section G — Interpret the confidence interval");
+
+BEGIN_PGML
+Choose the best interpretation of the confidence interval you constructed for [``\mu``].
+
+1) [``99\%``] of all individual poster-printing times must lie inside the interval.
+
+2) There is a [``99\%``] chance that the sample mean [``\bar x``] lies inside the interval.
+
+3) The interval proves that the true mean printing time is exactly equal to [``\bar x``].
+
+4) We are [``99\%``] confident that the true mean time required to print a large conference poster lies between the two endpoints of the interval.
+
+5) [``99\%``] of all possible sample means are equal to the true mean.
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_interp);
+
+Section::End();
+
+# ============================================================
+# Feedback — hidden in Library Browser
+# ============================================================
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+ Section::Begin("Feedback");
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+# ============================================================
+# Solution
+# ============================================================
+BEGIN_PGML_SOLUTION
+**1. Choose the correct formula**
+
+Because the sample is small, the population is normal, and the population standard deviation is unknown, the correct formula is
+
+[``\bar x \pm t_{\alpha/2}\dfrac{s}{\sqrt{n}}``]
+
+**2. Compute the sample mean and sample standard deviation**
+
+Using the 10 data values in 1-variable statistics, we get
+
+[``\bar x = 19.900``]
+
+and
+
+[``s = 0.989``]
+
+(more precisely, [``s \approx 0.988826``]).
+
+**3. Find alpha and the t cutoff**
+
+For a [``99\%``] confidence interval,
+
+[``1-\alpha = 0.99``]
+
+so
+
+[``\alpha = 0.01``]
+
+Then
+
+[``\alpha/2 = 0.005``]
+
+and the degrees of freedom are
+
+[``df = n-1 = 10-1 = 9``]
+
+From the [``t``] table,
+
+[``t_{\alpha/2} = t_{0.005,9} = 3.250``]
+
+**4. Compute the standard error**
+
+[``\dfrac{s}{\sqrt{n}} = \dfrac{0.988826}{\sqrt{10}} \approx 0.313``]
+
+So the standard error is [``0.313``].
+
+**5. Compute the margin of error**
+
+[``E = t_{\alpha/2}\dfrac{s}{\sqrt{n}}``]
+
+So
+
+[``E = (3.250)(0.312689) \approx 1.016``]
+
+Therefore, the margin of error is [``1.016``].
+
+**6. Construct the confidence interval**
+
+Use
+
+[``\bar x \pm E``]
+
+So
+
+[``19.900 \pm 1.016``]
+
+Lower endpoint:
+
+[``19.900 - 1.016 = 18.884``]
+
+Upper endpoint:
+
+[``19.900 + 1.016 = 20.916``]
+
+Therefore, the [``99\%``] confidence interval for [``\mu``] is
+
+[``(18.884,\ 20.916)``]
+
+**7. Interpret the confidence interval**
+
+The correct interpretation is:
+
+We are [``99\%``] confident that the true mean time required to print a large conference poster lies between [``18.884``] minutes and [``20.916``] minutes.
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/cutoff.jpg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/cutoff.jpg
new file mode 100644
index 0000000000..6a650be0ea
Binary files /dev/null and b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/cutoff.jpg differ
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/cutoff_t.jpg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/cutoff_t.jpg
new file mode 100644
index 0000000000..a856b2b0c3
Binary files /dev/null and b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/Estimation/cutoff_t.jpg differ
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/NormalRandomVariables_NonStandard_GuidedProblem1.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/NormalRandomVariables_NonStandard_GuidedProblem1.pg
new file mode 100644
index 0000000000..ddbabc4c65
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/NormalRandomVariables_NonStandard_GuidedProblem1.pg
@@ -0,0 +1,333 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Standardizing: Using the z-table for Non-Standard Normal Variables (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Normal Distribution)
+## Level(2)
+## KEYWORDS('normal distribution','standardization','z score','z table','non-standard normal','cutoff')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser detection (LB stability)
+# ----------------------------------------------------------------
+$inLibraryBrowser = ($envir{isLibraryBrowser} || $envir{isLibrary} || 0);
+
+# =======================================================
+# Data
+# =======================================================
+Context("Numeric");
+
+# Images (put in same folder as this .pg file)
+$IMG_STD = "non_st_to_st.jpg";
+$IMG_THEORY = "nonstandard_theory.jpg"; # <-- rename this to match your actual filename if different
+
+# Main variable for Practices 1-6
+$mu = Real(70);
+$sigma = Real(8);
+
+# Warm-up z-scores
+$z_78 = Real("1.00"); # (78-70)/8
+$z_62 = Real("-1.00"); # (62-70)/8
+
+# Probabilities (computed internally; not shown to students)
+$p_X_lt_78 = Real("0.8413"); # P(X<78)
+$p_X_gt_62 = Real("0.8413"); # P(X>62)
+$p_66_82 = Real("0.6247"); # P(66 x* = 70 + (1.6448536269)(8)
+$x_star_95 = Real("83.16");
+
+# NEW last reverse problem (same non-standard normal):
+# Find x* such that P(|X-70| < x*) = 0.90 with X~N(70,8).
+# Standardize: |X-70| |Z| < x*/8
+# Need z* where P(|Z| z* ≈ 1.6448536269
+# Thus x* = 8 z* ≈ 13.1588290156
+$x_star_abs90 = Real("13.16");
+
+# Tolerances
+$tol_z = 0.005; # z-scores to 2 decimals
+$tol_p = 0.00005; # probabilities to 4 decimals
+$tol_x3 = 0.0005; # cutoffs to 3 decimals
+
+# Answer evaluators (with gentle AnswerHints)
+$cmp_z1 = $z_78->cmp(tolType=>"absolute", tolerance=>$tol_z)->withPostFilter(AnswerHints(
+ 0.00 => "Make sure you subtract the mean first, then divide by the standard deviation."
+));
+$cmp_z2 = $z_62->cmp(tolType=>"absolute", tolerance=>$tol_z)->withPostFilter(AnswerHints(
+ 1.00 => "Check the sign: 62 is below the mean, so the z-score should be negative."
+));
+
+$cmp_p1 = $p_X_lt_78->cmp(tolType=>"absolute", tolerance=>$tol_p)->withPostFilter(AnswerHints(
+ 0.5000 => "If you got 0.5, you may have used z=0. Recheck your z-score."
+));
+$cmp_p2 = $p_X_gt_62->cmp(tolType=>"absolute", tolerance=>$tol_p)->withPostFilter(AnswerHints(
+ 0.1587 => "That is a common left-tail value for z=-1. This question is a right tail."
+));
+$cmp_p3 = $p_66_82->cmp(tolType=>"absolute", tolerance=>$tol_p)->withPostFilter(AnswerHints(
+ 0.9332 => "That looks like a single left-tail. This one is between two cutoffs."
+));
+$cmp_p4 = $p_within_12->cmp(tolType=>"absolute", tolerance=>$tol_p)->withPostFilter(AnswerHints(
+ 0.5000 => "This is not centered at 0 in X-units; first convert both endpoints to z-scores."
+));
+
+$cmp_x1 = $x_star_95->cmp(tolType=>"absolute", tolerance=>$tol_x3)->withPostFilter(AnswerHints(
+ 70 => "If you answered the mean, you probably stopped after finding z*."
+));
+$cmp_x2 = $x_star_abs90->cmp(tolType=>"absolute", tolerance=>$tol_x3)->withPostFilter(AnswerHints(
+ 1.645 => "That is the z* value. Convert it back to X-units by multiplying by sigma."
+));
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "always",
+ is_open => "always",
+ );
+} else {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ );
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement and Goal
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+Let [``X``] be a normally distributed random variable.
+
+**Goal:** Use your standard normal table by first converting a probability about [``X``] into a probability about a standard normal variable [``Z``].
+
+In Practices 1 to 6, assume:
+
+[``X \sim N(70,8)``]
+
+Here [``70``] is the mean and [``8``] is the standard deviation.
+
+Rounding:
+- Round **z-scores** to **2 decimals**.
+- Round **probabilities** to **4 decimals**.
+- Round **cutoffs** like [``x^*``] to **3 decimals**.
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Step 2 — Standardizing theory + picture
+# -------------------------------------------------------
+Section::Begin("Standardizing (same shaded area)");
+BEGIN_PGML
+**Theory (standardizing an interval):**
+
+If [``X \sim N(\mu,\sigma)``], then
+
+[``P(a760) @]*
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Step 3 — Warm-up: compute z-scores
+# -------------------------------------------------------
+Section::Begin("Warm-up: compute z-scores");
+BEGIN_PGML
+Compute each z-score (round to 2 decimals).
+
+1) For [``x=78``], compute [``z=\dfrac{x-\mu}{\sigma}=\dfrac{x-70}{8}``].
+[____]
+
+2) For [``x=62``], compute [``z=\dfrac{x-\mu}{\sigma}=\dfrac{x-70}{8}``].
+[____]
+END_PGML
+
+ANS($cmp_z1, $cmp_z2);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 4 — Practice 1: left tail probability
+# -------------------------------------------------------
+Section::Begin("Practice 1");
+BEGIN_PGML
+Find [``P(X<78)``] (round to 4 decimals).
+
+Hint: From the previous step, the z-score for 78 is [``1``]. So [``P(X<78)=P(Z<1)``], Use your table to find the answer.
+
+Answer: [____]
+END_PGML
+
+ANS($cmp_p1);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 5 — Practice 2: right tail probability
+# -------------------------------------------------------
+Section::Begin("Practice 2");
+BEGIN_PGML
+Find [``P(X>62)``] (round to 4 decimals).
+
+Hint: From step (c), the z-score for 62 is [``-1``]. So [``P(X>62)=P(Z>-1)``], Use your table to find the answer.
+
+Answer: [____]
+END_PGML
+
+ANS($cmp_p2);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 6 — Practice 3: between two numbers
+# -------------------------------------------------------
+Section::Begin("Practice 3");
+BEGIN_PGML
+Find [``P(66cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return 1;
+ }
+ );
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/NormalRandomVariables_NonStandard_GuidedProblem2.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/NormalRandomVariables_NonStandard_GuidedProblem2.pg
new file mode 100644
index 0000000000..f3ee94cad5
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/NormalRandomVariables_NonStandard_GuidedProblem2.pg
@@ -0,0 +1,340 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Standardizing: Using the z-table for Non-Standard Normal Variables (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Normal Distribution)
+## Level(2)
+## KEYWORDS('normal distribution','standardization','z score','z table','non-standard normal','cutoff')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser detection (LB stability)
+# ----------------------------------------------------------------
+$inLibraryBrowser = ($envir{isLibraryBrowser} || $envir{isLibrary} || 0);
+
+# =======================================================
+# Data
+# =======================================================
+Context("Numeric");
+
+# Image (put in same folder as this .pg file)
+$IMG_STD = "non_st_to_st.jpg";
+
+# Main variable for Practices 1-6
+$mu = Real(68);
+$sigma = Real(7);
+
+# Warm-up z-scores (rounded to 2 decimals, as students are instructed)
+$z_79 = Real("1.57"); # (79-68)/7 = 1.5714...
+$z_60 = Real("-1.14"); # (60-68)/7 = -1.1429...
+
+# Probabilities using the rounded z-scores above (students will use 2-decimal z in tables)
+$p_X_lt_79 = Real("0.9418"); # Phi(1.57)
+$p_X_gt_60 = Real("0.8729"); # 1 - Phi(-1.14) = Phi(1.14)
+$p_64_76 = Real("0.5886"); # Phi(1.14) - Phi(-0.57)
+$p_within_10 = Real("0.8472"); # Phi(1.43) - Phi(-1.43)
+
+# Reverse cutoff: P(X < x*) = 0.93
+# Table typically brackets 0.93 between z = 1.47 and 1.48, so use the average z* = 1.475
+# x* = 68 + (1.475)(7) = 78.325
+$x_star_93 = Real("78.325");
+
+# Reverse centered at mean: P(|X-68| < x*) = 0.90
+# P(|Z| < z*) = 0.90 -> area from 0 to z* is 0.45 (usually bracketed by 1.64 and 1.65)
+# z* = 1.645 (average), so x* = (1.645)(7) = 11.515
+$x_star_abs90 = Real("11.515");
+
+# Tolerances
+$tol_z = 0.005; # z-scores to 2 decimals
+$tol_p = 0.00005; # probabilities to 4 decimals
+$tol_x3 = 0.0005; # cutoffs to 3 decimals
+
+# Answer evaluators + hints
+$cmp_z1 = $z_79->cmp(tolType=>"absolute", tolerance=>$tol_z)->withPostFilter(AnswerHints(
+ 1.00 => "These z-scores are not meant to be clean. Double-check (x - mean) / sd."
+));
+
+$cmp_z2 = $z_60->cmp(tolType=>"absolute", tolerance=>$tol_z)->withPostFilter(AnswerHints(
+ 1.14 => "Check the sign: 60 is below the mean, so the z-score should be negative."
+));
+
+$cmp_p1 = $p_X_lt_79->cmp(tolType=>"absolute", tolerance=>$tol_p)->withPostFilter(AnswerHints(
+ 0.5000 => "If you got 0.5, you may have used z=0. Recheck your z-score first."
+));
+
+$cmp_p2 = $p_X_gt_60->cmp(tolType=>"absolute", tolerance=>$tol_p)->withPostFilter(AnswerHints(
+ 0.1271 => "That looks like a right tail for z=1.14. Make sure you're using the correct tail for X>60."
+));
+
+$cmp_p3 = $p_64_76->cmp(tolType=>"absolute", tolerance=>$tol_p)->withPostFilter(AnswerHints(
+ 0.8729 => "That looks like a one-sided probability. This one is between two cutoffs."
+));
+
+$cmp_p4 = $p_within_10->cmp(tolType=>"absolute", tolerance=>$tol_p)->withPostFilter(AnswerHints(
+ 0.9418 => "That looks like a single left-tail. This one is an interval centered at the mean."
+));
+
+$cmp_x1 = $x_star_93->cmp(tolType=>"absolute", tolerance=>$tol_x3)->withPostFilter(AnswerHints(
+ 1.475 => "That is the z* value. Convert it back to X-units using x* = mean + (z*)(sd)."
+));
+
+$cmp_x2 = $x_star_abs90->cmp(tolType=>"absolute", tolerance=>$tol_x3)->withPostFilter(AnswerHints(
+ 1.645 => "That is the z* value. Convert it back to X-units by multiplying by the standard deviation."
+));
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "always",
+ is_open => "always",
+ );
+} else {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ );
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement and Goal
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+Let [``X``] be a normally distributed random variable.
+
+**Goal:** Use your standard normal table by first converting a probability about [``X``] into a probability about a standard normal variable [``Z``].
+
+In Practices 1 to 6, assume:
+
+[``X \sim N(68,7)``]
+
+Here [``68``] is the mean and [``7``] is the standard deviation.
+
+Rounding:
+- Round **z-scores** to **2 decimals**.
+- Round **probabilities** to **4 decimals**.
+- Round **cutoffs** like [``x^*``] to **3 decimals**.
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Step 2 — Standardizing theory + picture
+# -------------------------------------------------------
+Section::Begin("Standardizing (same shaded area)");
+BEGIN_PGML
+**Theory (standardizing an interval):**
+
+If [``X \sim N(\mu,\sigma)``], then
+
+[``P(a760) @]*
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Step 3 — Warm-up: compute z-scores
+# -------------------------------------------------------
+Section::Begin("Warm-up: compute z-scores");
+BEGIN_PGML
+Compute each z-score (round to 2 decimals).
+
+1) For [``x=79``], compute [``z= \dfrac{x-\mu}{\sigma} = \dfrac{x-68}{7}``].
+[____]
+
+2) For [``x=60``], compute [``z= \dfrac{x-\mu}{\sigma} = \dfrac{x-68}{7}``].
+[____]
+END_PGML
+
+ANS($cmp_z1, $cmp_z2);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 4 — Practice 1: left tail probability
+# -------------------------------------------------------
+Section::Begin("Practice 1");
+BEGIN_PGML
+Find [``P(X<79)``] (round to 4 decimals).
+
+Hint: Use the z-score for 79 that you found in the previous step. [``P(X<79)=P(Z60)``] (round to 4 decimals).
+
+Hint: Use the z-score for 60 that you found in step (c). [``P(X>60)=P(Z>z)``]. Use your table to find this probability.
+
+Answer: [____]
+END_PGML
+
+ANS($cmp_p2);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 6 — Practice 3: between two numbers
+# -------------------------------------------------------
+Section::Begin("Practice 3");
+BEGIN_PGML
+Find [``P(64cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return 1;
+ }
+ );
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/NormalRandomVariables_NonStandard_GuidedProblem3.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/NormalRandomVariables_NonStandard_GuidedProblem3.pg
new file mode 100644
index 0000000000..4165db6a92
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/NormalRandomVariables_NonStandard_GuidedProblem3.pg
@@ -0,0 +1,203 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Normal Probability (Battery Lifetimes) (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Normal Distribution)
+## Level(2)
+## KEYWORDS('normal distribution','standardization','z score','z table','non-standard normal')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser detection (LB stability)
+# ----------------------------------------------------------------
+$inLibraryBrowser = ($envir{isLibraryBrowser} || $envir{isLibrary} || 0);
+
+# =======================================================
+# Data
+# =======================================================
+Context("Numeric");
+
+$mu = Real("18.5");
+$sigma = Real("2.1");
+
+# z-scores (students round to 2 decimals)
+$z1 = Real("-1.19"); # (16 - 18.5)/2.1 = -1.190476...
+$z2 = Real("1.19"); # (21 - 18.5)/2.1 = 1.190476...
+
+# Final probability using z = +/-1.19 from tables:
+# Phi(1.19)=0.8830 so P(-1.19cmp(tolType=>"absolute", tolerance=>$tol_z)->withPostFilter(AnswerHints(
+ 1.19 => "Check the sign: 16 is below the mean 18.5, so the z-score should be negative.",
+ -1.00 => "These z-scores are not meant to be clean. Use (x - mean) / sd carefully."
+));
+
+$cmp_z2 = $z2->cmp(tolType=>"absolute", tolerance=>$tol_z)->withPostFilter(AnswerHints(
+ -1.19 => "Check the sign: 21 is above the mean 18.5, so the z-score should be positive."
+));
+
+$cmp_p = $p_final->cmp(tolType=>"absolute", tolerance=>$tol_p)->withPostFilter(AnswerHints(
+ 0.8830 => "That looks like a single left-tail value. This question is the area between two cutoffs.",
+ 0.3830 => "That is the area between 0 and z (for z=1.19). For the full interval -z to z, you need to double it.",
+ 0.2340 => "That looks like a right-tail. Recheck whether you subtracted the two left-tail areas correctly."
+));
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "always",
+ is_open => "always",
+ );
+} else {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ );
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+The lifetimes of a certain brand of phone battery are normally distributed with mean [``18.5``] hours and standard deviation [``2.1``] hours.
+
+In symbols:
+
+[``X \sim N(18.5,2.1)``]
+
+Find the probability that a randomly selected battery lasts **between 16 and 21 hours**:
+
+[``P(16cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return 1;
+ }
+ );
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/NormalRandomVariables_NonStandard_GuidedProblem4.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/NormalRandomVariables_NonStandard_GuidedProblem4.pg
new file mode 100644
index 0000000000..07e4c49cae
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/NormalRandomVariables_NonStandard_GuidedProblem4.pg
@@ -0,0 +1,194 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Normal Probability (Delivery Times: More Than 50 Minutes) (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Normal Distribution)
+## Level(2)
+## KEYWORDS('normal distribution','standardization','z score','z table','right tail','delivery time')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser detection (LB stability)
+# ----------------------------------------------------------------
+$inLibraryBrowser = ($envir{isLibraryBrowser} || $envir{isLibrary} || 0);
+
+# =======================================================
+# Data
+# =======================================================
+Context("Numeric");
+
+$mu = Real(42); # minutes
+$sigma = Real(8); # minutes
+
+# z-score for 50 minutes (students round to 2 decimals)
+$z = Real("1.00");
+
+# P(T > 50) = P(Z > 1.00) = 0.1587
+$p_final = Real("0.1587");
+
+# Tolerances
+$tol_z = 0.005; # z-scores to 2 decimals
+$tol_p = 0.00005; # probabilities to 4 decimals
+
+$cmp_z = $z->cmp(tolType=>"absolute", tolerance=>$tol_z)->withPostFilter(AnswerHints(
+ 0.00 => "Make sure you subtract the mean first, then divide by the standard deviation.",
+ -1.00 => "Check the sign: 50 is above the mean 42, so the z-score should be positive."
+));
+
+$cmp_p = $p_final->cmp(tolType=>"absolute", tolerance=>$tol_p)->withPostFilter(AnswerHints(
+ 0.8413 => "That looks like a left-tail probability for z=1.00. This question asks for a right tail (more than 50).",
+ 0.5000 => "If you got 0.5, you may have used z=0. Recheck the z-score first."
+));
+
+# Rating checker (any integer 1–5 is marked correct)
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "always",
+ is_open => "always",
+ );
+} else {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ );
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+The delivery time (in minutes) for an online grocery service is normally distributed with mean [``42``] minutes and standard deviation [``8``] minutes.
+
+In symbols:
+
+[``T \sim N(42,8)``]
+
+Find the probability that a delivery takes **more than 50 minutes**:
+
+[``P(T>50)``]
+
+Rounding:
+- Round the **z-score** to **2 decimals**.
+- Round the final **probability** to **4 decimals**.
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Step 2 — Standardizing
+# -------------------------------------------------------
+Section::Begin("Standardizing");
+BEGIN_PGML
+To use a standard normal table, convert [``T``] to a standard normal variable [``Z``] using:
+
+[``z=\dfrac{t-\mu}{\sigma}``]
+
+For this problem:
+
+[``z=\dfrac{t-42}{8}``]
+
+So:
+
+[``P(T>50)=P\!\left(Z>\dfrac{50-42}{8}\right)``]
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Step 3 — Compute the z-score
+# -------------------------------------------------------
+Section::Begin("Compute the z-score");
+BEGIN_PGML
+Compute the z-score for [``t=50``] (round to 2 decimals):
+
+[``z=\dfrac{50-42}{8}``]
+
+Answer: [____]
+END_PGML
+
+ANS($cmp_z);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 4 — Final Answer
+# -------------------------------------------------------
+Section::Begin("Final Answer");
+BEGIN_PGML
+Now compute the probability (round to 4 decimals):
+
+[``P(T>50)=P(Z>z)``]
+
+Hint: If your table gives a left-tail probability [``P(Zcmp(tolType=>"absolute", tolerance=>$tol_z)->withPostFilter(AnswerHints(
+ 0.80 => "0.80 is a probability, not a z-score. Use your table to find z such that P(Z "1.28 corresponds to about 0.90 in the left tail. Here we need the left tail 0.80."
+));
+
+$cmp_x = $x_star->cmp(tolType=>"absolute", tolerance=>$tol_x)->withPostFilter(AnswerHints(
+ 0.842 => "That is z*. Convert back using x* = 510 + (z*)(60).",
+ 510 => "510 is the mean, not the cutoff for the top 20%."
+));
+
+# Rating checker (any integer 1–5 is marked correct)
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "always",
+ is_open => "always",
+ );
+} else {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ );
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+Scores on a standardized college entrance examination (CEE) are normally distributed with mean [``510``] and standard deviation [``60``].
+
+In symbols:
+
+[``X \sim N(510,60)``]
+
+A selective university considers for admission only applicants with CEE scores in the **top 20%**.
+
+Find the minimum score [``x^*``] that meets this requirement.
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Step 2 — Translate “top 20%” into a probability statement
+# -------------------------------------------------------
+Section::Begin("Translate the requirement");
+BEGIN_PGML
+"Top 20%" means that 20% of the scores are **above** the cutoff [``x^*``].
+
+So you can write the requirement as either:
+
+- [``P(X>x^*)=0.20``] (right tail), or equivalently
+- [``P(Xcmp(tolType=>"absolute", tolerance=>$tol_z)->withPostFilter(AnswerHints(
+ 0.05 => "0.05 is a probability, not a z-score. Use the table to find z such that P(Z "Check the sign. The lowest 5% is in the left tail, so z* must be negative."
+));
+
+$cmp_t = $t_star->cmp(tolType=>"absolute", tolerance=>$tol_t)->withPostFilter(AnswerHints(
+ -1.645 => "That is z*. Convert back using t* = mean + (z*)(sd).",
+ 28.5 => "28.5 is the mean, not the cutoff for the fastest 5%."
+));
+
+# Rating checker (any integer 1–5 is marked correct)
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "always",
+ is_open => "always",
+ );
+} else {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ );
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+The completion times for a certain 5K race are normally distributed with mean [``28.5``] minutes and standard deviation [``3.2``] minutes.
+
+In symbols:
+
+[``T \sim N(28.5,3.2)``]
+
+A running club gives a special award to runners whose times are in the **lowest 5%** (the fastest 5%).
+
+Find the cutoff time [``t^*``] such that a runner qualifies if their time is **less than** [``t^*``].
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Step 2 — Translate the requirement
+# -------------------------------------------------------
+Section::Begin("Translate the requirement");
+BEGIN_PGML
+"Lowest 5%" means that 5% of times are **below** the cutoff [``t^*``].
+
+So the requirement is:
+
+[``P(Tcmp(tolType=>"absolute", tolerance=>$tol_z)->withPostFilter(AnswerHints(
+ 0.75 => "0.75 is a probability, not a z-score. You need z* such that P(Z "You are very close. If the exact cutoff is not in the table, use the average of the two closest cutoffs.",
+ 0.68 => "You are very close. If the exact cutoff is not in the table, use the average of the two closest cutoffs."
+));
+
+$cmp_low = $t_low->cmp(tolType=>"absolute", tolerance=>$tol_t)->withPostFilter(AnswerHints(
+ 28.5 => "That is the mean. The lower cutoff should be below the mean.",
+ 30.66 => "That looks like the upper cutoff. The lower cutoff should be smaller."
+));
+
+$cmp_up = $t_up->cmp(tolType=>"absolute", tolerance=>$tol_t)->withPostFilter(AnswerHints(
+ 28.5 => "That is the mean. The upper cutoff should be above the mean.",
+ 26.34 => "That looks like the lower cutoff. The upper cutoff should be larger."
+));
+
+# Rating checker (any integer 1–5 is marked correct)
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "always",
+ is_open => "always",
+ );
+} else {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ );
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+The completion times for a certain 5K race are normally distributed with mean [``28.5``] minutes and standard deviation [``3.2``] minutes.
+
+In symbols:
+
+[``T \sim N(28.5,3.2)``]
+
+The running club wants to identify the **average runners**, meaning the **middle 50%** of completion times.
+
+Find the time interval [``(t_L,t_U)``] such that:
+
+[``P(t_L 0.93)
+$ans_d = $P_le_093 - Real("0.5"); # P(0 <= Z <= 0.93)
+$ans_e = $ans_c; # P(Z < -0.93)
+$ans_f = Real(2) * $ans_d; # P(-0.93 <= Z <= 0.93)
+$ans_g = $ans_d; # P(-0.93 <= Z <= 0)
+
+# Accept 4-decimal rounding comfortably
+$tolerance = 0.00005;
+
+# Answer evaluators + hints (ASCII in Perl strings for LB stability)
+$cmp_a = $ans_a->cmp(tolType=>"absolute", tolerance=>$tolerance)->withPostFilter(AnswerHints(
+ $ans_c->value => "This is a left-tail probability. Use the table value directly (do not take 1 minus it)."
+));
+
+$cmp_b = $ans_b->cmp(tolType=>"absolute", tolerance=>$tolerance)->withPostFilter(AnswerHints(
+ $ans_c->value => "For a continuous normal variable, 'less than' and 'less than or equal to' give the same probability."
+));
+
+$cmp_c = $ans_c->cmp(tolType=>"absolute", tolerance=>$tolerance)->withPostFilter(AnswerHints(
+ $ans_a->value => "This is a right-tail probability. Use 1 minus the left-tail probability."
+));
+
+$cmp_d = $ans_d->cmp(tolType=>"absolute", tolerance=>$tolerance)->withPostFilter(AnswerHints(
+ $ans_a->value => "This is between 0 and 0.93. Compute (left tail at 0.93) minus (left tail at 0)."
+));
+
+$cmp_e = $ans_e->cmp(tolType=>"absolute", tolerance=>$tolerance)->withPostFilter(AnswerHints(
+ $ans_a->value => "Use symmetry: the left tail at -0.93 equals the right tail at +0.93."
+));
+
+$cmp_f = $ans_f->cmp(tolType=>"absolute", tolerance=>$tolerance)->withPostFilter(AnswerHints(
+ $ans_d->value => "This interval is symmetric about 0. It is 2 times the area from 0 to 0.93."
+));
+
+$cmp_g = $ans_g->cmp(tolType=>"absolute", tolerance=>$tolerance)->withPostFilter(AnswerHints(
+ $ans_e->value => "This is the area between -0.93 and 0. Use symmetry, or subtract the left tail at -0.93 from 0.5."
+));
+
+# Final-answer evaluator (expression entry)
+$cmp_final = $ans_f->cmp(tolType=>"absolute", tolerance=>$tolerance)->withPostFilter(AnswerHints(
+ $ans_d->value => "This is the middle area from -0.93 to 0.93, not just from 0 to 0.93."
+));
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "always",
+ is_open => "always",
+ );
+} else {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ );
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+Let [``Z``] be a standard normal random variable.
+
+Use the standard normal table shown in the next step to find each probability.
+Round your answers to **4 decimals**.
+
+a) [``P(Z < 0.93)``]
+b) [``P(Z \le 0.93)``]
+c) [``P(Z > 0.93)``]
+d) [``P(0 \le Z \le 0.93)``]
+e) [``P(Z < -0.93)``]
+f) [``P(-0.93 \le Z \le 0.93)``]
+g) [``P(-0.93 \le Z \le 0)``]
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Step 2 — How the table works (with image)
+# -------------------------------------------------------
+Section::Begin("How this normal table works");
+BEGIN_PGML
+This table is a **cumulative (left-tail) table**. It gives:
+
+[``P(Z \le z)``]
+
+How to read it:
+- The **row** gives the first two digits of \(z\) (example: [``0.9``]).
+- The **column** gives the hundredths (example: [``0.03``]).
+- The intersection is the cumulative probability.
+
+[@ image("normal_table_0_to_1.jpg", width=>700) @]*
+
+Two facts we will use:
+- [``P(Z \le 0)=0.5``] (symmetry).
+- Since [``Z``] is continuous, [``P(Z < z)=P(Z \le z)``].
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Step 3 — Combined: parts (a) to (g)
+# -------------------------------------------------------
+Section::Begin("Compute the probabilities (use z = 0.93)");
+BEGIN_PGML
+Use the **boxed** table value for [``z=0.93``] when needed.
+
+**a)** [``P(Z < 0.93)``]
+Hint: This is a left-tail probability. Read the boxed table value.
+Answer: [____]
+
+**b)** [``P(Z \le 0.93)``]
+Hint: For a continuous normal variable, "less than" and "less than or equal to" give the same probability.
+Answer: [____]
+
+**c)** [``P(Z > 0.93)``]
+Hint: Right tail equals 1 minus the left tail.
+Answer: [____]
+
+**d)** [``P(0 \le Z \le 0.93)``]
+Hint: Compute [``P(Z \le 0.93)-P(Z \le 0)``]. Use [``P(Z \le 0)=0.5``].
+Answer: [____]
+
+**e)** [``P(Z < -0.93)``]
+Hint: Use symmetry: [``P(Z < -0.93)=P(Z > 0.93)``].
+Answer: [____]
+
+**f)** [``P(-0.93 \le Z \le 0.93)``]
+Hint: Symmetric about 0, so it is 2 times [``P(0 \le Z \le 0.93)``].
+Answer: [____]
+
+**g)** [``P(-0.93 \le Z \le 0)``]
+Hint: By symmetry, this equals [``P(0 \le Z \le 0.93)``].
+Answer: [____]
+END_PGML
+
+ANS($cmp_a, $cmp_b, $cmp_c, $cmp_d, $cmp_e, $cmp_f, $cmp_g);
+
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating) — hidden in Library Browser
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+
+ Section::Begin("Feedback");
+
+ # Any integer 1–5 should be marked correct.
+ $cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return 1;
+ }
+ );
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/NormalRandomVariables_Standard_GuidedProblem2.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/NormalRandomVariables_Standard_GuidedProblem2.pg
new file mode 100644
index 0000000000..e4fef8d348
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/NormalRandomVariables_Standard_GuidedProblem2.pg
@@ -0,0 +1,231 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Standard Normal Table (Area from 0 to z, z = 1.25) (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Normal Distribution)
+## Level(2)
+## KEYWORDS('standard normal','z table','area between 0 and z','normal table','symmetry','left tail','right tail')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser detection (LB stability)
+# ----------------------------------------------------------------
+$inLibraryBrowser = ($envir{isLibraryBrowser} || $envir{isLibrary} || 0);
+
+# =======================================================
+# Data
+# =======================================================
+Context("Numeric");
+
+# Image file (put in same folder as this .pg file)
+$TABLE_IMAGE = "normal_table_0_to_z.jpg";
+
+# This table gives the area between 0 and a positive z:
+# Boxed value for z = 1.25 is P(0 <= Z <= 1.25).
+$A_0125 = Real("0.3944");
+
+# Target answers (computed internally; do NOT display these numbers in text)
+$ans_a = Real("0.5") + $A_0125; # P(Z < 1.25)
+$ans_b = Real("0.5") + $A_0125; # P(Z <= 1.25)
+$ans_c = Real("0.5") - $A_0125; # P(Z > 1.25)
+$ans_d = $A_0125; # P(0 <= Z <= 1.25)
+$ans_e = Real("0.5") - $A_0125; # P(Z < -1.25)
+$ans_f = Real(2) * $A_0125; # P(-1.25 <= Z <= 1.25)
+$ans_g = $A_0125; # P(-1.25 <= Z <= 0)
+
+# Accept 4-decimal rounding comfortably
+$tolerance = 0.00005;
+
+# Answer evaluators + hints (ASCII in Perl strings for LB stability)
+$cmp_a = $ans_a->cmp(tolType=>"absolute", tolerance=>$tolerance)->withPostFilter(AnswerHints(
+ $ans_d->value => "Careful: this table gives area from 0 to z. To get P(Z < 1.25), add 0.5 to the boxed value."
+));
+
+$cmp_b = $ans_b->cmp(tolType=>"absolute", tolerance=>$tolerance)->withPostFilter(AnswerHints(
+ $ans_d->value => "For a continuous normal variable, '<' and '<=' give the same probability. Also add 0.5 to the boxed value."
+));
+
+$cmp_c = $ans_c->cmp(tolType=>"absolute", tolerance=>$tolerance)->withPostFilter(AnswerHints(
+ $ans_a->value => "Right tail: P(Z > 1.25) = 1 - P(Z <= 1.25)."
+));
+
+$cmp_d = $ans_d->cmp(tolType=>"absolute", tolerance=>$tolerance)->withPostFilter(AnswerHints(
+ $ans_a->value => "This one is exactly what the table provides: area from 0 to 1.25."
+));
+
+$cmp_e = $ans_e->cmp(tolType=>"absolute", tolerance=>$tolerance)->withPostFilter(AnswerHints(
+ $ans_a->value => "Use symmetry. The left tail at -1.25 equals 0.5 minus the area from 0 to 1.25."
+));
+
+$cmp_f = $ans_f->cmp(tolType=>"absolute", tolerance=>$tolerance)->withPostFilter(AnswerHints(
+ $ans_a->value => "This is the middle area from -1.25 to 1.25. Use symmetry: it is 2 times the area from 0 to 1.25."
+));
+
+$cmp_g = $ans_g->cmp(tolType=>"absolute", tolerance=>$tolerance)->withPostFilter(AnswerHints(
+ $ans_e->value => "This is the area between -1.25 and 0. By symmetry it matches the area between 0 and 1.25."
+));
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "always",
+ is_open => "always",
+ );
+} else {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ );
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+Let [``Z``] be a standard normal random variable.
+
+In this problem, the table we use gives the **area between 0 and a positive number z**.
+
+Use the table shown in the next step to find each probability.
+Round your answers to **4 decimals**.
+
+a) [``P(Z < 1.25)``]
+b) [``P(Z \le 1.25)``]
+c) [``P(Z > 1.25)``]
+d) [``P(0 \le Z \le 1.25)``]
+e) [``P(Z < -1.25)``]
+f) [``P(-1.25 \le Z \le 1.25)``]
+g) [``P(-1.25 \le Z \le 0)``]
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Step 2 — How the table works (with image)
+# -------------------------------------------------------
+Section::Begin("How this normal table works");
+BEGIN_PGML
+This table gives the area **between 0 and a positive z**:
+
+[``P(0 \le Z \le z)``] (for [``z>0``])
+
+How to read it:
+- The **row** gives the first two digits of \(z\) (example: [``1.2``]).
+- The **column** gives the hundredths (example: [``0.05``]).
+- The intersection is the area from 0 to \(z\).
+
+Make sure the image file is in the same folder as this .pg file:
+
+[@ image("normal_table_0_to_1.4.jpg", width=>700) @]*
+
+Two facts we will use:
+- [``P(Z \le 0)=0.5``] (symmetry).
+- Since [``Z``] is continuous, [``P(Z 1.25)``]
+Hint: Right tail equals 1 minus [``P(Z \le 1.25)``].
+Answer: [____]
+
+**d)** [``P(0 \le Z \le 1.25)``]
+Hint: This is exactly what the table gives (the boxed entry).
+Answer: [____]
+
+**e)** [``P(Z < -1.25)``]
+Hint: By symmetry, [``P(Z < -1.25)=0.5-P(0 \le Z \le 1.25)``].
+Answer: [____]
+
+**f)** [``P(-1.25 \le Z \le 1.25)``]
+Hint: Symmetric about 0, so it is 2 times [``P(0 \le Z \le 1.25)``].
+Answer: [____]
+
+**g)** [``P(-1.25 \le Z \le 0)``]
+Hint: By symmetry, this equals [``P(0 \le Z \le 1.25)``].
+Answer: [____]
+END_PGML
+
+ANS($cmp_a, $cmp_b, $cmp_c, $cmp_d, $cmp_e, $cmp_f, $cmp_g);
+
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating) — hidden in Library Browser
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+
+ Section::Begin("Feedback");
+
+ # Any integer 1–5 should be marked correct.
+ $cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return 1;
+ }
+ );
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/NormalRandomVariables_Standard_GuidedProblem3.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/NormalRandomVariables_Standard_GuidedProblem3.pg
new file mode 100644
index 0000000000..8371355d83
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/NormalRandomVariables_Standard_GuidedProblem3.pg
@@ -0,0 +1,283 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Standard Normal Table (Area from 0 to z): Areas Between Two Numbers (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Normal Distribution)
+## Level(2)
+## KEYWORDS('standard normal','z table','area between 0 and z','areas between two numbers','symmetry')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser detection (LB stability)
+# ----------------------------------------------------------------
+$inLibraryBrowser = ($envir{isLibraryBrowser} || $envir{isLibrary} || 0);
+
+# =======================================================
+# Data
+# =======================================================
+Context("Numeric");
+
+# Image file (put in the same folder as this .pg file)
+$TABLE_IMAGE = "normal_table_0_to_1.4_unmarked.jpg";
+
+# This table gives A(z) = P(0 <= Z <= z) for z > 0.
+# Table values needed (from the provided standard table):
+$A035 = Real("0.1368"); # A(0.35)
+$A112 = Real("0.3686"); # A(1.12)
+$A105 = Real("0.3531"); # A(1.05)
+$A149 = Real("0.4319"); # A(1.49)
+$A068 = Real("0.2517"); # A(0.68)
+$A092 = Real("0.3212"); # A(0.92)
+$A125 = Real("0.3944"); # A(1.25)
+$A040 = Real("0.1554"); # A(0.40)
+$A022 = Real("0.0871"); # A(0.22)
+$A047 = Real("0.1808"); # A(0.47)
+
+# Easy -> hard practice answers (computed internally; do NOT display these numbers)
+$ans_1 = $A112 - $A035; # P(0.35 <= Z <= 1.12)
+$ans_2 = $A149 - $A105; # P(1.05 <= Z <= 1.49)
+$ans_3 = $A068 + $A092; # P(-0.68 <= Z <= 0.92)
+$ans_4 = $A125 - $A040; # P(-1.25 <= Z <= -0.40)
+$ans_5 = $A022 + $A047; # P(-0.22 <= Z <= 0.47)
+
+# Final answer (one more "between two numbers" question)
+$ans_final = $A105 + $A149; # P(-1.05 <= Z <= 1.49)
+
+# Accept 4-decimal rounding comfortably
+$tolerance = 0.00005;
+
+$cmp_1 = $ans_1->cmp(tolType=>"absolute", tolerance=>$tolerance);
+$cmp_2 = $ans_2->cmp(tolType=>"absolute", tolerance=>$tolerance);
+$cmp_3 = $ans_3->cmp(tolType=>"absolute", tolerance=>$tolerance);
+$cmp_4 = $ans_4->cmp(tolType=>"absolute", tolerance=>$tolerance);
+$cmp_5 = $ans_5->cmp(tolType=>"absolute", tolerance=>$tolerance);
+
+$cmp_final = $ans_final->cmp(tolType=>"absolute", tolerance=>$tolerance);
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "always",
+ is_open => "always",
+ );
+} else {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ );
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+Let [``Z``] be a standard normal random variable.
+
+In this Guided Problem, the table we use gives **areas between 0 and a positive number z**.
+
+Use the table shown in the next step to find each probability.
+Round your answers to **4 decimals**.
+
+1) [``P(0.35 \le Z \le 1.12)``]
+2) [``P(1.05 \le Z \le 1.49)``]
+3) [``P(-0.68 \le Z \le 0.92)``]
+4) [``P(-1.25 \le Z \le -0.40)``]
+5) [``P(-0.22 \le Z \le 0.47)``]
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Step 2 — How the table works (with image)
+# -------------------------------------------------------
+Section::Begin("How this normal table works");
+BEGIN_PGML
+This table gives the area between 0 and a positive number \(z\):
+
+[``A(z)=P(0 \le Z \le z)``] (for [``z>0``])
+
+
+[@ image("$TABLE_IMAGE", width=>720) @]*
+
+How to use it for "between two numbers" questions:
+
+- If [``0 \le a \le b``], then
+ [``P(a \le Z \le b)=A(b)-A(a)``].
+
+- If the interval crosses 0, like [``-a \le Z \le b``] with [``a>0``] and [``b>0``], then
+ [``P(-a \le Z \le b)=A(a)+A(b)``].
+
+- If both endpoints are negative, like [``-b \le Z \le -a``] with [``0cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return 1;
+ }
+ );
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/NormalRandomVariables_Standard_GuidedProblem4.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/NormalRandomVariables_Standard_GuidedProblem4.pg
new file mode 100644
index 0000000000..183f5577cd
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/NormalRandomVariables_Standard_GuidedProblem4.pg
@@ -0,0 +1,311 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Finding Cutoffs z* from Tail Areas (Using 0-to-z Table) (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Normal Distribution)
+## Level(2)
+## KEYWORDS('standard normal','z table','cutoff','critical value','tail area','two tails','symmetry')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+ "PGcourse.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser detection (LB stability)
+# ----------------------------------------------------------------
+$inLibraryBrowser = ($envir{isLibraryBrowser} || $envir{isLibrary} || 0);
+
+# =======================================================
+# Data
+# =======================================================
+Context("Numeric");
+
+# Images (put in the same folder as this .pg file)
+$IMG_Z = "normal_z.jpg";
+$IMG_TABLE = "normal_table_0_to_2.4.jpg";
+
+# -------------------------------------------------------
+# Target cutoffs z* (students must enter z* rounded to 3 decimals)
+# If a table area is not exact, we accept the "average of two closest cutoffs".
+# -------------------------------------------------------
+$z_ex = Real("1.960"); # P(Z > z*) = 0.0250 -> A(z*) = 0.4750
+
+$z1 = Real("1.885"); # P(Z < z*) = 0.97 -> A = 0.4700 (between 1.88 and 1.89)
+$z2 = Real("2.055"); # P(Z > z*) = 0.02 -> A = 0.4800 (between 2.05 and 2.06)
+$z3 = Real("-1.405"); # P(Z < z*) = 0.08 -> A(|z|)=0.42 (between 1.40 and 1.41), then negative
+$z4 = Real("2.325"); # P(|Z| < z*) = 0.98 -> A = 0.49 (between 2.32 and 2.33)
+$z5 = Real("-1.285"); # P(Z > z*) = 0.90 -> left tail 0.10 -> A(|z|)=0.40 (between 1.28 and 1.29), then negative
+$z6 = Real("1.645"); # P(|Z| > z*) = 0.10 -> each tail 0.05 -> A = 0.45 (between 1.64 and 1.65)
+
+# Accept 3-decimal rounding
+$tolZ = 0.0005;
+
+$cmp_ex = $z_ex->cmp(tolType=>"absolute", tolerance=>$tolZ)->withPostFilter(AnswerHints(
+ 1.64 => "Be careful: that is for tail 0.05, not 0.025.",
+ 1.96 => "Good. This matches the table area A(z*) = 0.4750."
+));
+
+$cmp_1 = $z1->cmp(tolType=>"absolute", tolerance=>$tolZ)->withPostFilter(AnswerHints(
+ 1.96 => "0.97 is not the same as 0.975. Convert to A(z) = 0.97 - 0.5 first."
+));
+
+$cmp_2 = $z2->cmp(tolType=>"absolute", tolerance=>$tolZ)->withPostFilter(AnswerHints(
+ 2.33 => "This is too far in the tail. First convert to left tail: 1 - 0.02 = 0.98, then A(z) = 0.48."
+));
+
+$cmp_3 = $z3->cmp(tolType=>"absolute", tolerance=>$tolZ)->withPostFilter(AnswerHints(
+ -1.28 => "You are close, but use A(z) = 0.5 - 0.08 = 0.42 and then average the two closest cutoffs."
+));
+
+$cmp_4 = $z4->cmp(tolType=>"absolute", tolerance=>$tolZ)->withPostFilter(AnswerHints(
+ 1.96 => "This is the cutoff for two tails total 0.05 (middle 0.95). Here the middle is 0.98, so z* is larger."
+));
+
+$cmp_5 = $z5->cmp(tolType=>"absolute", tolerance=>$tolZ)->withPostFilter(AnswerHints(
+ 1.28 => "The cutoff must be negative because the right tail is 0.90 (most of the area is to the right)."
+));
+
+$cmp_6 = $z6->cmp(tolType=>"absolute", tolerance=>$tolZ)->withPostFilter(AnswerHints(
+ 1.96 => "Two tails total 0.10 means each tail is 0.05, not 0.025."
+));
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "always",
+ is_open => "always",
+ );
+} else {
+ Scaffold::Begin(
+ numbered => 1,
+ can_open => "when_previous_correct",
+ is_open => "correct_or_first_incorrect",
+ );
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement (includes the goal)
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+**Goal:** Work backward to find a cutoff value [``z^*``] on the standard normal curve.
+
+You will be given a probability (left tail, right tail, or both tails), and your job is to find the value [``z^*``] that makes that probability true.
+
+Important: the table we use does **not** give [``P(Z \le z)``].
+It gives the area between 0 and a positive number:
+
+[``A(z)=P(0 \le Z \le z)``] for [``z>0``].
+
+If an exact area is not in the table, use the **two closest table areas** and take the **average of the two cutoffs** (then round to 3 decimals).
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Step 2 — The table we use
+# -------------------------------------------------------
+Section::Begin("The table we use (area from 0 to z)");
+BEGIN_PGML
+
+[@ image("$IMG_TABLE", width=>760) @]*
+
+This table gives [``A(z)=P(0 \le Z \le z)``] for [``z>0``].
+
+In every situation you should figure out what [``A(z)``] is. Then, find [``z``] from the table margins. Finally, you will find [``z^*``] based on [``z``]. See the next step for a worked example.
+
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Step 3 — Worked example (z* = 1.96)
+# -------------------------------------------------------
+Section::Begin("Worked example (z* = 1.96)");
+BEGIN_PGML
+Here is the picture for a right-tail area of [``0.0250``]:
+
+[@ image("$IMG_Z", width=>760) @]*
+
+This means:
+
+[``P(Z>z^*)=0.0250``].
+
+To use the table, convert to an area from 0 to a positive number:
+
+[``A(z) = 0.5 - 0.0250 = 0.4750``].
+
+Now look for [``0.4750``] in the table to get [``z``]. In this case [``z^*=z``]
+
+Enter [``z^*``] (round to 3 decimals): [____]
+END_PGML
+ANS($cmp_ex);
+Section::End();
+
+# -------------------------------------------------------
+# Practice 1 (easy): left tail 0.97
+# -------------------------------------------------------
+Section::Begin("Practice 1");
+BEGIN_PGML
+Find [``z^*``] if:
+
+[``P(Z0.5``], convert to table area: [``A(z)=0.97-0.5``].
+If it is not exact in the table, average the two closest cutoffs.
+
+Enter [``z^*``] (round to 3 decimals): [____]
+END_PGML
+ANS($cmp_1);
+Section::End();
+
+# -------------------------------------------------------
+# Practice 2: right tail 0.02
+# -------------------------------------------------------
+Section::Begin("Practice 2");
+BEGIN_PGML
+Find [``z^*``] if:
+
+[``P(Z>z^*)=0.02``].
+
+Hint: Since the right tail is [``0.02<0.5``], then [``A(z)=0.5-0.02``].
+If it is not exact in the table, average the two closest cutoffs.
+
+Enter [``z^*``] (round to 3 decimals): [____]
+END_PGML
+ANS($cmp_2);
+Section::End();
+
+# -------------------------------------------------------
+# Practice 3: left tail small (negative cutoff)
+# -------------------------------------------------------
+Section::Begin("Practice 3");
+BEGIN_PGML
+Find [``z^*``] if:
+
+[``P(Zz^*)=0.90``].
+
+Hint: A right-tail probability of 0.90 means the cutoff is **negative**.
+Convert to left tail:
+[``P(Zz^*)=0.10``].
+
+Hint: Split into two equal tails: each tail is [``0.10/2``].
+Then the area from 0 to [``z``] is:
+[``A(z)=0.5-(0.10/2)``].
+If it is not exact in the table, average the two closest cutoffs.
+
+Enter [``z^*``] (round to 3 decimals): [____]
+END_PGML
+ANS($cmp_6);
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating) — hidden in Library Browser
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+
+ Section::Begin("Feedback");
+
+ $cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return 1;
+ }
+ );
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/non_st_to_st.jpg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/non_st_to_st.jpg
new file mode 100644
index 0000000000..82fbbac1da
Binary files /dev/null and b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/non_st_to_st.jpg differ
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/normal_table_0_to_1.4.jpg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/normal_table_0_to_1.4.jpg
new file mode 100644
index 0000000000..73ceb85947
Binary files /dev/null and b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/normal_table_0_to_1.4.jpg differ
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/normal_table_0_to_1.4_unmarked.jpg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/normal_table_0_to_1.4_unmarked.jpg
new file mode 100644
index 0000000000..20ead88b20
Binary files /dev/null and b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/normal_table_0_to_1.4_unmarked.jpg differ
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/normal_table_0_to_1.jpg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/normal_table_0_to_1.jpg
new file mode 100644
index 0000000000..a7c63966da
Binary files /dev/null and b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/normal_table_0_to_1.jpg differ
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/normal_table_0_to_2.4.jpg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/normal_table_0_to_2.4.jpg
new file mode 100644
index 0000000000..63af6136a4
Binary files /dev/null and b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/normal_table_0_to_2.4.jpg differ
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/normal_z.jpg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/normal_z.jpg
new file mode 100644
index 0000000000..acbeb799ec
Binary files /dev/null and b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/NormalRandomVariables/normal_z.jpg differ
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/SamplingDistributions/SamplingDistributions_Mean_GuidedProblem1.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/SamplingDistributions/SamplingDistributions_Mean_GuidedProblem1.pg
new file mode 100644
index 0000000000..9d5484ce48
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/SamplingDistributions/SamplingDistributions_Mean_GuidedProblem1.pg
@@ -0,0 +1,475 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Sampling Distributions: Work Tables for X and X-bar (4-Sided Die, n=2) (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Sampling Distributions)
+## Level(2)
+## KEYWORDS('sampling distribution','sample mean','work table','expected value','variance','standard deviation','die')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser detection (LB stability)
+# ----------------------------------------------------------------
+$inLibraryBrowser = ($envir{isLibraryBrowser} || $envir{isLibrary} || 0);
+
+Context("Numeric");
+
+# =======================================================
+# Postfilter: add a hint ONLY when the answer is wrong
+# (avoids AnswerHints(".*" => ...) issues on some servers)
+# =======================================================
+sub HintIfWrong {
+ my $msg = shift;
+ return sub {
+ my $ans = shift;
+ if (defined($ans->{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+ return $ans;
+ };
+}
+
+# =======================================================
+# Correct values (internal)
+# =======================================================
+
+# For X = one roll of a fair 4-sided die
+$EX = Compute("5/2");
+$EX2 = Compute("15/2");
+$VarX = Compute("5/4");
+$SigX = Real(sqrt(5)/2);
+
+# For Xbar with n=2: Xbar = (X1+X2)/2
+$EXb = $EX;
+$EXb2 = Compute("55/8");
+$VarXb = Compute("5/8");
+$SigXb = Real(sqrt(5/8));
+
+# Formula checks (n=2)
+$SigXb_formula = Real($SigX->value / sqrt(2));
+
+# n=3 prediction
+$EXb_n3 = $EX;
+$SigXb_n3 = Real($SigX->value / sqrt(3));
+
+# =======================================================
+# HTML: sample space table (4x4) for (X1, X2) and X-bar
+# (no answer blanks here)
+# =======================================================
+$samp = ''
+. ''
+. ''
+. '| | '
+. '\(X_2=1\) | '
+. '\(X_2=2\) | '
+. '\(X_2=3\) | '
+. '\(X_2=4\) | '
+. '
'
+. ''
+. '| \(X_1=1\) | '
+. '\(1.0\) | \(1.5\) | \(2.0\) | \(2.5\) | '
+. '
'
+. ''
+. '| \(X_1=2\) | '
+. '\(1.5\) | \(2.0\) | \(2.5\) | \(3.0\) | '
+. '
'
+. ''
+. '| \(X_1=3\) | '
+. '\(2.0\) | \(2.5\) | \(3.0\) | \(3.5\) | '
+. '
'
+. ''
+. '| \(X_1=4\) | '
+. '\(2.5\) | \(3.0\) | \(3.5\) | \(4.0\) | '
+. '
'
+. '
';
+
+# =======================================================
+# Build tables RIGHT BEFORE they are displayed
+# (prevents answer-blank numbering from getting out of order)
+# =======================================================
+sub make_tblX {
+ return ''
+ . ''
+ . ''
+ . '| \(x\) | '
+ . '\(P(X=x)\) | '
+ . '\(x\,P(X=x)\) | '
+ . '\(x^2\,P(X=x)\) | '
+ . '
'
+ . ''
+ . '| '.ans_rule(6).' | '
+ . ''.ans_rule(6).' | '
+ . ''.ans_rule(8).' | '
+ . ''.ans_rule(8).' | '
+ . '
'
+ . ''
+ . '| '.ans_rule(6).' | '
+ . ''.ans_rule(6).' | '
+ . ''.ans_rule(8).' | '
+ . ''.ans_rule(8).' | '
+ . '
'
+ . ''
+ . '| '.ans_rule(6).' | '
+ . ''.ans_rule(6).' | '
+ . ''.ans_rule(8).' | '
+ . ''.ans_rule(8).' | '
+ . '
'
+ . ''
+ . '| '.ans_rule(6).' | '
+ . ''.ans_rule(6).' | '
+ . ''.ans_rule(8).' | '
+ . ''.ans_rule(8).' | '
+ . '
'
+ . ''
+ . '| Totals | '
+ . ' | '
+ . ''.ans_rule(8).' (this total is \(E(X)\)) | '
+ . ''.ans_rule(8).' (this total is \(E(X^2)\)) | '
+ . '
'
+ . '
';
+}
+
+sub make_tblXbar {
+ return ''
+ . ''
+ . ''
+ . '| \(\bar{x}\) | '
+ . '\(P(\bar{X}=\bar{x})\) | '
+ . '\(\bar{x}\,P(\bar{X}=\bar{x})\) | '
+ . '\((\bar{x})^2\,P(\bar{X}=\bar{x})\) | '
+ . '
'
+ . '| '.ans_rule(6).' | '.ans_rule(6).' | '.ans_rule(8).' | '.ans_rule(8).' |
'
+ . '| '.ans_rule(6).' | '.ans_rule(6).' | '.ans_rule(8).' | '.ans_rule(8).' |
'
+ . '| '.ans_rule(6).' | '.ans_rule(6).' | '.ans_rule(8).' | '.ans_rule(8).' |
'
+ . '| '.ans_rule(6).' | '.ans_rule(6).' | '.ans_rule(8).' | '.ans_rule(8).' |
'
+ . '| '.ans_rule(6).' | '.ans_rule(6).' | '.ans_rule(8).' | '.ans_rule(8).' |
'
+ . '| '.ans_rule(6).' | '.ans_rule(6).' | '.ans_rule(8).' | '.ans_rule(8).' |
'
+ . '| '.ans_rule(6).' | '.ans_rule(6).' | '.ans_rule(8).' | '.ans_rule(8).' |
'
+ . ''
+ . '| Totals | '
+ . ' | '
+ . ''.ans_rule(8).' (this total is \(E(\bar{X})\)) | '
+ . ''.ans_rule(8).' (this total is \(E((\bar{X})^2)\)) | '
+ . '
'
+ . '
';
+}
+
+# =======================================================
+# Tolerances (students round to 3 decimals throughout)
+# =======================================================
+$tol = 0.0006;
+
+# =======================================================
+# X table correct entries (20 evaluators)
+# =======================================================
+$cmp_x_r1_x = Compute("1")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_x_r1_p = Compute("1/4")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_x_r1_c3 = Compute("1/4")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_x_r1_c4 = Compute("1/4")->cmp(tolType=>"absolute", tolerance=>$tol);
+
+$cmp_x_r2_x = Compute("2")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_x_r2_p = Compute("1/4")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_x_r2_c3 = Compute("1/2")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_x_r2_c4 = Compute("1")->cmp(tolType=>"absolute", tolerance=>$tol);
+
+$cmp_x_r3_x = Compute("3")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_x_r3_p = Compute("1/4")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_x_r3_c3 = Compute("3/4")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_x_r3_c4 = Compute("9/4")->cmp(tolType=>"absolute", tolerance=>$tol);
+
+$cmp_x_r4_x = Compute("4")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_x_r4_p = Compute("1/4")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_x_r4_c3 = Compute("1")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_x_r4_c4 = Compute("4")->cmp(tolType=>"absolute", tolerance=>$tol);
+
+$cmp_x_tot_c3 = $EX->cmp(tolType=>"absolute", tolerance=>$tolanc86h3=tol)->withPostFilter(HintIfWrong("Add column 3. That total is E(X)."));
+$cmp_x_tot_c4 = $EX2->cmp(tolType=>"absolute", tolerance=>$tol)->withPostFilter(HintIfWrong("Add column 4. That total is E(X^2)."));
+$cmp_x_var = $VarX->cmp(tolType=>"absolute", tolerance=>$tol)->withPostFilter(HintIfWrong("Use Var(X)=E(X^2)-[E(X)]^2."));
+$cmp_x_sd = $SigX->cmp(tolType=>"absolute", tolerance=>$tol)->withPostFilter(HintIfWrong("Standard deviation is sqrt(Var)."));
+
+# =======================================================
+# Xbar table correct entries (32 evaluators)
+# =======================================================
+$cmp_b_r1_x = Compute("1")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r1_p = Compute("1/16")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r1_c3 = Compute("1/16")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r1_c4 = Compute("1/16")->cmp(tolType=>"absolute", tolerance=>$tol);
+
+$cmp_b_r2_x = Compute("3/2")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r2_p = Compute("2/16")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r2_c3 = Compute("3/16")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r2_c4 = Compute("9/32")->cmp(tolType=>"absolute", tolerance=>$tol);
+
+$cmp_b_r3_x = Compute("2")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r3_p = Compute("3/16")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r3_c3 = Compute("3/8")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r3_c4 = Compute("3/4")->cmp(tolType=>"absolute", tolerance=>$tol);
+
+$cmp_b_r4_x = Compute("5/2")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r4_p = Compute("4/16")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r4_c3 = Compute("5/8")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r4_c4 = Compute("25/16")->cmp(tolType=>"absolute", tolerance=>$tol);
+
+$cmp_b_r5_x = Compute("3")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r5_p = Compute("3/16")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r5_c3 = Compute("9/16")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r5_c4 = Compute("27/16")->cmp(tolType=>"absolute", tolerance=>$tol);
+
+$cmp_b_r6_x = Compute("7/2")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r6_p = Compute("2/16")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r6_c3 = Compute("7/16")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r6_c4 = Compute("49/32")->cmp(tolType=>"absolute", tolerance=>$tol);
+
+$cmp_b_r7_x = Compute("4")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r7_p = Compute("1/16")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r7_c3 = Compute("1/4")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r7_c4 = Compute("1")->cmp(tolType=>"absolute", tolerance=>$tol);
+
+$cmp_b_tot_c3 = $EXb->cmp(tolType=>"absolute", tolerance=>$tol)->withPostFilter(HintIfWrong("Add column 3. That total is E(X-bar)."));
+$cmp_b_tot_c4 = $EXb2->cmp(tolType=>"absolute", tolerance=>$tol)->withPostFilter(HintIfWrong("Add column 4. That total is E((X-bar)^2)."));
+$cmp_b_var = $VarXb->cmp(tolType=>"absolute", tolerance=>$tol)->withPostFilter(HintIfWrong("Use Var(X-bar)=E((X-bar)^2)-[E(X-bar)]^2."));
+$cmp_b_sd = $SigXb->cmp(tolType=>"absolute", tolerance=>$tol)->withPostFilter(HintIfWrong("Standard deviation is sqrt(Var)."));
+
+# =======================================================
+# Verify formulas (n=2)
+# =======================================================
+$cmp_verify_mu = $EX->cmp(tolType=>"absolute", tolerance=>$tol)->withPostFilter(HintIfWrong("The sample mean has the same mean as the population mean."));
+$cmp_verify_sig2 = $SigXb_formula->cmp(tolType=>"absolute", tolerance=>$tol)->withPostFilter(HintIfWrong("For n=2, divide the population SD by sqrt(2)."));
+
+# =======================================================
+# n=3
+# =======================================================
+$cmp_n3_mu = $EXb_n3->cmp(tolType=>"absolute", tolerance=>$tol)->withPostFilter(HintIfWrong("The sample mean has the same mean as the population mean."));
+$cmp_n3_sig = $SigXb_n3->cmp(tolType=>"absolute", tolerance=>$tol)->withPostFilter(HintIfWrong("For n=3, divide the population SD by sqrt(3)."));
+
+# =======================================================
+# Rating checker
+# =======================================================
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(numbered=>1, can_open=>"always", is_open=>"always");
+} else {
+ Scaffold::Begin(numbered=>1, can_open=>"when_previous_correct", is_open=>"correct_or_first_incorrect");
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A fair 4-sided die has outcomes [``1,2,3,4``]. Let [``X``] be the result of one roll.
+
+Now roll the die twice. Call the two results [``X_1``] and [``X_2``]. The sample mean for a sample of size [``n=2``] is:
+
+[``\bar X = (X_1+X_2)/2``]
+
+Why is [``\bar X``] a random variable?
+Because [``X_1``] and [``X_2``] are random, so the average changes from sample to sample.
+
+Why do we care about the probability distribution of [``\bar X``]?
+In statistics, we use [``\bar X``] to estimate a population mean. To understand how reliable that estimate is, we study the distribution of [``\bar X``], especially its mean and standard deviation.
+
+Big idea: [``\bar X``] has the same center as [``X``] and tends to be less variable than [``X``]. The spread shrinks as [``n``] grows.
+
+In this Guided Problem, you will compute the mean and standard deviation of both [``X``] and [``\bar X``] directly using work tables, then verify the general formulas.
+
+Rounding: Round all answers to 3 decimals.
+END_PGML
+Section::End();
+
+# Build X table NOW (so its blanks are created in the correct order)
+$tblX = make_tblX();
+
+# -------------------------------------------------------
+# Step 2 — Work table for X
+# -------------------------------------------------------
+Section::Begin("Work table for X");
+BEGIN_PGML
+Fill the table row-by-row (all numeric cells).
+
+- Column 3 is [``x\,P(X=x)``]
+- Column 4 is [``x^2\,P(X=x)``]
+
+Then add columns 3 and 4 to get [``E(X)``] and [``E(X^2)``].
+
+[@ $tblX @]*
+
+Now compute:
+- [``\mathrm{Var}(X)=E(X^2)-[E(X)]^2``]
+- [``\sigma_X=\sqrt{\mathrm{Var}(X)}``]
+
+Enter [``\mathrm{Var}(X)``]: [____]
+Enter [``\sigma_X``]: [____]
+END_PGML
+
+ANS(
+ # row 1
+ $cmp_x_r1_x, $cmp_x_r1_p, $cmp_x_r1_c3, $cmp_x_r1_c4,
+ # row 2
+ $cmp_x_r2_x, $cmp_x_r2_p, $cmp_x_r2_c3, $cmp_x_r2_c4,
+ # row 3
+ $cmp_x_r3_x, $cmp_x_r3_p, $cmp_x_r3_c3, $cmp_x_r3_c4,
+ # row 4
+ $cmp_x_r4_x, $cmp_x_r4_p, $cmp_x_r4_c3, $cmp_x_r4_c4,
+ # totals
+ $cmp_x_tot_c3, $cmp_x_tot_c4,
+ # var, sd
+ $cmp_x_var, $cmp_x_sd
+);
+
+Section::End();
+
+# Build Xbar table NOW (so its blanks come AFTER Section B blanks)
+$tblXbar = make_tblXbar();
+
+# -------------------------------------------------------
+# Step 3 — Sample space + work table for X-bar (n=2)
+# -------------------------------------------------------
+Section::Begin("Work table for X-bar (n=2)");
+BEGIN_PGML
+For [``n=2``], the sample mean is [``\bar X=(X_1+X_2)/2``].
+
+**Sample space table (each cell shows** [``\bar X``] **for that ordered pair** [``(X_1,X_2)``]**):**
+
+[@ $samp @]*
+
+Now use that sample space to build the probability distribution of [``\bar X``] and fill the work table below (all numeric cells).
+
+[@ $tblXbar @]*
+
+Now compute:
+- [``\mathrm{Var}(\bar X)=E((\bar X)^2)-[E(\bar X)]^2``]
+- [``\sigma_{\bar X}=\sqrt{\mathrm{Var}(\bar X)}``]
+
+Enter [``\mathrm{Var}(\bar X)``]: [____]
+Enter [``\sigma_{\bar X}``]: [____]
+END_PGML
+
+ANS(
+ # row 1
+ $cmp_b_r1_x, $cmp_b_r1_p, $cmp_b_r1_c3, $cmp_b_r1_c4,
+ # row 2
+ $cmp_b_r2_x, $cmp_b_r2_p, $cmp_b_r2_c3, $cmp_b_r2_c4,
+ # row 3
+ $cmp_b_r3_x, $cmp_b_r3_p, $cmp_b_r3_c3, $cmp_b_r3_c4,
+ # row 4
+ $cmp_b_r4_x, $cmp_b_r4_p, $cmp_b_r4_c3, $cmp_b_r4_c4,
+ # row 5
+ $cmp_b_r5_x, $cmp_b_r5_p, $cmp_b_r5_c3, $cmp_b_r5_c4,
+ # row 6
+ $cmp_b_r6_x, $cmp_b_r6_p, $cmp_b_r6_c3, $cmp_b_r6_c4,
+ # row 7
+ $cmp_b_r7_x, $cmp_b_r7_p, $cmp_b_r7_c3, $cmp_b_r7_c4,
+ # totals
+ $cmp_b_tot_c3, $cmp_b_tot_c4,
+ # var, sd
+ $cmp_b_var, $cmp_b_sd
+);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 4 — Main concept + verify formulas (n=2)
+# -------------------------------------------------------
+Section::Begin("Main concept: verify the formulas");
+BEGIN_PGML
+For random samples of size [``n``] from a population with mean [``\mu``] and standard deviation [``\sigma``], the sample mean [``\bar X``] satisfies:
+
+- [``\mu_{\bar X}=\mu``]
+- [``\sigma_{\bar X}=\sigma/\sqrt{n}``]
+
+Use your results from the work tables to verify these for [``n=2``]:
+
+1) Enter [``\mu_{\bar X}``] (it should match [``\mu``]): [____]
+
+2) Compute [``\sigma/\sqrt{2}``] and enter it (it should match your [``\sigma_{\bar X}``]): [____]
+END_PGML
+
+ANS($cmp_verify_mu, $cmp_verify_sig2);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 5 — What if n=3?
+# -------------------------------------------------------
+Section::Begin("What if n=3?");
+BEGIN_PGML
+Now imagine you roll the fair 4-sided die three times and compute the sample mean [``\bar X``] for [``n=3``].
+
+Use the formulas:
+
+- [``\mu_{\bar X}=\mu``]
+- [``\sigma_{\bar X}=\sigma/\sqrt{3}``]
+
+Enter [``\mu_{\bar X}``] for [``n=3``]: [____]
+Enter [``\sigma_{\bar X}``] for [``n=3``]: [____]
+
+Note: bigger sample size means smaller variability in [``\bar X``].
+END_PGML
+
+ANS($cmp_n3_mu, $cmp_n3_sig);
+
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating) — hidden in Library Browser
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+
+ Section::Begin("Feedback");
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/SamplingDistributions/SamplingDistributions_Mean_GuidedProblem2.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/SamplingDistributions/SamplingDistributions_Mean_GuidedProblem2.pg
new file mode 100644
index 0000000000..47490d55ba
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/SamplingDistributions/SamplingDistributions_Mean_GuidedProblem2.pg
@@ -0,0 +1,505 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Sampling Distributions: Work Tables for X and X-bar (Children per Family, n=2) (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Sampling Distributions)
+## Level(2)
+## KEYWORDS('sampling distribution','sample mean','work table','expected value','variance','standard deviation','discrete distribution')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser detection (LB stability)
+# ----------------------------------------------------------------
+$inLibraryBrowser = ($envir{isLibraryBrowser} || $envir{isLibrary} || 0);
+
+Context("Numeric");
+
+# =======================================================
+# Postfilter: add a hint ONLY when the answer is wrong
+# (avoids AnswerHints(".*" => ...) issues on some servers)
+# =======================================================
+sub HintIfWrong {
+ my $msg = shift;
+ return sub {
+ my $ans = shift;
+ if (defined($ans->{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+ return $ans;
+ };
+}
+
+# =======================================================
+# Population distribution for X (children per family)
+# X in {0,1,2,3} with probabilities 0.2, 0.5, 0.2, 0.1
+# =======================================================
+$p0 = Compute("0.2");
+$p1 = Compute("0.5");
+$p2 = Compute("0.2");
+$p3 = Compute("0.1");
+
+# =======================================================
+# Correct values (internal)
+# =======================================================
+# For X
+$EX = Compute("6/5"); # 1.2
+$EX2 = Compute("11/5"); # 2.2
+$VarX = Compute("19/25"); # 0.76
+$SigX = Real(sqrt(19)/5);
+
+# For Xbar with n=2: Xbar = (X1+X2)/2
+$EXb = $EX;
+$EXb2 = Compute("91/50"); # 1.82
+$VarXb = Compute("19/50"); # 0.38
+$SigXb = Real(sqrt(19/50));
+
+# Formula checks (n=2)
+$SigXb_formula = Real($SigX->value / sqrt(2));
+
+# n=3 prediction
+$EXb_n3 = $EX;
+$SigXb_n3 = Real($SigX->value / sqrt(3));
+
+# =======================================================
+# HTML: sample space table (4x4) for (X1, X2) and X-bar
+# (no answer blanks here)
+# =======================================================
+$samp = ''
+. ''
+. ''
+. '| | '
+. '\(X_2=0\) | '
+. '\(X_2=1\) | '
+. '\(X_2=2\) | '
+. '\(X_2=3\) | '
+. '
'
+. ''
+. '| \(X_1=0\) | '
+. '\(0.0\) | \(0.5\) | \(1.0\) | \(1.5\) | '
+. '
'
+. ''
+. '| \(X_1=1\) | '
+. '\(0.5\) | \(1.0\) | \(1.5\) | \(2.0\) | '
+. '
'
+. ''
+. '| \(X_1=2\) | '
+. '\(1.0\) | \(1.5\) | \(2.0\) | \(2.5\) | '
+. '
'
+. ''
+. '| \(X_1=3\) | '
+. '\(1.5\) | \(2.0\) | \(2.5\) | \(3.0\) | '
+. '
'
+. '
';
+
+# =======================================================
+# IMPORTANT FIX
+# Build tables ONLY right before the section that displays them.
+# Do NOT build $tblXbar in the preamble (it creates answer blanks early
+# and shifts the answer list, causing the “many incorrect rows” symptom).
+# =======================================================
+sub make_tblX {
+ return ''
+ . ''
+ . ''
+ . '| \(x\) | '
+ . '\(P(X=x)\) | '
+ . '\(x\,P(X=x)\) | '
+ . '\(x^2\,P(X=x)\) | '
+ . '
'
+ . ''
+ . '| '.ans_rule(6).' | '
+ . ''.ans_rule(6).' | '
+ . ''.ans_rule(8).' | '
+ . ''.ans_rule(8).' | '
+ . '
'
+ . ''
+ . '| '.ans_rule(6).' | '
+ . ''.ans_rule(6).' | '
+ . ''.ans_rule(8).' | '
+ . ''.ans_rule(8).' | '
+ . '
'
+ . ''
+ . '| '.ans_rule(6).' | '
+ . ''.ans_rule(6).' | '
+ . ''.ans_rule(8).' | '
+ . ''.ans_rule(8).' | '
+ . '
'
+ . ''
+ . '| '.ans_rule(6).' | '
+ . ''.ans_rule(6).' | '
+ . ''.ans_rule(8).' | '
+ . ''.ans_rule(8).' | '
+ . '
'
+ . ''
+ . '| Totals | '
+ . ' | '
+ . ''.ans_rule(8).' (this total is \(E(X)\)) | '
+ . ''.ans_rule(8).' (this total is \(E(X^2)\)) | '
+ . '
'
+ . '
';
+}
+
+sub make_tblXbar {
+ return ''
+ . ''
+ . ''
+ . '| \(\bar{x}\) | '
+ . '\(P(\bar{X}=\bar{x})\) | '
+ . '\(\bar{x}\,P(\bar{X}=\bar{x})\) | '
+ . '\((\bar{x})^2\,P(\bar{X}=\bar{x})\) | '
+ . '
'
+ . '| '.ans_rule(6).' | '.ans_rule(6).' | '.ans_rule(8).' | '.ans_rule(8).' |
'
+ . '| '.ans_rule(6).' | '.ans_rule(6).' | '.ans_rule(8).' | '.ans_rule(8).' |
'
+ . '| '.ans_rule(6).' | '.ans_rule(6).' | '.ans_rule(8).' | '.ans_rule(8).' |
'
+ . '| '.ans_rule(6).' | '.ans_rule(6).' | '.ans_rule(8).' | '.ans_rule(8).' |
'
+ . '| '.ans_rule(6).' | '.ans_rule(6).' | '.ans_rule(8).' | '.ans_rule(8).' |
'
+ . '| '.ans_rule(6).' | '.ans_rule(6).' | '.ans_rule(8).' | '.ans_rule(8).' |
'
+ . '| '.ans_rule(6).' | '.ans_rule(6).' | '.ans_rule(8).' | '.ans_rule(8).' |
'
+ . ''
+ . '| Totals | '
+ . ' | '
+ . ''.ans_rule(8).' (this total is \(E(\bar{X})\)) | '
+ . ''.ans_rule(8).' (this total is \(E((\bar{X})^2)\)) | '
+ . '
'
+ . '
';
+}
+
+# =======================================================
+# Tolerances (students round to 3 decimals throughout)
+# =======================================================
+$tol = 0.0006;
+
+# =======================================================
+# X table correct entries (20 evaluators)
+# =======================================================
+$cmp_x_r1_x = Compute("0")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_x_r1_p = Compute("1/5")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_x_r1_c3 = Compute("0")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_x_r1_c4 = Compute("0")->cmp(tolType=>"absolute", tolerance=>$tol);
+
+$cmp_x_r2_x = Compute("1")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_x_r2_p = Compute("1/2")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_x_r2_c3 = Compute("1/2")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_x_r2_c4 = Compute("1/2")->cmp(tolType=>"absolute", tolerance=>$tol);
+
+$cmp_x_r3_x = Compute("2")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_x_r3_p = Compute("1/5")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_x_r3_c3 = Compute("2/5")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_x_r3_c4 = Compute("4/5")->cmp(tolType=>"absolute", tolerance=>$tol);
+
+$cmp_x_r4_x = Compute("3")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_x_r4_p = Compute("1/10")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_x_r4_c3 = Compute("3/10")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_x_r4_c4 = Compute("9/10")->cmp(tolType=>"absolute", tolerance=>$tol);
+
+$cmp_x_tot_c3 = $EX->cmp(tolType=>"absolute", tolerance=>$tol)
+ ->withPostFilter(HintIfWrong("Add column 3. That total is E(X)."));
+$cmp_x_tot_c4 = $EX2->cmp(tolType=>"absolute", tolerance=>$tol)
+ ->withPostFilter(HintIfWrong("Add column 4. That total is E(X^2)."));
+$cmp_x_var = $VarX->cmp(tolType=>"absolute", tolerance=>$tol)
+ ->withPostFilter(HintIfWrong("Use Var(X)=E(X^2)-[E(X)]^2."));
+$cmp_x_sd = $SigX->cmp(tolType=>"absolute", tolerance=>$tol)
+ ->withPostFilter(HintIfWrong("Standard deviation is sqrt(Var)."));
+
+# =======================================================
+# Xbar table correct entries (32 evaluators)
+# Values: 0, 0.5, 1, 1.5, 2, 2.5, 3
+# Probabilities: 0.04, 0.20, 0.33, 0.24, 0.14, 0.04, 0.01
+# =======================================================
+$cmp_b_r1_x = Compute("0")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r1_p = Compute("1/25")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r1_c3 = Compute("0")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r1_c4 = Compute("0")->cmp(tolType=>"absolute", tolerance=>$tol);
+
+$cmp_b_r2_x = Compute("1/2")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r2_p = Compute("1/5")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r2_c3 = Compute("1/10")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r2_c4 = Compute("1/20")->cmp(tolType=>"absolute", tolerance=>$tol);
+
+$cmp_b_r3_x = Compute("1")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r3_p = Compute("33/100")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r3_c3 = Compute("33/100")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r3_c4 = Compute("33/100")->cmp(tolType=>"absolute", tolerance=>$tol);
+
+$cmp_b_r4_x = Compute("3/2")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r4_p = Compute("6/25")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r4_c3 = Compute("9/25")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r4_c4 = Compute("27/50")->cmp(tolType=>"absolute", tolerance=>$tol);
+
+$cmp_b_r5_x = Compute("2")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r5_p = Compute("7/50")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r5_c3 = Compute("7/25")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r5_c4 = Compute("14/25")->cmp(tolType=>"absolute", tolerance=>$tol);
+
+$cmp_b_r6_x = Compute("5/2")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r6_p = Compute("1/25")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r6_c3 = Compute("1/10")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r6_c4 = Compute("1/4")->cmp(tolType=>"absolute", tolerance=>$tol);
+
+$cmp_b_r7_x = Compute("3")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r7_p = Compute("1/100")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r7_c3 = Compute("3/100")->cmp(tolType=>"absolute", tolerance=>$tol);
+$cmp_b_r7_c4 = Compute("9/100")->cmp(tolType=>"absolute", tolerance=>$tol);
+
+$cmp_b_tot_c3 = $EXb->cmp(tolType=>"absolute", tolerance=>$tol)
+ ->withPostFilter(HintIfWrong("Add column 3. That total is E(X-bar)."));
+$cmp_b_tot_c4 = $EXb2->cmp(tolType=>"absolute", tolerance=>$tol)
+ ->withPostFilter(HintIfWrong("Add column 4. That total is E((X-bar)^2)."));
+$cmp_b_var = $VarXb->cmp(tolType=>"absolute", tolerance=>$tol)
+ ->withPostFilter(HintIfWrong("Use Var(X-bar)=E((X-bar)^2)-[E(X-bar)]^2."));
+$cmp_b_sd = $SigXb->cmp(tolType=>"absolute", tolerance=>$tol)
+ ->withPostFilter(HintIfWrong("Standard deviation is sqrt(Var)."));
+
+# =======================================================
+# Verify formulas (n=2)
+# =======================================================
+$cmp_verify_mu = $EX->cmp(tolType=>"absolute", tolerance=>$tol)
+ ->withPostFilter(HintIfWrong("The sample mean has the same mean as the population mean."));
+$cmp_verify_sig2 = $SigXb_formula->cmp(tolType=>"absolute", tolerance=>$tol)
+ ->withPostFilter(HintIfWrong("For n=2, divide the population SD by sqrt(2)."));
+
+# =======================================================
+# n=3
+# =======================================================
+$cmp_n3_mu = $EXb_n3->cmp(tolType=>"absolute", tolerance=>$tol)
+ ->withPostFilter(HintIfWrong("The sample mean has the same mean as the population mean."));
+$cmp_n3_sig = $SigXb_n3->cmp(tolType=>"absolute", tolerance=>$tol)
+ ->withPostFilter(HintIfWrong("For n=3, divide the population SD by sqrt(3)."));
+
+# =======================================================
+# Rating checker
+# =======================================================
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(numbered=>1, can_open=>"always", is_open=>"always");
+} else {
+ Scaffold::Begin(numbered=>1, can_open=>"when_previous_correct", is_open=>"correct_or_first_incorrect");
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+Let [``X``] be the number of children per family in a certain population. Assume:
+
+- [``P(X=0)=0.2``]
+- [``P(X=1)=0.5``]
+- [``P(X=2)=0.2``]
+- [``P(X=3)=0.1``]
+
+Now take a random sample of size [``n=2``] from this population. Call the two values [``X_1``] and [``X_2``]. The sample mean is:
+
+[``\bar X = (X_1+X_2)/2``]
+
+Why is [``\bar X``] a random variable?
+Because [``X_1``] and [``X_2``] are random, so the average changes from sample to sample.
+
+Why do we care about the probability distribution of [``\bar X``]?
+In statistics, we use [``\bar X``] to estimate a population mean. To understand how reliable that estimate is, we study the distribution of [``\bar X``], especially its mean and standard deviation.
+
+Big idea: [``\bar X``] has the same center as [``X``] and tends to be less variable than [``X``]. The spread shrinks as [``n``] grows.
+
+Rounding: Round all answers to 3 decimals.
+END_PGML
+Section::End();
+
+# Build X table NOW (so its blanks come before Step 2’s [____] blanks)
+$tblX = make_tblX();
+
+# -------------------------------------------------------
+# Step 2 — Work table for X
+# -------------------------------------------------------
+Section::Begin("Work table for X");
+BEGIN_PGML
+Fill the table row-by-row (all numeric cells).
+
+- Column 3 is [``x\,P(X=x)``]
+- Column 4 is [``x^2\,P(X=x)``]
+
+Then add columns 3 and 4 to get [``E(X)``] and [``E(X^2)``].
+
+[@ $tblX @]*
+
+Now compute:
+- [``\mathrm{Var}(X)=E(X^2)-[E(X)]^2``]
+- [``\sigma_X=\sqrt{\mathrm{Var}(X)}``]
+
+Enter [``\mathrm{Var}(X)``]: [____]
+Enter [``\sigma_X``]: [____]
+END_PGML
+
+ANS(
+ # row 1
+ $cmp_x_r1_x, $cmp_x_r1_p, $cmp_x_r1_c3, $cmp_x_r1_c4,
+ # row 2
+ $cmp_x_r2_x, $cmp_x_r2_p, $cmp_x_r2_c3, $cmp_x_r2_c4,
+ # row 3
+ $cmp_x_r3_x, $cmp_x_r3_p, $cmp_x_r3_c3, $cmp_x_r3_c4,
+ # row 4
+ $cmp_x_r4_x, $cmp_x_r4_p, $cmp_x_r4_c3, $cmp_x_r4_c4,
+ # totals
+ $cmp_x_tot_c3, $cmp_x_tot_c4,
+ # var, sd
+ $cmp_x_var, $cmp_x_sd
+);
+
+Section::End();
+
+# Build Xbar table NOW (so its blanks come AFTER Step 2 blanks)
+$tblXbar = make_tblXbar();
+
+# -------------------------------------------------------
+# Step 3 — Sample space + work table for X-bar (n=2)
+# -------------------------------------------------------
+Section::Begin("Work table for X-bar (n=2)");
+BEGIN_PGML
+For [``n=2``], the sample mean is [``\bar X=(X_1+X_2)/2``].
+
+Hint (important): The 16 ordered samples [``(X_1,X_2)``] are NOT equally likely, because the values of [``X``] are not equally likely.
+Use independence: [``P(X_1=a \text{ and } X_2=b)=P(X=a)\,P(X=b)``].
+
+**Sample space table (each cell shows** [``\bar X``] **for that ordered pair** [``(X_1,X_2)``]**):**
+
+[@ $samp @]*
+
+Now use that sample space to build the probability distribution of [``\bar X``] and fill the work table below (all numeric cells).
+
+[@ $tblXbar @]*
+
+Now compute:
+- [``\mathrm{Var}(\bar X)=E((\bar X)^2)-[E(\bar X)]^2``]
+- [``\sigma_{\bar X}=\sqrt{\mathrm{Var}(\bar X)}``]
+
+Enter [``\mathrm{Var}(\bar X)``]: [____]
+Enter [``\sigma_{\bar X}``]: [____]
+END_PGML
+
+ANS(
+ # row 1
+ $cmp_b_r1_x, $cmp_b_r1_p, $cmp_b_r1_c3, $cmp_b_r1_c4,
+ # row 2
+ $cmp_b_r2_x, $cmp_b_r2_p, $cmp_b_r2_c3, $cmp_b_r2_c4,
+ # row 3
+ $cmp_b_r3_x, $cmp_b_r3_p, $cmp_b_r3_c3, $cmp_b_r3_c4,
+ # row 4
+ $cmp_b_r4_x, $cmp_b_r4_p, $cmp_b_r4_c3, $cmp_b_r4_c4,
+ # row 5
+ $cmp_b_r5_x, $cmp_b_r5_p, $cmp_b_r5_c3, $cmp_b_r5_c4,
+ # row 6
+ $cmp_b_r6_x, $cmp_b_r6_p, $cmp_b_r6_c3, $cmp_b_r6_c4,
+ # row 7
+ $cmp_b_r7_x, $cmp_b_r7_p, $cmp_b_r7_c3, $cmp_b_r7_c4,
+ # totals
+ $cmp_b_tot_c3, $cmp_b_tot_c4,
+ # var, sd
+ $cmp_b_var, $cmp_b_sd
+);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 4 — Main concept + verify formulas (n=2)
+# -------------------------------------------------------
+Section::Begin("Main concept: verify the formulas");
+BEGIN_PGML
+For random samples of size [``n``] from a population with mean [``\mu``] and standard deviation [``\sigma``], the sample mean [``\bar X``] satisfies:
+
+- [``\mu_{\bar X}=\mu``]
+- [``\sigma_{\bar X}=\sigma/\sqrt{n}``]
+
+Use your results from the work tables to verify these for [``n=2``]:
+
+1) Enter [``\mu_{\bar X}``] (it should match [``\mu``]): [____]
+
+2) Compute [``\sigma/\sqrt{2}``] and enter it (it should match your [``\sigma_{\bar X}``]): [____]
+END_PGML
+
+ANS($cmp_verify_mu, $cmp_verify_sig2);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 5 — What if n=3?
+# -------------------------------------------------------
+Section::Begin("What if n=3?");
+BEGIN_PGML
+Now imagine you take a random sample of size [``n=3``] from the same population and compute the sample mean [``\bar X``].
+
+Use the formulas:
+
+- [``\mu_{\bar X}=\mu``]
+- [``\sigma_{\bar X}=\sigma/\sqrt{3}``]
+
+Enter [``\mu_{\bar X}``] for [``n=3``]: [____]
+Enter [``\sigma_{\bar X}``] for [``n=3``]: [____]
+
+Note: bigger sample size means smaller variability in [``\bar X``].
+END_PGML
+
+ANS($cmp_n3_mu, $cmp_n3_sig);
+
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating) — hidden in Library Browser
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+
+ Section::Begin("Feedback");
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/SamplingDistributions/SamplingDistributions_Mean_GuidedProblem3.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/SamplingDistributions/SamplingDistributions_Mean_GuidedProblem3.pg
new file mode 100644
index 0000000000..9d90448182
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/SamplingDistributions/SamplingDistributions_Mean_GuidedProblem3.pg
@@ -0,0 +1,238 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Sampling Distribution of the Sample Mean (Normal Population): Salmon Weights (n=5) (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Sampling Distributions)
+## Level(2)
+## KEYWORDS('normal distribution','sampling distribution','sample mean','z-score','standardization','sigma over root n','salmon weights')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser detection (LB stability)
+# ----------------------------------------------------------------
+$inLibraryBrowser = ($envir{isLibraryBrowser} || $envir{isLibrary} || 0);
+
+Context("Numeric");
+
+# =======================================================
+# Postfilter: add a hint ONLY when the answer is wrong
+# =======================================================
+sub HintIfWrong {
+ my $msg = shift;
+ return sub {
+ my $ans = shift;
+ if (defined($ans->{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+ return $ans;
+ };
+}
+
+# =======================================================
+# Data (given)
+# =======================================================
+$mu = Real(4.5);
+$sigma = Real(0.6);
+$c = Real(4.0);
+$n = 5;
+
+# =======================================================
+# Correct numeric targets (precomputed)
+# =======================================================
+# Standard error: sigma/sqrt(5) = 0.268328...
+$SE_exact = 0.2683281572999747;
+
+# Part (a): z = (4.0-4.5)/0.6 = -0.833333...
+$z_a_exact = -0.8333333333333334;
+# P(X<4.0) = Phi(z) = 0.202328...
+$P_a_exact = 0.20232838096364303;
+
+# Part (b): z = (4.0-4.5)/(0.6/sqrt(5)) = -1.863389...
+$z_b_exact = -1.8633899812498251;
+# P(Xbar<4.0) = Phi(z) = 0.0312037...
+$P_b_exact = 0.0312037092843529;
+
+# =======================================================
+# Tolerances
+# =======================================================
+# Students will likely round z to 3 decimals and probabilities to 4 decimals.
+$tol_mu = 0.001;
+$tol_se = 0.002; # allows 0.268 or 0.2683
+$tol_z = 0.02; # allows typical rounding of z
+$tol_p = 0.001; # allows 4-decimal rounding safely
+
+# =======================================================
+# Comparators
+# =======================================================
+$cmp_mu_bar = $mu->cmp(tolType=>"absolute", tolerance=>$tol_mu)
+ ->withPostFilter(HintIfWrong("For a normal population, the mean of X-bar is the same as the mean of X."));
+
+$cmp_se = Real($SE_exact)->cmp(tolType=>"absolute", tolerance=>$tol_se)
+ ->withPostFilter(HintIfWrong("Standard error is sigma divided by sqrt(n). Here: 0.6/sqrt(5)."));
+
+$cmp_z1 = Real($z_a_exact)->cmp(tolType=>"absolute", tolerance=>$tol_z)
+ ->withPostFilter(HintIfWrong("Compute z = (c - mu)/sigma."));
+
+$cmp_p1 = Real($P_a_exact)->cmp(tolType=>"absolute", tolerance=>$tol_p)
+ ->withPostFilter(HintIfWrong("Use the standard normal table/CDF: P(Xcmp(tolType=>"absolute", tolerance=>$tol_z)
+ ->withPostFilter(HintIfWrong("Use z = (c - mu)/(sigma/sqrt(n)). The denominator is the standard error."));
+
+$cmp_p2 = Real($P_b_exact)->cmp(tolType=>"absolute", tolerance=>$tol_p)
+ ->withPostFilter(HintIfWrong("Use the standard normal table/CDF: P(X-barcmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(numbered=>1, can_open=>"always", is_open=>"always");
+} else {
+ Scaffold::Begin(numbered=>1, can_open=>"when_previous_correct", is_open=>"correct_or_first_incorrect");
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+Let [``X``] be the weight (in kg) of a farm-raised salmon at the time of harvest.
+
+Assume [``X``] is normally distributed with mean [``\mu=4.5``] and standard deviation [``\sigma=0.6``]. In symbols:
+
+[``X \sim N(4.5,\,0.6)``]
+
+Let [``c=4.0``] kg.
+
+(a) Find [``P(X{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+ return $ans;
+ };
+}
+
+# =======================================================
+# Data (given)
+# =======================================================
+$mu = Real(355);
+$sigma = Real(6);
+$c = Real(6);
+$n = 9;
+
+# =======================================================
+# Correct numeric targets (precomputed)
+# =======================================================
+# Standard error: sigma/sqrt(9) = 2
+$SE_exact = 2.0;
+
+# Part (a): z = c/sigma = 1
+$z_a_exact = 1.0;
+# P(mu-c < X < mu+c) = P(-1 < Z < 1)
+$P_a_exact = 0.6826894921370859;
+
+# Part (b): z = c/(sigma/sqrt(9)) = 3
+$z_b_exact = 3.0;
+# P(mu-c < Xbar < mu+c) = P(-3 < Z < 3)
+$P_b_exact = 0.9973002039367398;
+
+# =======================================================
+# Tolerances
+# =======================================================
+$tol_mu = 0.001;
+$tol_se = 0.01; # 2 or 2.00 etc.
+$tol_z = 0.02; # typical rounding of z
+$tol_p = 0.001; # 4-decimal rounding safe
+
+# =======================================================
+# Comparators
+# =======================================================
+$cmp_mu_bar = $mu->cmp(tolType=>"absolute", tolerance=>$tol_mu)
+ ->withPostFilter(HintIfWrong("For a normal population, the mean of X-bar is the same as the mean of X."));
+
+$cmp_se = Real($SE_exact)->cmp(tolType=>"absolute", tolerance=>$tol_se)
+ ->withPostFilter(HintIfWrong("Standard error is sigma divided by sqrt(n). Here: 6/sqrt(9)."));
+
+$cmp_z1 = Real($z_a_exact)->cmp(tolType=>"absolute", tolerance=>$tol_z)
+ ->withPostFilter(HintIfWrong("For part (a), the z-bound is z = c/sigma."));
+
+$cmp_p1 = Real($P_a_exact)->cmp(tolType=>"absolute", tolerance=>$tol_p)
+ ->withPostFilter(HintIfWrong("Use symmetry: P(mu-c < X < mu+c) = P(-z < Z < z)."));
+
+$cmp_z2 = Real($z_b_exact)->cmp(tolType=>"absolute", tolerance=>$tol_z)
+ ->withPostFilter(HintIfWrong("For part (b), use z = c/(sigma/sqrt(n)). The denominator is the standard error."));
+
+$cmp_p2 = Real($P_b_exact)->cmp(tolType=>"absolute", tolerance=>$tol_p)
+ ->withPostFilter(HintIfWrong("Use symmetry: P(mu-c < X-bar < mu+c) = P(-z < Z < z)."));
+
+# =======================================================
+# Compare question (MC as numeric choice 1-5, no context switching)
+# Correct choice: 3
+# =======================================================
+$cmp_mc = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return ($s == 3) ? 1 : 0;
+ }
+)->withPostFilter(HintIfWrong("Think: X-bar has smaller standard deviation (sigma/sqrt(n)), so it stays closer to mu more often."));
+
+# =======================================================
+# Rating checker
+# =======================================================
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(numbered=>1, can_open=>"always", is_open=>"always");
+} else {
+ Scaffold::Begin(numbered=>1, can_open=>"when_previous_correct", is_open=>"correct_or_first_incorrect");
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A beverage company uses a machine to fill bottles.
+
+Let [``X``] be the fill volume (in mL) of a randomly selected bottle.
+
+Assume [``X``] is normally distributed with mean [``\mu=355``] and standard deviation [``\sigma=6``]. In symbols:
+
+[``X \sim N(355,\,6)``]
+
+Let [``c=6``] mL. So we are looking at the interval from [``\mu-c``] to [``\mu+c``].
+
+(a) Find [``P(\mu-c < X < \mu+c)``].
+
+(b) Take a random sample of [``n=9``] bottles. Let [``\bar X``] be the sample mean. Find [``P(\mu-c < \bar X < \mu+c)``].
+
+Rounding: Round z-scores to 3 decimals and probabilities to 4 decimals.
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Step 2 — Main concept (no image)
+# -------------------------------------------------------
+Section::Begin("Main concept: sampling distribution of the mean (normal population)");
+BEGIN_PGML
+**Theorem (Normal population):**
+If [``X``] is normally distributed, then for any sample size [``n``], the sample mean [``\bar X``] is also normally distributed, with
+
+- [``\mu_{\bar X}=\mu``]
+- [``\sigma_{\bar X}=\sigma/\sqrt{n}``]
+
+For this problem, [``n=9``].
+
+Enter [``\mu_{\bar X}``]: [____]
+Enter [``\sigma_{\bar X}``] (the standard error): [____]
+END_PGML
+
+ANS($cmp_mu_bar, $cmp_se);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 3 — Part (a)
+# -------------------------------------------------------
+Section::Begin("Part (a): probability within c of the mean for one bottle");
+BEGIN_PGML
+We want:
+
+[``P(\mu-c < X < \mu+c)``]
+
+Standardize using [``Z=(X-\mu)/\sigma``]. The bounds become:
+
+[``-\dfrac{c}{\sigma} < Z < \dfrac{c}{\sigma}``]
+
+1) Compute the z-bound [``z=\dfrac{c}{\sigma}``]: [____]
+
+2) Then compute [``P(-z{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+ return $ans;
+ };
+}
+
+# =======================================================
+# Data (given)
+# =======================================================
+$mu = Real(50);
+$sigma = Real(6);
+$c = Real(48);
+$n = 36;
+
+# =======================================================
+# Correct numeric targets (precomputed)
+# =======================================================
+# Standard error: sigma/sqrt(36) = 1
+$SE_exact = 1.0;
+
+# Part (a): z = (48-50)/6 = -1/3
+$z_a_exact = -0.3333333333333333;
+# P(X<48) = Phi(-1/3) = 0.369441...
+$P_a_exact = 0.36944134018176367;
+
+# Part (b): z = (48-50)/(6/sqrt(36)) = (48-50)/1 = -2
+$z_b_exact = -2.0;
+# P(Xbar<48) = Phi(-2) = 0.0227501...
+$P_b_exact = 0.02275013194817921;
+
+# =======================================================
+# Tolerances
+# =======================================================
+# Students will likely round z to 3 decimals and probabilities to 4 decimals.
+$tol_mu = 0.001;
+$tol_se = 0.01;
+$tol_z = 0.02;
+$tol_p = 0.001;
+
+# =======================================================
+# Comparators
+# =======================================================
+$cmp_mu_bar = $mu->cmp(tolType=>"absolute", tolerance=>$tol_mu)
+ ->withPostFilter(HintIfWrong("For a normal population, the mean of X-bar is the same as the mean of X."));
+
+$cmp_se = Real($SE_exact)->cmp(tolType=>"absolute", tolerance=>$tol_se)
+ ->withPostFilter(HintIfWrong("Standard error is sigma divided by sqrt(n). Here: 6/sqrt(36)."));
+
+$cmp_z1 = Real($z_a_exact)->cmp(tolType=>"absolute", tolerance=>$tol_z)
+ ->withPostFilter(HintIfWrong("Compute z = (48 - 50)/6."));
+
+$cmp_p1 = Real($P_a_exact)->cmp(tolType=>"absolute", tolerance=>$tol_p)
+ ->withPostFilter(HintIfWrong("Use the standard normal table/CDF: P(X<48)=P(Zcmp(tolType=>"absolute", tolerance=>$tol_z)
+ ->withPostFilter(HintIfWrong("Use z = (48 - 50)/(sigma/sqrt(36)). The denominator is the standard error."));
+
+$cmp_p2 = Real($P_b_exact)->cmp(tolType=>"absolute", tolerance=>$tol_p)
+ ->withPostFilter(HintIfWrong("Use the standard normal table/CDF: P(X-bar<48)=P(Zcmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return ($s == 3) ? 1 : 0;
+ }
+)->withPostFilter(HintIfWrong("If the claim is true, the probability in part (b) is very small (about 0.02), so this sample mean is unusual."));
+
+# =======================================================
+# Rating checker
+# =======================================================
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(numbered=>1, can_open=>"always", is_open=>"always");
+} else {
+ Scaffold::Begin(numbered=>1, can_open=>"when_previous_correct", is_open=>"correct_or_first_incorrect");
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+An automobile battery manufacturer claims that its midgrade battery has a mean life of [``50``] months with a standard deviation of [``6``] months.
+Suppose the distribution of battery lives of this particular brand is approximately normal.
+
+Let [``X``] be the life (in months) of a randomly selected battery.
+
+Assume:
+[``X \sim N(50,\,6)``]
+
+(a) On the assumption that the manufacturer's claims are true, find [``P(X<48)``].
+
+(b) On the same assumption, find the probability that the mean of a random sample of [``n=36``] such batteries will be less than [``48``] months, i.e. find [``P(\bar X<48)``].
+
+(c) If you observe a sample mean as low as [``48``] (or lower) for a random sample of [``36``] batteries, will you be inclined to suspect the manufacturer's claim?
+
+Rounding: Round z-scores to 3 decimals and probabilities to 4 decimals.
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Step 2 — Main concept (no image)
+# -------------------------------------------------------
+Section::Begin("Main concept: sampling distribution of the mean (normal population)");
+BEGIN_PGML
+**Theorem (Normal population):**
+If [``X``] is normally distributed, then for any sample size [``n``], the sample mean [``\bar X``] is also normally distributed, with
+
+- [``\mu_{\bar X}=\mu``]
+- [``\sigma_{\bar X}=\sigma/\sqrt{n}``]
+
+For this problem, [``n=36``].
+
+Enter [``\mu_{\bar X}``]: [____]
+Enter [``\sigma_{\bar X}``] (the standard error): [____]
+END_PGML
+
+ANS($cmp_mu_bar, $cmp_se);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 3 — Part (a)
+# -------------------------------------------------------
+Section::Begin("Part (a): P(X < 48)");
+BEGIN_PGML
+To find [``P(X<48)``], standardize:
+
+[``z=\dfrac{48-\mu}{\sigma}``]
+
+1) Compute the z-score: [____]
+
+2) Then compute [``P(X<48)=P(Z{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+ return $ans;
+ };
+}
+
+# =======================================================
+# Data (given) -- do NOT state distribution of X
+# =======================================================
+# X = lifespan (hours) of an electronic device
+$mu = Real(1200);
+$sigma = Real(300);
+$c = Real(1100);
+$n = 36;
+
+# =======================================================
+# Correct numeric targets (precomputed)
+# =======================================================
+# Standard error: sigma/sqrt(36) = 300/6 = 50
+$SE_exact = 50.0;
+
+# Part (b): z = (c - mu) / (sigma/sqrt(n)) = (1100-1200)/50 = -2
+$z_b_exact = -2.0;
+
+# P(Xbar < 1100) = Phi(-2) = 0.0227501...
+$P_b_exact = 0.02275013194817921;
+
+# =======================================================
+# Tolerances
+# =======================================================
+# Students round z to 3 decimals and probability to 4 decimals.
+$tol_mu = 0.001;
+$tol_se = 0.05; # allows typical rounding like 50 or 50.0
+$tol_z = 0.02;
+$tol_p = 0.001;
+
+# =======================================================
+# Comparators
+# =======================================================
+$cmp_mu_bar = $mu->cmp(tolType=>"absolute", tolerance=>$tol_mu)
+ ->withPostFilter(HintIfWrong("For the sample mean, mu_Xbar equals mu."));
+
+$cmp_se = Real($SE_exact)->cmp(tolType=>"absolute", tolerance=>$tol_se)
+ ->withPostFilter(HintIfWrong("Standard error is sigma divided by sqrt(n). Here: 300/sqrt(36)."));
+
+# Part (a) "MC" as numeric choice 1-5. Correct choice: 2.
+$cmp_a = Real(2)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return ($s == 2) ? 1 : 0;
+ }
+)->withPostFilter(HintIfWrong("We were only given mu and sigma. Without the distribution of X, we cannot find P(X < c)."));
+
+$cmp_zb = Real($z_b_exact)->cmp(tolType=>"absolute", tolerance=>$tol_z)
+ ->withPostFilter(HintIfWrong("Use z = (c - mu)/(sigma/sqrt(n)). The denominator is the standard error."));
+
+$cmp_pb = Real($P_b_exact)->cmp(tolType=>"absolute", tolerance=>$tol_p)
+ ->withPostFilter(HintIfWrong("After you get z, compute P(Z < z) using the standard normal table/CDF."));
+
+# =======================================================
+# Rating checker
+# =======================================================
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(numbered=>1, can_open=>"always", is_open=>"always");
+} else {
+ Scaffold::Begin(numbered=>1, can_open=>"when_previous_correct", is_open=>"correct_or_first_incorrect");
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+Let [``X``] be the lifespan (in hours) of a certain electronic device.
+
+You are told only that the population mean is [``\mu=1200``] hours and the population standard deviation is [``\sigma=300``] hours.
+
+Let [``c=1100``] hours.
+
+(a) Find [``P(X{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+ return $ans;
+ };
+}
+
+# =======================================================
+# Data (given) -- do NOT state the distribution of X
+# =======================================================
+# X = number of IT service desk requests per day (discrete)
+$mu = Real(120);
+$sigma = Real(30);
+$c = Real(10);
+$n = 50;
+
+# =======================================================
+# Correct numeric targets (precomputed)
+# =======================================================
+# Standard error: sigma/sqrt(50) = 4.242640687...
+$SE_exact = 4.2426406871192848;
+
+# z-bound for X-bar band: z = c / (sigma/sqrt(n)) = c*sqrt(n)/sigma
+$z_b_exact = 2.3570226039551585;
+
+# P(mu-c < X-bar < mu+c) = P(-z < Z < z) = 0.9815778745...
+$P_b_exact = 0.9815778745459009;
+
+# =======================================================
+# Tolerances
+# =======================================================
+$tol_mu = 0.001;
+$tol_se = 0.02; # allows 4.243
+$tol_z = 0.03; # allows rounding to 3 decimals
+$tol_p = 0.001; # allows 4-decimal rounding
+
+# =======================================================
+# Comparators
+# =======================================================
+$cmp_mu_bar = $mu->cmp(tolType=>"absolute", tolerance=>$tol_mu)
+ ->withPostFilter(HintIfWrong("For the sample mean, mu_Xbar equals mu."));
+
+$cmp_se = Real($SE_exact)->cmp(tolType=>"absolute", tolerance=>$tol_se)
+ ->withPostFilter(HintIfWrong("Standard error is sigma divided by sqrt(n). Here: 30/sqrt(50)."));
+
+# Part (a): Enter 1 if you can compute, 0 if you cannot.
+$cmp_a_can = Compute("0")->cmp(tolType=>"absolute", tolerance=>0.001)
+ ->withPostFilter(HintIfWrong("We only know mu and sigma. Without the distribution of X, we cannot compute that probability for X."));
+
+$cmp_zb = Real($z_b_exact)->cmp(tolType=>"absolute", tolerance=>$tol_z)
+ ->withPostFilter(HintIfWrong("Use z = c/(sigma/sqrt(n)) = c*sqrt(n)/sigma."));
+
+$cmp_pb = Real($P_b_exact)->cmp(tolType=>"absolute", tolerance=>$tol_p)
+ ->withPostFilter(HintIfWrong("After you find z, compute P(-z < Z < z) using the standard normal table/CDF."));
+
+# =======================================================
+# Rating checker
+# =======================================================
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(numbered=>1, can_open=>"always", is_open=>"always");
+} else {
+ Scaffold::Begin(numbered=>1, can_open=>"when_previous_correct", is_open=>"correct_or_first_incorrect");
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+Let [``X``] be the number of requests an IT service desk receives in one day. This is a discrete random variable.
+
+From long-term records, the mean number of requests per day is [``\mu=120``] and the standard deviation is [``\sigma=30``].
+
+Let [``c=10``]. So the interval from [``\mu-c``] to [``\mu+c``] is from [``110``] to [``130``].
+
+(a) Find [``P(\mu-c < X < \mu+c)``].
+
+(b) Take a random sample of size [``n=50``] days. Let [``\bar X``] be the sample mean number of requests per day. Find [``P(\mu-c < \bar X < \mu+c)``].
+
+Rounding: Round z-scores to 3 decimals and probabilities to 4 decimals.
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Step 2 — Main concept: Central Limit Theorem (no image)
+# -------------------------------------------------------
+Section::Begin("Main concept: Central Limit Theorem");
+BEGIN_PGML
+**Central Limit Theorem (CLT):**
+For samples of size [``30``] or more, the sample mean [``\bar X``] is approximately normally distributed, with
+
+- [``\mu_{\bar X}=\mu``]
+- [``\sigma_{\bar X}=\sigma/\sqrt{n}``]
+
+Here, [``n=50``].
+
+Enter [``\mu_{\bar X}``]: [____]
+Enter [``\sigma_{\bar X}``] (the standard error): [____]
+END_PGML
+
+ANS($cmp_mu_bar, $cmp_se);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 3 — Part (a): Can we compute P(mu-c < X < mu+c)?
+# -------------------------------------------------------
+Section::Begin("Part (a): can we compute the probability for X?");
+BEGIN_PGML
+We want [``P(\mu-c < X < \mu+c)``], which is [``P(110 < X < 130)``].
+
+But we were not told the probability distribution of [``X``]. With only [``\mu``] and [``\sigma``], Can this probability be computed?
+
+Enter [``1``] if this probability can be computed from the given information, or enter [``0``] if it cannot be computed:
+
+Answer: [____]
+END_PGML
+
+ANS($cmp_a_can);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 4 — Part (b): Use CLT for the sample mean
+# -------------------------------------------------------
+Section::Begin("Part (b): use CLT for the sample mean");
+BEGIN_PGML
+Now we want [``P(\mu-c < \bar X < \mu+c)``] for [``n=50``], which is [``P(110 < \bar X < 130)``].
+
+By CLT, [``\bar X``] is approximately normal with mean [``\mu``] and standard deviation [``\sigma/\sqrt{n}``].
+
+Standardize the bounds:
+
+[``-\dfrac{c}{\sigma/\sqrt{n}} < Z < \dfrac{c}{\sigma/\sqrt{n}}``]
+
+1) Compute the z-bound [``z=\dfrac{c}{\sigma/\sqrt{n}}``]: [____]
+
+2) Then compute [``P(-z{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+ return $ans;
+ };
+}
+
+# =======================================================
+# Data (given) -- discrete and clearly not normal; do NOT give a distribution
+# =======================================================
+# X = number of defective items found in a daily batch (nonnegative integer)
+$mu = Real(2.5);
+$sigma = Real(6);
+$k = Real(3);
+$n = 50;
+
+# =======================================================
+# Correct numeric targets (precomputed)
+# =======================================================
+# Standard error: sigma/sqrt(50)
+$SE_exact = 0.8485281374238570;
+
+# Part (b): z = (3 - 2.5)/(6/sqrt(50)) = 0.5892556509...
+$z_b_exact = 0.5892556509887896;
+
+# P(Xbar > 3) = P(Z > z) = 0.2778448951...
+$P_b_exact = 0.2778448951413973;
+
+# =======================================================
+# Tolerances
+# =======================================================
+$tol_mu = 0.001;
+$tol_se = 0.02; # allows 0.849
+$tol_z = 0.03; # allows rounding to 3 decimals
+$tol_p = 0.001; # allows 4-decimal rounding
+
+# =======================================================
+# Comparators
+# =======================================================
+$cmp_mu_bar = $mu->cmp(tolType=>"absolute", tolerance=>$tol_mu)
+ ->withPostFilter(HintIfWrong("For the sample mean, mu_Xbar equals mu."));
+
+$cmp_se = Real($SE_exact)->cmp(tolType=>"absolute", tolerance=>$tol_se)
+ ->withPostFilter(HintIfWrong("Standard error is sigma divided by sqrt(n). Here: 6/sqrt(50)."));
+
+# Part (a) MC (numeric 1-5). Correct choice: 2 (cannot compute).
+$cmp_a = Real(2)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return ($s == 2) ? 1 : 0;
+ }
+)->withPostFilter(HintIfWrong("We only know mu and sigma. Without the probability distribution of X, we cannot compute P(X>3)."));
+
+$cmp_zb = Real($z_b_exact)->cmp(tolType=>"absolute", tolerance=>$tol_z)
+ ->withPostFilter(HintIfWrong("Use z = (3 - mu)/(sigma/sqrt(n)). The denominator is the standard error."));
+
+$cmp_pb = Real($P_b_exact)->cmp(tolType=>"absolute", tolerance=>$tol_p)
+ ->withPostFilter(HintIfWrong("Upper tail: P(X-bar>3)=P(Z>z)=1-P(Zcmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return ($s == 3) ? 1 : 0;
+ }
+)->withPostFilter(HintIfWrong("If the claim is true, the probability in part (b) is not tiny (around 0.28), so X-bar > 3 is not that unusual."));
+
+# =======================================================
+# Rating checker
+# =======================================================
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(numbered=>1, can_open=>"always", is_open=>"always");
+} else {
+ Scaffold::Begin(numbered=>1, can_open=>"when_previous_correct", is_open=>"correct_or_first_incorrect");
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A manufacturer tracks the number of defective items found in a daily batch.
+
+Let [``X``] be the number of defects in one day. This is a **discrete** random variable (a nonnegative integer), and it is **not** expected to look normal.
+
+The manufacturer claims that the mean number of defects per day is [``\mu=2.5``] and the standard deviation is [``\sigma=6``].
+
+(a) On the assumption that the manufacturer's claims are true, find [``P(X>3)``].
+
+(b) On the same assumption, take a random sample of [``n=50``] days. Let [``\bar X``] be the sample mean number of defects per day. Find [``P(\bar X>3)``].
+
+(c) If you observe a sample mean as high as [``3``] (or higher) for a random sample of [``50``] days, will you be inclined to suspect the manufacturer's claim?
+
+Rounding: Round z-scores to 3 decimals and probabilities to 4 decimals.
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Step 2 — Main concept: Central Limit Theorem (no image)
+# -------------------------------------------------------
+Section::Begin("Main concept: Central Limit Theorem");
+BEGIN_PGML
+**Central Limit Theorem (CLT):**
+For samples of size [``30``] or more, the sample mean [``\bar X``] is approximately normally distributed, with
+
+- [``\mu_{\bar X}=\mu``]
+- [``\sigma_{\bar X}=\sigma/\sqrt{n}``]
+
+Here, [``n=50``].
+
+Enter [``\mu_{\bar X}``]: [____]
+Enter [``\sigma_{\bar X}``] (the standard error): [____]
+END_PGML
+
+ANS($cmp_mu_bar, $cmp_se);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 3 — Part (a): Can we compute P(X > 3)?
+# -------------------------------------------------------
+Section::Begin("Part (a): can we compute P(X > 3)?");
+BEGIN_PGML
+Can [``P(X>3)``] be calculated from the information in the problem statement?
+
+Choose the best answer:
+
+1) Yes, because CLT says [``X``] is (approximately) normal.
+2) No, because we do not know the probability distribution of [``X``].
+3) Yes, because [``n=50``] is large.
+4) Yes, because [``\bar X``] is approximately normal, so [``X``] must be normal too.
+5) No, because [``X``] is discrete.
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_a);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 4 — Part (b): Use CLT for P(X-bar > 3)
+# -------------------------------------------------------
+Section::Begin("Part (b): use CLT to find P(X-bar > 3)");
+BEGIN_PGML
+Now we want [``P(\bar X>3)``] for [``n=50``].
+
+By CLT, [``\bar X``] is approximately normal with mean [``\mu``] and standard deviation [``\sigma/\sqrt{n}``].
+
+Standardize:
+
+[``z=\dfrac{3-\mu}{\sigma/\sqrt{n}}``]
+
+1) Compute the z-score for [``\bar X``]: [____]
+
+2) Then compute the probability:
+[``P(\bar X>3)=P(Z>z)``]: [____]
+Note that since [``X``] is NOT normally distributed, for these calculations to be justified we need a large sample size, at least 30. CLT is not valid for small samples.
+
+END_PGML
+
+ANS($cmp_zb, $cmp_pb);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 5 — Part (c): should we suspect the claim?
+# -------------------------------------------------------
+Section::Begin("Part (c): should we suspect the claim?");
+BEGIN_PGML
+If you observe a sample mean as high as [``3``] (or higher) for a random sample of [``50``] days, will you be inclined to suspect the manufacturer's claim?
+
+Choose the best answer:
+
+1) Yes. Any sample mean above 3 contradicts the claim.
+2) Yes. CLT does not apply because [``X``] is discrete.
+3) No. If the claim is true, the probability in part (b) is not very small, so this sample mean is not that unusual.
+4) No. The sample mean must always equal [``\mu``] when [``n=50``].
+5) Not enough information.
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_mc);
+
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating) — hidden in Library Browser
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+
+ Section::Begin("Feedback");
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/SamplingDistributions/SamplingDistributions_Mean_GuidedProblem9.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/SamplingDistributions/SamplingDistributions_Mean_GuidedProblem9.pg
new file mode 100644
index 0000000000..b4524a968a
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/SamplingDistributions/SamplingDistributions_Mean_GuidedProblem9.pg
@@ -0,0 +1,283 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Central Limit Theorem (CLT): Customer Returns per Day (Discrete X, n=49) (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Sampling Distributions)
+## Level(2)
+## KEYWORDS('central limit theorem','CLT','sampling distribution','sample mean','z-score','standardization','sigma over root n','discrete random variable','customer returns')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser detection (LB stability)
+# ----------------------------------------------------------------
+$inLibraryBrowser = ($envir{isLibraryBrowser} || $envir{isLibrary} || 0);
+
+Context("Numeric");
+
+# =======================================================
+# Postfilter: add a hint ONLY when the answer is wrong
+# =======================================================
+sub HintIfWrong {
+ my $msg = shift;
+ return sub {
+ my $ans = shift;
+ if (defined($ans->{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+ return $ans;
+ };
+}
+
+# =======================================================
+# Data (given) -- discrete and clearly not normal; do NOT give a distribution
+# =======================================================
+# X = number of customer returns received in one day
+$mu = Real(40);
+$sigma = Real(15);
+$n = 49;
+$cut = Real(45);
+
+# =======================================================
+# Correct numeric targets (precomputed)
+# =======================================================
+# Standard error: sigma/sqrt(49) = 15/7
+$SE_exact = 2.142857142857143;
+
+# z = (45 - 40)/(15/sqrt(49)) = 2.333333333...
+$z_b_exact = 2.3333333333333335;
+
+# P(Xbar > 45) = P(Z > 2.333333333...) = 0.0098153286...
+$P_b_exact = 0.009815328628645342;
+
+# =======================================================
+# Tolerances
+# =======================================================
+$tol_mu = 0.001;
+$tol_se = 0.02;
+$tol_z = 0.03;
+$tol_p = 0.001;
+
+# =======================================================
+# Comparators
+# =======================================================
+$cmp_mu_bar = $mu->cmp(tolType=>"absolute", tolerance=>$tol_mu)
+ ->withPostFilter(HintIfWrong("For the sample mean, mu_Xbar equals mu."));
+
+$cmp_se = Real($SE_exact)->cmp(tolType=>"absolute", tolerance=>$tol_se)
+ ->withPostFilter(HintIfWrong("Standard error is sigma divided by sqrt(n). Here: 15/sqrt(49)."));
+
+# Part (a) MC (numeric 1-5). Correct choice: 2 (cannot compute).
+$cmp_a = Real(2)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return ($s == 2) ? 1 : 0;
+ }
+)->withPostFilter(HintIfWrong("We only know mu and sigma. Without the probability distribution of X, we cannot compute P(X>45)."));
+
+$cmp_zb = Real($z_b_exact)->cmp(tolType=>"absolute", tolerance=>$tol_z)
+ ->withPostFilter(HintIfWrong("Use z = (45 - mu)/(sigma/sqrt(n)). The denominator is the standard error."));
+
+$cmp_pb = Real($P_b_exact)->cmp(tolType=>"absolute", tolerance=>$tol_p)
+ ->withPostFilter(HintIfWrong("Upper tail: P(X-bar>45)=P(Z>z)=1-P(Zcmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return ($s == 1) ? 1 : 0;
+ }
+)->withPostFilter(HintIfWrong("If the claim is true, the probability in part (b) is very small (less than 0.05), so X-bar > 45 would be unusual."));
+
+# =======================================================
+# Rating checker
+# =======================================================
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(numbered=>1, can_open=>"always", is_open=>"always");
+} else {
+ Scaffold::Begin(numbered=>1, can_open=>"when_previous_correct", is_open=>"correct_or_first_incorrect");
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A warehouse tracks the number of customer returns received each day.
+
+Let [``X``] be the number of customer returns in one day. This is a **discrete** random variable (a nonnegative integer), and it is **not** expected to look normal.
+
+The warehouse manager claims that the mean number of returns per day is [``\mu=40``] and the standard deviation is [``\sigma=15``].
+
+(a) On the assumption that the manager's claims are true, find [``P(X>45)``].
+
+(b) On the same assumption, take a random sample of [``n=49``] days. Let [``\bar X``] be the sample mean number of returns per day. Find [``P(\bar X>45)``].
+
+(c) If you observe a sample mean as high as [``45``] (or higher) for a random sample of [``49``] days, will you be inclined to suspect the manager's claim?
+
+Rounding: Round z-scores to 3 decimals and probabilities to 4 decimals.
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Step 2 — Main concept: Central Limit Theorem
+# -------------------------------------------------------
+Section::Begin("Main concept: Central Limit Theorem");
+BEGIN_PGML
+**Central Limit Theorem (CLT):**
+For samples of size [``30``] or more, the sample mean [``\bar X``] is approximately normally distributed, with
+
+- [``\mu_{\bar X}=\mu``]
+- [``\sigma_{\bar X}=\sigma/\sqrt{n}``]
+
+Here, [``n=49``].
+
+Enter [``\mu_{\bar X}``]: [____]
+Enter [``\sigma_{\bar X}``] (the standard error): [____]
+END_PGML
+
+ANS($cmp_mu_bar, $cmp_se);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 3 — Part (a): Can we compute P(X > 45)?
+# -------------------------------------------------------
+Section::Begin("Part (a): can we compute P(X > 45)?");
+BEGIN_PGML
+Can [``P(X>45)``] be calculated from the information in the problem statement?
+
+Choose the best answer:
+
+1) Yes, because CLT says [``X``] is (approximately) normal.
+2) No, because we do not know the probability distribution of [``X``].
+3) Yes, because [``n=49``] is large.
+4) Yes, because [``\bar X``] is approximately normal, so [``X``] must be normal too.
+5) No, because [``X``] is discrete.
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_a);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 4 — Part (b): Use CLT for P(X-bar > 45)
+# -------------------------------------------------------
+Section::Begin("Part (b): use CLT to find P(X-bar > 45)");
+BEGIN_PGML
+Now we want [``P(\bar X>45)``] for [``n=49``].
+
+By CLT, [``\bar X``] is approximately normal with mean [``\mu``] and standard deviation [``\sigma/\sqrt{n}``].
+
+Standardize:
+
+[``z=\dfrac{45-\mu}{\sigma/\sqrt{n}}``]
+
+1) Compute the z-score for [``\bar X``]: [____]
+
+2) Then compute the probability:
+[``P(\bar X>45)=P(Z>z)``]: [____]
+
+Note that since [``X``] is NOT normally distributed, for these calculations to be justified we need a large sample size, at least 30. CLT is not valid for small samples.
+END_PGML
+
+ANS($cmp_zb, $cmp_pb);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 5 — Part (c): should we suspect the claim?
+# -------------------------------------------------------
+Section::Begin("Part (c): should we suspect the claim?");
+BEGIN_PGML
+If you observe a sample mean as high as [``45``] (or higher) for a random sample of [``49``] days, will you be inclined to suspect the manager's claim?
+
+Choose the best answer:
+
+1) Yes. If the claim is true, the probability of observing such a large sample mean or even larger, calculated in part (b), is unusually small (less than 1 percent). In other words this sample mean would be very unlikely.
+2) Yes. Any sample mean above [``45``] contradicts the claim.
+3) No. If the claim is true, the probability in part (b) is not very small, so this sample mean is not that unusual.
+4) No. The sample mean must always equal [``\mu``] when [``n=49``].
+5) Not enough information.
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_mc);
+
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating) — hidden in Library Browser
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+
+ Section::Begin("Feedback");
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/SamplingDistributions/SamplingDistributions_Proportion_GuidedProblem1.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/SamplingDistributions/SamplingDistributions_Proportion_GuidedProblem1.pg
new file mode 100644
index 0000000000..14b8527ff9
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/SamplingDistributions/SamplingDistributions_Proportion_GuidedProblem1.pg
@@ -0,0 +1,371 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Sampling Distribution of a Proportion: Bond Issue Support (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Sampling Distributions)
+## Level(2)
+## KEYWORDS('sampling distribution','sample proportion','p-hat','normal approximation','conditions for normality','within 5 percentage points','voters','bond issue')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser detection (LB stability)
+# ----------------------------------------------------------------
+$inLibraryBrowser = ($envir{isLibraryBrowser} || $envir{isLibrary} || 0);
+
+Context("Numeric");
+
+# =======================================================
+# Postfilter: add a hint ONLY when the answer is wrong
+# =======================================================
+sub HintIfWrong {
+ my $msg = shift;
+ return sub {
+ my $ans = shift;
+ if (defined($ans->{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+ return $ans;
+ };
+}
+
+# =======================================================
+# Data
+# =======================================================
+$p = Real(0.38);
+$q = Real(0.62);
+$n = 900;
+$margin = Real(0.05);
+
+$lower = Real(0.33);
+$upper = Real(0.43);
+
+# =======================================================
+# Correct numeric targets
+# =======================================================
+$mu_phat_exact = 0.38;
+$se_exact = 0.016179548132682128;
+$np_exact = 342;
+$nq_exact = 558;
+
+$z_lower_exact = -3.090321162863735;
+$z_upper_exact = 3.090321162863735;
+
+$p_final_exact = 0.9980005982948514;
+
+# =======================================================
+# Tolerances
+# =======================================================
+$tol_mu = 0.001;
+$tol_se = 0.001;
+$tol_n = 0.001;
+$tol_z = 0.03;
+$tol_p = 0.001;
+
+# =======================================================
+# Comparators
+# =======================================================
+$cmp_mu_phat = Real($mu_phat_exact)->cmp(tolType=>"absolute", tolerance=>$tol_mu)
+ ->withPostFilter(HintIfWrong("For p-hat, the mean is p."));
+
+$cmp_se = Real($se_exact)->cmp(tolType=>"absolute", tolerance=>$tol_se)
+ ->withPostFilter(HintIfWrong("Use sqrt(p(1-p)/n)."));
+
+$cmp_np = Real($np_exact)->cmp(tolType=>"absolute", tolerance=>$tol_n)
+ ->withPostFilter(HintIfWrong("Compute np using n=900 and p=0.38."));
+
+$cmp_nq = Real($nq_exact)->cmp(tolType=>"absolute", tolerance=>$tol_n)
+ ->withPostFilter(HintIfWrong("Compute n(1-p) using n=900 and 1-p=0.62."));
+
+# Step 3 MC: correct choice = 4
+$cmp_cond = Real(4)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return ($s == 4) ? 1 : 0;
+ }
+)->withPostFilter(HintIfWrong("The normal approximation for p-hat is justified when both np and n(1-p) are at least 5."));
+
+$cmp_z_lower = Real($z_lower_exact)->cmp(tolType=>"absolute", tolerance=>$tol_z)
+ ->withPostFilter(HintIfWrong("Use z = (0.33 - 0.38)/sqrt(0.38(0.62)/900)."));
+
+$cmp_z_upper = Real($z_upper_exact)->cmp(tolType=>"absolute", tolerance=>$tol_z)
+ ->withPostFilter(HintIfWrong("Use z = (0.43 - 0.38)/sqrt(0.38(0.62)/900)."));
+
+$cmp_final = Real($p_final_exact)->cmp(tolType=>"absolute", tolerance=>$tol_p)
+ ->withPostFilter(HintIfWrong("This is a middle-area probability: P(0.33 < p-hat < 0.43) = P(z_lower < Z < z_upper)."));
+
+# Rating checker
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(numbered=>1, can_open=>"always", is_open=>"always");
+} else {
+ Scaffold::Begin(numbered=>1, can_open=>"when_previous_correct", is_open=>"correct_or_first_incorrect");
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+Suppose that in a population of voters in a certain region, **38%** are in favor of a particular bond issue.
+
+A random sample of [``n=900``] voters is selected, and each voter is asked whether they favor the bond issue.
+
+Let [``\hat p``] be the sample proportion of voters in the sample who are in favor of the bond issue.
+
+(a) Verify that the sampling distribution of [``\hat p``] can be approximated by a normal distribution.
+
+(b) Find the probability that the sample proportion [``\hat p``] is within **5 percentage points** of the true population proportion.
+
+That is, find
+
+[``P(|\hat p - p| < 0.05)``]
+
+Rounding: Round z-scores to 3 decimals and probabilities to 4 decimals.
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Step 2 — Main concept
+# -------------------------------------------------------
+Section::Begin("Main concept: sampling distribution of p-hat");
+BEGIN_PGML
+For a sample proportion [``\hat p``], the sampling distribution is approximately normal when the sample is random and the success-failure conditions are satisfied.
+
+When the approximation is valid,
+
+- [``\mu_{\hat p} = p``]
+- [``\sigma_{\hat p} = \sqrt{\dfrac{p(1-p)}{n}}``]
+
+Using [``p=0.38``] and [``n=900``]:
+
+Enter [``\mu_{\hat p}``]: [____]
+
+Enter [``\sigma_{\hat p}``]: [____]
+END_PGML
+
+ANS($cmp_mu_phat, $cmp_se);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 3 — Check normality conditions
+# -------------------------------------------------------
+Section::Begin("Check the normality conditions");
+BEGIN_PGML
+To justify the normal approximation for [``\hat p``], check the success-failure conditions:
+
+- [``np \ge 5``]
+- [``n(1-p) \ge 5``]
+
+1) Compute [``np``]: [____]
+
+2) Compute [``n(1-p)``]: [____]
+
+3) Is normal approximation justified in this case? Choose the best conclusion:
+
+1) No, because [``p``] is not close to [``0.50``].
+2) No, because [``\hat p``] is a proportion, not a mean.
+3) Yes, because [``n=900``] is greater than [``30``].
+4) Yes, because both [``np``] and [``n(1-p)``] are at least [``5``].
+5) No, because the population proportion is less than [``1``].
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_np, $cmp_nq, $cmp_cond);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 4 — Rewrite the event and standardize
+# -------------------------------------------------------
+Section::Begin("Rewrite the event and standardize");
+BEGIN_PGML
+Being within [``5``] percentage points of the true proportion [``p=0.38``] means
+
+[``0.38 - 0.05 < \hat p < 0.38 + 0.05``]
+
+So we want
+
+[``P(0.33 < \hat p < 0.43)``]
+
+Now standardize the two endpoints.
+
+Lower endpoint z-score:
+
+[``z = \dfrac{0.33 - 0.38}{\sqrt{0.38(0.62)/900}}``]
+
+Enter the lower z-score: [____]
+
+Upper endpoint z-score:
+
+[``z = \dfrac{0.43 - 0.38}{\sqrt{0.38(0.62)/900}}``]
+
+Enter the upper z-score: [____]
+END_PGML
+
+ANS($cmp_z_lower, $cmp_z_upper);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 5 — Final Answer
+# -------------------------------------------------------
+Section::Begin("Final Answer");
+BEGIN_PGML
+Now find the probability
+
+[``P(0.33 < \hat p < 0.43) = P(z_{\text{lower}} < Z < z_{\text{upper}})``]
+
+Enter the probability: [____]
+END_PGML
+
+ANS($cmp_final);
+
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating) — hidden in Library Browser
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+
+ Section::Begin("Feedback");
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+BEGIN_PGML_SOLUTION
+**1. Identify the statistic.**
+
+The statistic is the sample proportion [``\hat p``].
+
+The population proportion is
+
+[``p = 0.38``]
+
+so
+
+[``1-p = 0.62``]
+
+and the sample size is
+
+[``n = 900``]
+
+**2. Write the sampling distribution facts for [``\hat p``].**
+
+When the normal approximation is justified,
+
+[``\mu_{\hat p} = p = 0.38``]
+
+and
+
+[``\sigma_{\hat p} = \sqrt{\dfrac{p(1-p)}{n}} = \sqrt{\dfrac{(0.38)(0.62)}{900}} \approx 0.01618``]
+
+**3. Check the success-failure conditions.**
+
+We compute
+
+[``np = (900)(0.38) = 342``]
+
+and
+
+[``n(1-p) = (900)(0.62) = 558``]
+
+Both values are at least [``5``], so the sampling distribution of [``\hat p``] is approximately normal.
+
+**4. Rewrite the probability statement.**
+
+"Within 5 percentage points of the true proportion" means
+
+[``| \hat p - 0.38 | < 0.05``]
+
+which is the same as
+
+[``0.33 < \hat p < 0.43``]
+
+So we want
+
+[``P(0.33 < \hat p < 0.43)``]
+
+**5. Standardize the endpoints.**
+
+For the lower endpoint,
+
+[``z = \dfrac{0.33 - 0.38}{0.01618} \approx -3.090``]
+
+For the upper endpoint,
+
+[``z = \dfrac{0.43 - 0.38}{0.01618} \approx 3.090``]
+
+So
+
+[``P(0.33 < \hat p < 0.43) = P(-3.090 < Z < 3.090)``]
+
+**6. Find the probability.**
+
+Using the standard normal distribution,
+
+[``P(-3.090 < Z < 3.090) \approx 0.9980``]
+
+So the probability that the sample proportion is within 5 percentage points of the true population proportion is
+
+[``0.9980``]
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/SamplingDistributions/SamplingDistributions_Proportion_GuidedProblem2.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/SamplingDistributions/SamplingDistributions_Proportion_GuidedProblem2.pg
new file mode 100644
index 0000000000..7e5121e67d
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/SamplingDistributions/SamplingDistributions_Proportion_GuidedProblem2.pg
@@ -0,0 +1,380 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Sampling Distribution of a Proportion: Defective Items Claim (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Sampling Distributions)
+## Level(2)
+## KEYWORDS('sampling distribution','sample proportion','p-hat','normal approximation','conditions for normality','z-score','defective items')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser detection (LB stability)
+# ----------------------------------------------------------------
+$inLibraryBrowser = ($envir{isLibraryBrowser} || $envir{isLibrary} || 0);
+
+Context("Numeric");
+
+# =======================================================
+# Postfilter: add a hint ONLY when the answer is wrong
+# =======================================================
+sub HintIfWrong {
+ my $msg = shift;
+ return sub {
+ my $ans = shift;
+ if (defined($ans->{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+ return $ans;
+ };
+}
+
+# =======================================================
+# Data
+# =======================================================
+# p = true proportion of defective items
+$p = Real(0.08);
+$q = Real(0.92);
+$n = 200;
+$cutoff = Real(0.12);
+
+# =======================================================
+# Correct numeric targets
+# =======================================================
+$mu_phat_exact = 0.08;
+$se_exact = 0.01918332609325088;
+$np_exact = 16;
+$nq_exact = 184;
+$z_exact = 2.085144140570747;
+$p_final_exact = 0.0185281092820595;
+
+# =======================================================
+# Tolerances
+# =======================================================
+$tol_mu = 0.001;
+$tol_se = 0.001;
+$tol_n = 0.001;
+$tol_z = 0.03;
+$tol_p = 0.001;
+
+# =======================================================
+# Comparators
+# =======================================================
+$cmp_mu_phat = Real($mu_phat_exact)->cmp(tolType=>"absolute", tolerance=>$tol_mu)
+ ->withPostFilter(HintIfWrong("For p-hat, the mean is p."));
+
+$cmp_se = Real($se_exact)->cmp(tolType=>"absolute", tolerance=>$tol_se)
+ ->withPostFilter(HintIfWrong("The standard deviation of p-hat is sqrt(p(1-p)/n)."));
+
+$cmp_np = Real($np_exact)->cmp(tolType=>"absolute", tolerance=>$tol_n)
+ ->withPostFilter(HintIfWrong("Compute np using n=200 and p=0.08."));
+
+$cmp_nq = Real($nq_exact)->cmp(tolType=>"absolute", tolerance=>$tol_n)
+ ->withPostFilter(HintIfWrong("Compute n(1-p) using n=200 and 1-p=0.92."));
+
+# Step 3 MC: correct choice = 4
+$cmp_cond = Real(4)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return ($s == 4) ? 1 : 0;
+ }
+)->withPostFilter(HintIfWrong("The normal approximation for p-hat is justified when both np and n(1-p) are at least 5."));
+
+$cmp_z = Real($z_exact)->cmp(tolType=>"absolute", tolerance=>$tol_z)
+ ->withPostFilter(HintIfWrong("Use z = (0.12 - p)/sqrt(p(1-p)/n)."));
+
+$cmp_final = Real($p_final_exact)->cmp(tolType=>"absolute", tolerance=>$tol_p)
+ ->withPostFilter(HintIfWrong("Use the upper tail: P(p-hat > 0.12) = P(Z > z)."));
+
+# Step 6 MC: correct choice = 2
+$cmp_interp = Real(2)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return ($s == 2) ? 1 : 0;
+ }
+)->withPostFilter(HintIfWrong("If the claim is true, the probability you found is quite small, so p-hat = 0.12 or more would be unusual."));
+
+# Rating checker
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(numbered=>1, can_open=>"always", is_open=>"always");
+} else {
+ Scaffold::Begin(numbered=>1, can_open=>"when_previous_correct", is_open=>"correct_or_first_incorrect");
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A manufacturer claims that **8%** of the items produced by a machine are defective.
+
+A random sample of [``n=200``] items is selected. Let [``\hat p``] be the sample proportion of defective items.
+
+(a) Verify that the sampling distribution of [``\hat p``] can be approximated by a normal distribution.
+
+(b) Assuming the manufacturer's claim is true, find [``P(\hat p > 0.12)``].
+
+(c) If, in a sample of [``200``] items, you observe a sample proportion as high as [``0.12``] (or higher), would you be inclined to suspect the manufacturer's claim?
+
+Rounding: Round z-scores to 3 decimals and probabilities to 4 decimals.
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Step 2 — Main concept
+# -------------------------------------------------------
+Section::Begin("Main concept: sampling distribution of p-hat");
+BEGIN_PGML
+For a sample proportion [``\hat p``], the sampling distribution is approximately normal when the sample is random and the success-failure conditions are satisfied.
+
+When the approximation is valid,
+
+- [``\mu_{\hat p} = p``]
+- [``\sigma_{\hat p} = \sqrt{\dfrac{p(1-p)}{n}}``]
+
+Using [``p=0.08``] and [``n=200``]:
+
+Enter [``\mu_{\hat p}``]: [____]
+
+Enter [``\sigma_{\hat p}``]: [____]
+END_PGML
+
+ANS($cmp_mu_phat, $cmp_se);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 3 — Check normality conditions
+# -------------------------------------------------------
+Section::Begin("Check the normality conditions");
+BEGIN_PGML
+To justify the normal approximation for [``\hat p``], check the success-failure conditions:
+
+- [``np \ge 5``]
+- [``n(1-p) \ge 5``]
+
+1) Compute [``np``]: [____]
+
+2) Compute [``n(1-p)``]: [____]
+
+3) Is normal approximation justified in this case? Choose the best conclusion:
+
+1) No, because [``p``] is less than [``0.5``].
+2) No, because [``\hat p``] is a proportion, not a mean.
+3) Yes, because [``n=200``] is greater than [``30``].
+4) Yes, because both [``np``] and [``n(1-p)``] are at least [``5``].
+5) No, because the population proportion is unknown.
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_np, $cmp_nq, $cmp_cond);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 4 — Standardize
+# -------------------------------------------------------
+Section::Begin("Standardize the sample proportion");
+BEGIN_PGML
+Now find the z-score for [``\hat p = 0.12``].
+
+Use
+
+[``z = \dfrac{0.12 - p}{\sqrt{p(1-p)/n}}``]
+
+Enter the z-score: [____]
+END_PGML
+
+ANS($cmp_z);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 5 — Final Answer
+# -------------------------------------------------------
+Section::Begin("Final Answer");
+BEGIN_PGML
+Using your z-score, find the probability
+
+[``P(\hat p > 0.12) = P(Z > z)``]
+
+Enter the probability: [____]
+END_PGML
+
+ANS($cmp_final);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 6 — Interpretation
+# -------------------------------------------------------
+Section::Begin("Interpretation");
+BEGIN_PGML
+We did all the calculations assuming that the manufacturer's claim [``p=0.08``] is true.
+
+If you observe a sample proportion as high as [``0.12``] (or higher) in a sample of [``200``] items, would you be inclined to suspect the claim?
+
+Choose the best answer:
+
+1) No. A sample proportion of [``0.12``] is always close enough to [``0.08``].
+2) Yes. If the claim is true, getting [``\hat p \ge 0.12``] is fairly unlikely.
+3) No. Sample proportions this large happen about half the time.
+4) Yes. The sample proportion must equal the population proportion when [``n=200``].
+5) Not enough information.
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_interp);
+
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating) — hidden in Library Browser
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+
+ Section::Begin("Feedback");
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+BEGIN_PGML_SOLUTION
+**1. Identify the statistic.**
+
+The statistic here is the sample proportion [``\hat p``].
+
+The claim is that the population proportion is
+
+[``p = 0.08``]
+
+so
+
+[``1-p = 0.92``]
+
+and the sample size is
+
+[``n = 200``]
+
+**2. Write the sampling distribution facts for [``\hat p``].**
+
+When the normal approximation is justified,
+
+[``\mu_{\hat p} = p``]
+
+and
+
+[``\sigma_{\hat p} = \sqrt{\dfrac{p(1-p)}{n}}``]
+
+So,
+
+[``\mu_{\hat p} = 0.08``]
+
+and
+
+[``\sigma_{\hat p} = \sqrt{\dfrac{(0.08)(0.92)}{200}} \approx 0.01918``]
+
+**3. Check the success-failure conditions.**
+
+We compute
+
+[``np = (200)(0.08) = 16``]
+
+and
+
+[``n(1-p) = (200)(0.92) = 184``]
+
+Both values are at least [``5``], so the sampling distribution of [``\hat p``] is approximately normal.
+
+**4. Standardize [``\hat p = 0.12``].**
+
+We want
+
+[``P(\hat p > 0.12)``]
+
+First compute the z-score:
+
+[``z = \dfrac{0.12 - 0.08}{0.01918} \approx 2.085``]
+
+**5. Find the probability.**
+
+So
+
+[``P(\hat p > 0.12) = P(Z > 2.085)``]
+
+Using the standard normal table or calculator,
+
+[``P(Z > 2.085) \approx 0.0185``]
+
+**6. Interpret the result.**
+
+If the manufacturer's claim is true, the probability of getting a sample proportion as large as [``0.12``] is only about [``0.0185``].
+
+That is a small probability, so such a result would be unusual.
+
+So yes, observing [``\hat p \ge 0.12``] would make us suspicious of the claim.
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/SamplingDistributions/SamplingDistributions_Proportion_GuidedProblem3.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/SamplingDistributions/SamplingDistributions_Proportion_GuidedProblem3.pg
new file mode 100644
index 0000000000..25bdceb762
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/SamplingDistributions/SamplingDistributions_Proportion_GuidedProblem3.pg
@@ -0,0 +1,380 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project - Sampling Distribution of a Proportion: Battery First-Pass Rate (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Sampling Distributions)
+## Level(2)
+## KEYWORDS('sampling distribution','sample proportion','p-hat','normal approximation','conditions for normality','z-score','success rate','battery inspection')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser detection (LB stability)
+# ----------------------------------------------------------------
+$inLibraryBrowser = ($envir{isLibraryBrowser} || $envir{isLibrary} || 0);
+
+Context("Numeric");
+
+# =======================================================
+# Postfilter: add a hint ONLY when the answer is wrong
+# =======================================================
+sub HintIfWrong {
+ my $msg = shift;
+ return sub {
+ my $ans = shift;
+ if (defined($ans->{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+ return $ans;
+ };
+}
+
+# =======================================================
+# Data
+# =======================================================
+# p = true proportion of batteries that pass inspection on first attempt
+$p = Real(0.92);
+$q = Real(0.08);
+$n = 400;
+$cutoff = Real(0.89);
+
+# =======================================================
+# Correct numeric targets
+# =======================================================
+$mu_phat_exact = 0.92;
+$se_exact = 0.01356465996625053;
+$np_exact = 368;
+$nq_exact = 32;
+$z_exact = -2.2116293423234596;
+$p_final_exact = 0.013496143136201066;
+
+# =======================================================
+# Tolerances
+# =======================================================
+$tol_mu = 0.001;
+$tol_se = 0.001;
+$tol_n = 0.001;
+$tol_z = 0.03;
+$tol_p = 0.001;
+
+# =======================================================
+# Comparators
+# =======================================================
+$cmp_mu_phat = Real($mu_phat_exact)->cmp(tolType=>"absolute", tolerance=>$tol_mu)
+ ->withPostFilter(HintIfWrong("For p-hat, the mean is p."));
+
+$cmp_se = Real($se_exact)->cmp(tolType=>"absolute", tolerance=>$tol_se)
+ ->withPostFilter(HintIfWrong("The standard deviation of p-hat is sqrt(p(1-p)/n)."));
+
+$cmp_np = Real($np_exact)->cmp(tolType=>"absolute", tolerance=>$tol_n)
+ ->withPostFilter(HintIfWrong("Compute np using n=400 and p=0.92."));
+
+$cmp_nq = Real($nq_exact)->cmp(tolType=>"absolute", tolerance=>$tol_n)
+ ->withPostFilter(HintIfWrong("Compute n(1-p) using n=400 and 1-p=0.08."));
+
+# Step 3 MC: correct choice = 4
+$cmp_cond = Real(4)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return ($s == 4) ? 1 : 0;
+ }
+)->withPostFilter(HintIfWrong("The normal approximation for p-hat is justified when both np and n(1-p) are at least 5."));
+
+$cmp_z = Real($z_exact)->cmp(tolType=>"absolute", tolerance=>$tol_z)
+ ->withPostFilter(HintIfWrong("Use z = (0.89 - p)/sqrt(p(1-p)/n)."));
+
+$cmp_final = Real($p_final_exact)->cmp(tolType=>"absolute", tolerance=>$tol_p)
+ ->withPostFilter(HintIfWrong("This is a lower-tail probability: P(p-hat < 0.89) = P(Z < z)."));
+
+# Step 6 MC: correct choice = 2
+$cmp_interp = Real(2)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return ($s == 2) ? 1 : 0;
+ }
+)->withPostFilter(HintIfWrong("If the claim is true, getting p-hat <= 0.89 is fairly unlikely, so such a sample would make us suspicious."));
+
+# Rating checker
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(numbered=>1, can_open=>"always", is_open=>"always");
+} else {
+ Scaffold::Begin(numbered=>1, can_open=>"when_previous_correct", is_open=>"correct_or_first_incorrect");
+}
+
+# -------------------------------------------------------
+# Step 1 - Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A company claims that **92%** of its rechargeable batteries pass quality inspection on the first attempt.
+
+A random sample of [``n=400``] batteries is selected. Let [``\hat p``] be the sample proportion of batteries that pass inspection on the first attempt.
+
+(a) Verify that the sampling distribution of [``\hat p``] can be approximated by a normal distribution.
+
+(b) Assuming the company's claim is true, find [``P(\hat p < 0.89)``].
+
+(c) If, in a sample of [``400``] batteries, you observe a sample proportion as low as [``0.89``] or lower, would you be inclined to suspect the company's claim?
+
+Rounding: Round z-scores to 3 decimals and probabilities to 4 decimals.
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Step 2 - Main concept
+# -------------------------------------------------------
+Section::Begin("Main concept: sampling distribution of p-hat");
+BEGIN_PGML
+For a sample proportion [``\hat p``], the sampling distribution is approximately normal when the sample is random and the success-failure conditions are satisfied.
+
+When the approximation is valid,
+
+- [``\mu_{\hat p} = p``]
+- [``\sigma_{\hat p} = \sqrt{\dfrac{p(1-p)}{n}}``]
+
+Using [``p=0.92``] and [``n=400``]:
+
+Enter [``\mu_{\hat p}``]: [____]
+
+Enter [``\sigma_{\hat p}``]: [____]
+END_PGML
+
+ANS($cmp_mu_phat, $cmp_se);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 3 - Check normality conditions
+# -------------------------------------------------------
+Section::Begin("Check the normality conditions");
+BEGIN_PGML
+To justify the normal approximation for [``\hat p``], check the success-failure conditions:
+
+- [``np \ge 5``]
+- [``n(1-p) \ge 5``]
+
+1) Compute [``np``]: [____]
+
+2) Compute [``n(1-p)``]: [____]
+
+3) Is normal approximation justified in this case? Choose the best conclusion:
+
+1) No, because [``p``] is greater than [``0.50``].
+2) No, because [``\hat p``] is a proportion, not a mean.
+3) Yes, because [``n=400``] is greater than [``30``].
+4) Yes, because both [``np``] and [``n(1-p)``] are at least [``5``].
+5) No, because the population proportion is too close to [``1``].
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_np, $cmp_nq, $cmp_cond);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 4 - Standardize
+# -------------------------------------------------------
+Section::Begin("Standardize the sample proportion");
+BEGIN_PGML
+Now find the z-score for [``\hat p = 0.89``].
+
+Use
+
+[``z = \dfrac{0.89 - p}{\sqrt{p(1-p)/n}}``]
+
+Enter the z-score: [____]
+END_PGML
+
+ANS($cmp_z);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 5 - Final Answer
+# -------------------------------------------------------
+Section::Begin("Final Answer");
+BEGIN_PGML
+Using your z-score, find the probability
+
+[``P(\hat p < 0.89) = P(Z < z)``]
+
+Enter the probability: [____]
+END_PGML
+
+ANS($cmp_final);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 6 - Interpretation
+# -------------------------------------------------------
+Section::Begin("Interpretation");
+BEGIN_PGML
+We did all the calculations assuming that the company's claim [``p=0.92``] is true.
+
+If you observe a sample proportion as low as [``0.89``] (or lower) in a sample of [``400``] batteries, would you be inclined to suspect the claim?
+
+Choose the best answer:
+
+1) No. A sample proportion of [``0.89``] is always close enough to [``0.92``].
+2) Yes. If the claim is true, getting [``\hat p \le 0.89``] is fairly unlikely.
+3) No. Sample proportions this small happen about half the time.
+4) Yes. The sample proportion must equal the population proportion when [``n=400``].
+5) Not enough information.
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_interp);
+
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating) - hidden in Library Browser
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+
+ Section::Begin("Feedback");
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+BEGIN_PGML_SOLUTION
+**1. Identify the statistic.**
+
+The statistic here is the sample proportion [``\hat p``].
+
+The claimed population proportion is
+
+[``p = 0.92``]
+
+so
+
+[``1-p = 0.08``]
+
+and the sample size is
+
+[``n = 400``]
+
+**2. Write the sampling distribution facts for [``\hat p``].**
+
+When the normal approximation is justified,
+
+[``\mu_{\hat p} = p``]
+
+and
+
+[``\sigma_{\hat p} = \sqrt{\dfrac{p(1-p)}{n}}``]
+
+So,
+
+[``\mu_{\hat p} = 0.92``]
+
+and
+
+[``\sigma_{\hat p} = \sqrt{\dfrac{(0.92)(0.08)}{400}} \approx 0.01356``]
+
+**3. Check the success-failure conditions.**
+
+We compute
+
+[``np = (400)(0.92) = 368``]
+
+and
+
+[``n(1-p) = (400)(0.08) = 32``]
+
+Both values are at least [``5``], so the sampling distribution of [``\hat p``] is approximately normal.
+
+**4. Standardize [``\hat p = 0.89``].**
+
+We want
+
+[``P(\hat p < 0.89)``]
+
+First compute the z-score:
+
+[``z = \dfrac{0.89 - 0.92}{0.01356} \approx -2.212``]
+
+**5. Find the probability.**
+
+So
+
+[``P(\hat p < 0.89) = P(Z < -2.212)``]
+
+Using the standard normal table or calculator,
+
+[``P(Z < -2.212) \approx 0.0135``]
+
+**6. Interpret the result.**
+
+If the company's claim is true, the probability of getting a sample proportion as low as [``0.89``] is only about [``0.0135``].
+
+That is a small probability, so such a result would be unusual.
+
+So yes, observing [``\hat p \le 0.89``] would make us suspicious of the claim.
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
\ No newline at end of file
diff --git a/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/SamplingDistributions/SamplingDistributions_Proportion_GuidedProblem4.pg b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/SamplingDistributions/SamplingDistributions_Proportion_GuidedProblem4.pg
new file mode 100644
index 0000000000..be9cf8d7be
--- /dev/null
+++ b/Contrib/DawsonCollege/Probability_Statistics/GuidedProblems/SamplingDistributions/SamplingDistributions_Proportion_GuidedProblem4.pg
@@ -0,0 +1,348 @@
+## DESCRIPTION
+## WeBWorK Guided Problems Project — Sampling Distribution of a Proportion: Hospital Recovery Claim (Guided / Scaffolded)
+## ENDDESCRIPTION
+##
+## Institution(Dawson College)
+## Author(Mehdi Moodi)
+## DBsubject(Statistics)
+## DBchapter(Probability)
+## DBsection(Sampling Distributions)
+## Level(2)
+## KEYWORDS('sampling distribution','sample proportion','p-hat','normal approximation','conditions for normality','z-score','hospital','recovery rate')
+
+DOCUMENT();
+
+loadMacros(
+ "PGstandard.pl",
+ "PGanswermacros.pl",
+ "MathObjects.pl",
+ "PGML.pl",
+ "scaffold.pl",
+ "answerHints.pl",
+ "parserRadioButtons.pl",
+);
+
+TEXT(beginproblem());
+
+# ----------------------------------------------------------------
+# PILOT: usefulness rating toggle (ACTIVE)
+# ----------------------------------------------------------------
+$ENABLE_GP_RATING = 1;
+
+# ----------------------------------------------------------------
+# Library Browser detection (LB stability)
+# ----------------------------------------------------------------
+$inLibraryBrowser = ($envir{isLibraryBrowser} || $envir{isLibrary} || 0);
+
+Context("Numeric");
+
+# =======================================================
+# Postfilter: add a hint ONLY when the answer is wrong
+# =======================================================
+sub HintIfWrong {
+ my $msg = shift;
+ return sub {
+ my $ans = shift;
+ if (defined($ans->{score}) && $ans->{score} < 1) {
+ $ans->{ans_message} = "" unless defined($ans->{ans_message});
+ $ans->{ans_message} .= " $msg";
+ }
+ return $ans;
+ };
+}
+
+# =======================================================
+# Data
+# =======================================================
+# Claim: 90% recover without complications
+$p = Real(0.90);
+$q = Real(0.10);
+$n = 225;
+$x = 199;
+$phat_obs = Real($x / $n);
+
+# =======================================================
+# Correct numeric targets
+# =======================================================
+$phat_exact = 0.8844444444444445;
+$np_exact = 202.5;
+$nq_exact = 22.5;
+$se_exact = 0.02;
+$z_exact = -0.7777777777777773;
+$p_final_exact = 0.218350015361379;
+
+# =======================================================
+# Tolerances
+# =======================================================
+$tol_phat = 0.001;
+$tol_n = 0.01;
+$tol_se = 0.001;
+$tol_z = 0.03;
+$tol_p = 0.001;
+
+# =======================================================
+# Comparators
+# =======================================================
+$cmp_phat = Real($phat_exact)->cmp(tolType=>"absolute", tolerance=>$tol_phat)
+ ->withPostFilter(HintIfWrong("Sample proportion is number of successes divided by sample size: 199/225."));
+
+$cmp_np = Real($np_exact)->cmp(tolType=>"absolute", tolerance=>$tol_n)
+ ->withPostFilter(HintIfWrong("Use np with n=225 and p=0.90."));
+
+$cmp_nq = Real($nq_exact)->cmp(tolType=>"absolute", tolerance=>$tol_n)
+ ->withPostFilter(HintIfWrong("Use n(1-p) with n=225 and 1-p=0.10."));
+
+# Step 3 MC: correct choice = 4
+$cmp_cond = Real(4)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return ($s == 4) ? 1 : 0;
+ }
+)->withPostFilter(HintIfWrong("For p-hat, the normal approximation is justified when both np and n(1-p) are at least 5."));
+
+$cmp_se = Real($se_exact)->cmp(tolType=>"absolute", tolerance=>$tol_se)
+ ->withPostFilter(HintIfWrong("Use sqrt(p(1-p)/n) with p=0.90 and n=225."));
+
+$cmp_z = Real($z_exact)->cmp(tolType=>"absolute", tolerance=>$tol_z)
+ ->withPostFilter(HintIfWrong("Use z = (p-hat - p)/sqrt(p(1-p)/n), with p-hat = 199/225 and p = 0.90."));
+
+$cmp_final = Real($p_final_exact)->cmp(tolType=>"absolute", tolerance=>$tol_p)
+ ->withPostFilter(HintIfWrong("This is a lower-tail probability: P(p-hat <= observed) = P(Z < z)."));
+
+# Step 6 MC: correct choice = 3
+$cmp_interp = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return ($s == 3) ? 1 : 0;
+ }
+)->withPostFilter(HintIfWrong("If the claim is true, the observed sample result is not rare enough to cast serious doubt on the claim."));
+
+# Rating checker
+$cmp_rating = Real(3)->cmp(
+ checker => sub {
+ my ($correct, $student, $ansHash) = @_;
+ return 0 unless defined $student;
+ my $s = $student->value;
+ return 0 unless defined $s;
+ return 0 unless $s == int($s);
+ return 0 unless ($s >= 1 && $s <= 5);
+ return 1;
+ }
+);
+
+# =======================================================
+# Scaffold setup
+# =======================================================
+if ($inLibraryBrowser) {
+ Scaffold::Begin(numbered=>1, can_open=>"always", is_open=>"always");
+} else {
+ Scaffold::Begin(numbered=>1, can_open=>"when_previous_correct", is_open=>"correct_or_first_incorrect");
+}
+
+# -------------------------------------------------------
+# Step 1 — Problem Statement
+# -------------------------------------------------------
+Section::Begin("Problem Statement");
+BEGIN_PGML
+A hospital claims that **90%** of patients recover from a certain outpatient procedure without complications.
+
+A patient advocacy group reviewed [``225``] randomly selected cases; [``199``] of those patients recovered without complications.
+
+(a) Compute the sample proportion of patients who recovered without complications.
+
+(b) Confirm that the sample is large enough to assume that the sample proportion is approximately normally distributed. Use [``p=0.90``], corresponding to the assumption that the hospital's claim is valid.
+
+(c) Assuming the hospital's claim is true, find the probability that a sample of size [``225``] would produce a sample proportion as low as was observed in this sample.
+
+(d) Based on the answer to part (c), draw a conclusion about the hospital's claim.
+
+Rounding: Round z-scores to 3 decimals and probabilities to 4 decimals.
+END_PGML
+Section::End();
+
+# -------------------------------------------------------
+# Step 2 — Compute the sample proportion
+# -------------------------------------------------------
+Section::Begin("Compute the sample proportion");
+BEGIN_PGML
+The observed sample proportion is
+
+[``\hat p = \dfrac{\text{number of recoveries}}{\text{sample size}}``]
+
+Enter the observed sample proportion:
+
+[____]
+END_PGML
+
+ANS($cmp_phat);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 3 — Check normality conditions
+# -------------------------------------------------------
+Section::Begin("Check the normality conditions");
+BEGIN_PGML
+To justify the normal approximation for [``\hat p``], check the success-failure conditions using the claimed value [``p=0.90``]:
+
+- [``np \ge 5``]
+- [``n(1-p) \ge 5``]
+
+1) Compute [``np``]: [____]
+
+2) Compute [``n(1-p)``]: [____]
+
+3) Is normal approximation justified in this case? Choose the best conclusion:
+
+1) No, because [``p``] is greater than [``0.50``].
+2) No, because [``\hat p``] is a proportion, not a mean.
+3) Yes, because [``n=225``] is greater than [``30``].
+4) Yes, because both [``np``] and [``n(1-p)``] are at least [``5``].
+5) No, because the observed sample proportion is not exactly [``0.90``].
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_np, $cmp_nq, $cmp_cond);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 4 — Standardize the observed result
+# -------------------------------------------------------
+Section::Begin("Standardize the observed result");
+BEGIN_PGML
+Assuming the hospital's claim is true, the sampling distribution of [``\hat p``] is approximately normal with
+
+[``\sigma_{\hat p} = \sqrt{\dfrac{p(1-p)}{n}}``]
+
+1) Compute the standard deviation of [``\hat p``]: [____]
+
+2) Compute the z-score of the observed sample proportion:
+
+[``z = \dfrac{\hat p - p}{\sqrt{p(1-p)/n}}``]
+
+Enter the z-score: [____]
+END_PGML
+
+ANS($cmp_se, $cmp_z);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 5 — Final Answer
+# -------------------------------------------------------
+Section::Begin("Final Answer");
+BEGIN_PGML
+Now find the probability that a sample of size [``225``] would produce a sample proportion as low as the one observed:
+
+[``P(\hat p \le \text{observed value}) = P(Z < z)``]
+
+Enter the probability: [____]
+END_PGML
+
+ANS($cmp_final);
+
+Section::End();
+
+# -------------------------------------------------------
+# Step 6 — Interpretation
+# -------------------------------------------------------
+Section::Begin("Interpretation");
+BEGIN_PGML
+We did all the calculations assuming that the hospital's claim [``p=0.9``] is true. Based on the probability you found, what is the best conclusion about the hospital's claim?
+
+1) The claim must be false, because the observed sample proportion is below [``0.90``].
+2) The claim is doubtful, because the observed result would almost never happen if the claim were true.
+3) The observed result is not unusual enough to cast doubt on the claim, so the claim is not suspicious.
+4) The claim must be true, because the normal approximation applies.
+5) There is no way to make any conclusion from the sample.
+
+Enter the number (1-5): [____]
+END_PGML
+
+ANS($cmp_interp);
+
+Section::End();
+
+# -------------------------------------------------------
+# Feedback (rating) — hidden in Library Browser
+# -------------------------------------------------------
+if ($ENABLE_GP_RATING && !$inLibraryBrowser) {
+
+ Section::Begin("Feedback");
+
+ BEGIN_PGML
+How useful was this Guided Problem for you?
+
+(1 = not useful, 2 = slightly useful, 3 = useful, 4 = very useful, 5 = extremely useful)
+
+Note: Consider using the Email Instructor button below to suggest improvements.
+
+Rating (1-5): [____]
+END_PGML
+
+ ANS($cmp_rating);
+
+ Section::End();
+}
+
+Scaffold::End();
+
+BEGIN_PGML_SOLUTION
+**1. Compute the sample proportion.**
+
+The observed sample proportion is
+
+[``\hat p = \dfrac{199}{225} \approx 0.8844``]
+
+**2. Check that the sample is large enough for a normal approximation.**
+
+Using the claimed population proportion [``p=0.90``],
+
+[``np = (225)(0.90) = 202.5``]
+
+and
+
+[``n(1-p) = (225)(0.10) = 22.5``]
+
+Both values are at least [``5``], so the sampling distribution of [``\hat p``] is approximately normal.
+
+**3. Compute the standard deviation of [``\hat p``].**
+
+[``\sigma_{\hat p} = \sqrt{\dfrac{(0.90)(0.10)}{225}} = \sqrt{0.0004} = 0.02``]
+
+**4. Standardize the observed result.**
+
+We want the probability of getting a sample proportion as low as the one observed.
+
+First compute the z-score:
+
+[``z = \dfrac{0.8844 - 0.90}{0.02} \approx -0.778``]
+
+**5. Find the probability.**
+
+So
+
+[``P(\hat p \le 0.8844) = P(Z < -0.778) \approx 0.2184``]
+
+**6. Draw a conclusion.**
+
+If the hospital's claim is true, a sample result this low would happen with probability about [``0.2184``].
+
+That is not a small probability, so the observed result is not unusual enough to cast doubt on the claim.
+
+So the hospital's claim is **not suspicious** based on this sample.
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
\ No newline at end of file