# Changes: Discrete Demand & Tiered Historical Display ## Summary Made demand values discrete (integer-only) and split historical demand visibility into two tiers: - **Basic (everyone)**: See past discrete demand values only - **Advanced (forecasting tool users only)**: See past demand values + summary statistics (mean, std, min, max, n) ## Changes Made ### 1. Discrete Demand Generation (`newsvendor/__init__.py`) #### In `creating_session()`: - **Line ~90**: Synthetic history generation now rounds to integers: ```python hist = [float(max(0, round(np.random.normal(mean_hist, std_hist)))) for _ in range(C.HISTORY_SAMPLES)] ``` - **Line ~110**: Fallback synthetic history also rounds to integers: ```python hist = [float(max(0, round(np.random.normal(mean_hist, std_hist)))) for _ in range(C.HISTORY_SAMPLES)] ``` - **Line ~120**: Actual demand per round now rounded to integers: ```python draw = np.random.normal(player.mean_demand, player.std_demand) player.actual_demand = float(max(0, round(draw))) ``` ### 2. Historical Demand Display (`Order.vars_for_template`) #### Formatting changes: - **Line ~177**: Format history as integers without decimals: ```python formatted_history = [f"{int(v)}" for v in actual_hist] ``` - **Line ~180-181**: Min/max stored as integers: ```python hist_min = int(np.min(actual_hist)) if actual_hist else None hist_max = int(np.max(actual_hist)) if actual_hist else None ``` - **Line ~338-339**: Min/max passed to template as integers: ```python min=hist_min if hist_min is not None else None, # Already int max=hist_max if hist_max is not None else None, # Already int ``` ### 3. Results Page Display #### In `Results.vars_for_template`: - **Line ~415**: Actual demand shown as integer: ```python actual_demand=int(player.actual_demand), # Display as discrete integer ``` #### In feedback display: - **Line ~314**: Last round's demand shown as integer: ```python actual=int(pv['actual_demand_history'][idx]) if pv.get('actual_demand_history') else None, ``` ### 4. Template Changes (`newsvendor/Order.html`) #### Historical Demand section (Lines 17-32): - Everyone sees: List of discrete past demand values - Forecasting tool users additionally see: Summary statistics in a separate line below the values **Before:** ```html

Past actual demand from your completed rounds.

mean={{ history_stats.mean }}, std={{ history_stats.std }}, ...

``` **After:** ```html

Past actual demand from your completed rounds:

{% if show_demand_forecast %}

Summary statistics: mean={{ history_stats.mean }}, ...

{% endif %} ``` ## Access Control by Tool Level | Tool Count | Access Level | What They See | |-----------|--------------|---------------| | 1 (None) | Basic | Past demand values only (after Round 1) | | 2+ (Forecasting) | Advanced | Past demand values + summary stats (mean, std, min, max, n) | ## Testing Recommendations 1. **Test discrete demand generation**: - Start a new session - Check that `actual_demand` values are always integers (no decimals) - Verify on Results page 2. **Test basic access (tool_count=1)**: - Assign participant with `tool_count=1` - After Round 1, verify Historical Demand shows only discrete values - Confirm NO summary statistics are visible 3. **Test advanced access (tool_count>=2)**: - Assign participant with `tool_count=2` or higher - After Round 1, verify Historical Demand shows discrete values AND summary stats - Confirm stats line appears below the demand values 4. **Test data consistency**: - Verify demand values match between: - Results page display - Historical Demand on next Order page - Feedback tool (if available) - Dashboard charts (if available)