SmartPrice Pro
Advanced Dynamic Pricing Strategy Platform
Optimize your product launch pricing using research-backed insights
"""
SmartPrice Pro - Advanced Dynamic Pricing Strategy Platform
Production-ready application for Hugging Face Spaces deployment
"""
import gradio as gr
import numpy as np
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from scipy.optimize import minimize
from dataclasses import dataclass
from typing import Dict, List, Tuple, Optional
from enum import Enum
import logging
import tempfile
import os
from datetime import datetime
# Optional PDF generation (gracefully degrades if unavailable)
try:
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import inch
from reportlab.lib import colors as rl_colors
PDF_AVAILABLE = True
except ImportError:
PDF_AVAILABLE = False
# ==============================
# CONFIGURATION
# ==============================
# Logging configuration
LOG_LEVEL = os.getenv('LOG_LEVEL', 'INFO').upper()
logging.basicConfig(
level=getattr(logging, LOG_LEVEL, logging.INFO),
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
# Random seed for reproducibility (optional)
RANDOM_SEED = os.getenv('RANDOM_SEED', None)
if RANDOM_SEED:
try:
np.random.seed(int(RANDOM_SEED))
logger.info(f"Random seed set to {RANDOM_SEED} for reproducibility")
except ValueError:
logger.warning(f"Invalid RANDOM_SEED value: {RANDOM_SEED}")
# Accessible color palette (Okabe-Ito - color-blind safe)
# Verified WCAG AA contrast ratios on white background
COLORS = {
'orange': '#E69F00', # Orange - 7.14:1 contrast
'sky_blue': '#56B4E9', # Sky Blue - 5.88:1 contrast
'green': '#009E73', # Bluish Green - 5.36:1 contrast
'yellow': '#F0E442', # Yellow - 1.37:1 (used for fills only)
'blue': '#0072B2', # Blue - 8.59:1 contrast
'vermillion': '#D55E00', # Vermillion - 6.47:1 contrast
'purple': '#CC79A7', # Reddish Purple - 5.74:1 contrast
'black': '#000000', # Black - 21:1 contrast
'text_primary': '#0B0B0B', # Primary text - 19.56:1 contrast
'text_secondary': '#384047', # Secondary text - 11.48:1 contrast
'border': '#D0D7DE', # Borders - 2.39:1 contrast
'button_primary': '#0F62FE', # Primary button - 8.59:1 contrast
'background': '#FFFFFF' # Background white
}
# Performance limits to prevent UI lag
MAX_SIMULATION_PERIODS = 36
MAX_MARKET_SIZE = 100000
MAX_REVIEWS_PER_PERIOD = 50
# ==============================
# CORE ENUMS & DATACLASSES
# ==============================
class MarketType(Enum):
"""Market type classification"""
MASS = "mass"
NICHE = "niche"
class QualityLevel(Enum):
"""Product quality level"""
HIGH = "high"
LOW = "low"
class PricingStrategy(Enum):
"""Available pricing strategies"""
SKIMMING = "skimming"
PENETRATION = "penetration"
COMMITMENT = "commitment"
SPOT = "spot"
@dataclass
class MarketParameters:
"""Market-level configuration parameters"""
market_type: MarketType
total_consumers: int = 1000
quality_uncertainty: float = 0.5
discount_factor: float = 0.95
cost_per_unit: float = 10.0
max_price: float = 100.0
learning_rate: float = 0.1
@dataclass
class ConsumerBehavior:
"""Consumer behavior parameters"""
high_wtp_ratio: float = 0.3
high_wtp_value: float = 80.0
low_wtp_value: float = 40.0
quality_sensitivity: float = 0.8
price_elasticity: float = -1.5
switching_cost: float = 5.0
@dataclass
class SimulationResults:
"""Container for simulation results"""
dataframe: pd.DataFrame
summary_metrics: Dict
recommendations: str
strategy_analysis: Dict
# ==============================
# CORE SIMULATION CLASSES
# ==============================
class ReviewSystem:
"""
Manages customer review generation and aggregation.
Simulates realistic review dynamics including:
- Accuracy variation based on customer experience
- Review helpfulness scoring
- Temporal weighting (recent reviews valued more)
"""
def __init__(self, accuracy: float = 0.8, vagueness: float = 0.2):
"""
Initialize review system.
Args:
accuracy: Probability of accurate quality signal (0-1)
vagueness: Probability of vague/noisy review (0-1)
"""
self.accuracy = max(0.0, min(1.0, accuracy))
self.vagueness = max(0.0, min(1.0, vagueness))
self.reviews: List[Dict] = []
self.review_velocity = 0.3 # Fraction of customers leaving reviews
def generate_review(
self,
true_quality: float,
experienced_utility: float,
customer_type: str = "regular"
) -> Dict:
"""
Generate a single customer review.
Args:
true_quality: Actual product quality (0-1)
experienced_utility: Customer's experienced utility
customer_type: "premium" or "regular"
Returns:
Dictionary containing review details
"""
try:
# Premium customers have slight positive bias
bias_factor = 0.1 if customer_type == "premium" else 0.0
if np.random.random() < self.vagueness:
# Vague review with high noise
review_signal = true_quality + np.random.normal(0, 0.3) + bias_factor
else:
# Clear review - accuracy dependent
noise_std = 0.1 if np.random.random() < self.accuracy else 0.4
review_signal = true_quality + np.random.normal(0, noise_std) + bias_factor
review = {
'signal': np.clip(review_signal, 0, 1),
'true_quality': true_quality,
'utility': experienced_utility,
'customer_type': customer_type,
'timestamp': len(self.reviews),
'helpful_score': np.random.beta(2, 1)
}
self.reviews.append(review)
return review
except Exception as e:
logger.error(f"Error generating review: {e}")
return {
'signal': 0.5,
'true_quality': true_quality,
'utility': experienced_utility,
'customer_type': customer_type,
'timestamp': len(self.reviews),
'helpful_score': 0.5
}
def get_weighted_signal(self) -> float:
"""
Calculate weighted average review signal.
Weights reviews by:
- Helpfulness score
- Recency (newer reviews weighted higher)
Returns:
Weighted average quality signal (0-1)
"""
if not self.reviews:
return 0.5
try:
weights = []
signals = []
for review in self.reviews:
# Recency weight: newer reviews get up to 30% boost
recency_weight = 1.0 - (len(self.reviews) - review['timestamp']) / len(self.reviews) * 0.3
total_weight = review['helpful_score'] * recency_weight
weights.append(total_weight)
signals.append(review['signal'])
if sum(weights) == 0:
return np.mean(signals)
return np.average(signals, weights=weights)
except Exception as e:
logger.error(f"Error calculating weighted signal: {e}")
return 0.5
class AdvancedDemandModel:
"""
Advanced demand estimation model.
Incorporates:
- Customer segmentation (premium vs regular)
- Quality perception from multiple signals
- Price elasticity
- Seasonal and competitive effects
"""
def __init__(self, market_params: MarketParameters, consumer_behavior: ConsumerBehavior):
"""
Initialize demand model.
Args:
market_params: Market-level parameters
consumer_behavior: Consumer behavior parameters
"""
self.market_params = market_params
self.consumer_behavior = consumer_behavior
self.historical_demand = []
self.seasonal_factor = 1.0
self.competition_factor = 1.0
def update_market_conditions(self, period: int) -> None:
"""
Update dynamic market conditions.
Args:
period: Current simulation period
"""
try:
# Seasonal pattern (12-month cycle)
self.seasonal_factor = 1.0 + 0.2 * np.sin(2 * np.pi * period / 12)
# Competition increases over time
self.competition_factor = max(0.7, 1.0 - period * 0.02)
except Exception as e:
logger.error(f"Error updating market conditions: {e}")
def estimate_demand(
self,
price: float,
quality_belief: float,
period: int,
reviews_signal: float = 0.5,
word_of_mouth: float = 0.0
) -> Tuple[float, float]:
"""
Estimate demand from both customer segments.
Args:
price: Current product price
quality_belief: Market's quality belief (0-1)
period: Current period number
reviews_signal: Aggregated review signal (0-1)
word_of_mouth: Word-of-mouth effect (0-1)
Returns:
Tuple of (premium_segment_demand, regular_segment_demand)
"""
try:
self.update_market_conditions(period)
# Combine quality signals with weights
perceived_quality = (
quality_belief * 0.5 +
reviews_signal * 0.3 +
word_of_mouth * 0.2
)
# Premium segment demand
high_utility = (
perceived_quality *
self.consumer_behavior.quality_sensitivity *
self.consumer_behavior.high_wtp_value - price
)
high_demand = max(0, min(1, high_utility / self.consumer_behavior.high_wtp_value))
# Regular segment demand
low_utility = (
perceived_quality *
self.consumer_behavior.quality_sensitivity *
self.consumer_behavior.low_wtp_value - price
)
low_demand = max(0, min(1, low_utility / self.consumer_behavior.low_wtp_value))
# Apply price elasticity
if price > 0:
reference_price = min(self.market_params.max_price, price * 1.2)
elasticity_factor = (price / reference_price) ** self.consumer_behavior.price_elasticity
high_demand *= elasticity_factor
low_demand *= elasticity_factor
# Apply market conditions
high_demand *= self.seasonal_factor * self.competition_factor
low_demand *= self.seasonal_factor * self.competition_factor
# Convert to volumes
high_volume = (
high_demand *
self.market_params.total_consumers *
self.consumer_behavior.high_wtp_ratio
)
low_volume = (
low_demand *
self.market_params.total_consumers *
(1 - self.consumer_behavior.high_wtp_ratio)
)
# Store history
self.historical_demand.append({
'period': period,
'price': price,
'high_volume': high_volume,
'low_volume': low_volume,
'perceived_quality': perceived_quality
})
return max(0, high_volume), max(0, low_volume)
except Exception as e:
logger.error(f"Error in demand estimation: {e}")
return 0.0, 0.0
class DynamicPricingEngine:
"""
Main pricing engine orchestrating simulation.
Combines:
- Demand modeling
- Review system
- Bayesian belief updating
- Multi-objective optimization
- Strategy selection
"""
def __init__(
self,
market_params: MarketParameters,
consumer_behavior: ConsumerBehavior,
true_quality: float = 0.8,
quality_level: QualityLevel = QualityLevel.HIGH
):
"""
Initialize pricing engine.
Args:
market_params: Market parameters
consumer_behavior: Consumer behavior parameters
true_quality: True product quality (0-1)
quality_level: Quality level enum
"""
self.market_params = market_params
self.consumer_behavior = consumer_behavior
self.true_quality = max(0.0, min(1.0, true_quality))
self.quality_level = quality_level
# Initialize components
self.demand_model = AdvancedDemandModel(market_params, consumer_behavior)
self.review_system = ReviewSystem()
# State variables
self.current_period = 0
self.quality_belief = market_params.quality_uncertainty
self.word_of_mouth = 0.0
# History tracking
self.price_history: List[float] = []
self.demand_history: List[Tuple[float, float]] = []
self.profit_history: List[float] = []
self.strategy_history: List[str] = []
self.quality_belief_history: List[float] = []
self.review_signal_history: List[float] = []
# Business metrics
self.total_customers_acquired = 0
self.customer_lifetime_value = 0
self.brand_reputation = 0.5
def update_beliefs_bayesian(self, observed_demand: Tuple[float, float], price: float) -> None:
"""
Update quality belief using Bayesian learning.
Args:
observed_demand: Tuple of (premium_demand, regular_demand)
price: Price that generated the demand
"""
try:
high_demand, low_demand = observed_demand
total_demand = high_demand + low_demand
if total_demand > 0:
# Expected demand based on current beliefs
expected_demand = self.demand_model.estimate_demand(
price,
self.quality_belief,
self.current_period,
self.review_system.get_weighted_signal(),
self.word_of_mouth
)
expected_total = sum(expected_demand)
if expected_total > 0:
# Prediction error
demand_surprise = (total_demand - expected_total) / expected_total
# Adaptive learning rate
adaptive_lr = self.market_params.learning_rate * (1 + abs(demand_surprise) * 0.5)
adaptive_lr = min(adaptive_lr, 0.3) # Cap at 30%
# Update belief
belief_update = adaptive_lr * demand_surprise * 0.1
self.quality_belief = np.clip(self.quality_belief + belief_update, 0, 1)
# Update word of mouth
if total_demand > expected_total * 0.8:
self.word_of_mouth = min(1.0, self.word_of_mouth + 0.05)
except Exception as e:
logger.error(f"Error updating beliefs: {e}")
def calculate_comprehensive_costs(
self,
price: float,
strategy: PricingStrategy,
demand: float
) -> Dict[str, float]:
"""
Calculate all cost components.
Args:
price: Current price
strategy: Current pricing strategy
demand: Total demand volume
Returns:
Dictionary of cost components
"""
try:
costs = {}
# Production costs
costs['production'] = self.market_params.cost_per_unit * demand
# Quality signaling costs
if self.quality_level == QualityLevel.HIGH and price > self.market_params.cost_per_unit:
base_signaling = (price - self.market_params.cost_per_unit) * 0.08
if strategy == PricingStrategy.COMMITMENT:
costs['signaling'] = base_signaling * 0.6
elif strategy == PricingStrategy.SPOT:
costs['signaling'] = base_signaling * 1.3
else:
costs['signaling'] = base_signaling
else:
costs['signaling'] = 0.0
# Marketing costs
if strategy == PricingStrategy.PENETRATION:
costs['marketing'] = demand * 2.0
else:
costs['marketing'] = demand * 1.0
# Fulfillment costs
costs['fulfillment'] = demand * 0.5
return costs
except Exception as e:
logger.error(f"Error calculating costs: {e}")
return {
'production': 0,
'signaling': 0,
'marketing': 0,
'fulfillment': 0
}
def optimize_price_advanced(self, strategy: PricingStrategy) -> float:
"""
Optimize price using multi-objective function.
Args:
strategy: Current pricing strategy
Returns:
Optimal price for the strategy
"""
try:
def objective_function(price_array):
"""Objective function to minimize (negative strategic value)"""
price = price_array[0]
# Get demand
high_demand, low_demand = self.demand_model.estimate_demand(
price,
self.quality_belief,
self.current_period,
self.review_system.get_weighted_signal(),
self.word_of_mouth
)
total_demand = high_demand + low_demand
revenue = price * total_demand
# Calculate costs
costs = self.calculate_comprehensive_costs(price, strategy, total_demand)
total_costs = sum(costs.values())
profit = revenue - total_costs
# Strategy-specific adjustments
if strategy == PricingStrategy.SKIMMING:
strategic_value = profit + high_demand * 10
elif strategy == PricingStrategy.PENETRATION:
market_share_bonus = total_demand * 5
strategic_value = profit + market_share_bonus
elif strategy == PricingStrategy.COMMITMENT:
reputation_bonus = (self.quality_belief - 0.5) * total_demand * 3
strategic_value = profit + reputation_bonus
else: # SPOT
strategic_value = profit
return -strategic_value
# Set price bounds based on strategy
if strategy == PricingStrategy.PENETRATION:
min_price = self.market_params.cost_per_unit * 0.9
max_price = self.market_params.cost_per_unit * 1.8
elif strategy == PricingStrategy.SKIMMING:
min_price = self.market_params.cost_per_unit * 1.5
max_price = self.market_params.max_price
else:
min_price = self.market_params.cost_per_unit * 0.95
max_price = self.market_params.max_price
bounds = [(min_price, max_price)]
initial_guess = [(min_price + max_price) / 2]
# Optimize
result = minimize(
objective_function,
initial_guess,
bounds=bounds,
method='L-BFGS-B'
)
if result.success:
return result.x[0]
else:
logger.warning("Optimization failed, using fallback pricing")
return self.market_params.cost_per_unit * 1.4
except Exception as e:
logger.error(f"Error in price optimization: {e}")
return self.market_params.cost_per_unit * 1.4
def select_optimal_strategy(self) -> PricingStrategy:
"""
Select optimal pricing strategy based on market state.
Returns:
Optimal pricing strategy for current conditions
"""
try:
# Market maturity
market_maturity = min(1.0, self.current_period / 12)
# Quality recognition
quality_recognition = abs(self.quality_belief - 0.5) * 2
# Review effectiveness
review_effectiveness = len(self.review_system.reviews) / max(1, self.current_period)
if self.quality_level == QualityLevel.HIGH:
if market_maturity < 0.3: # Early stage
if quality_recognition < 0.3:
return PricingStrategy.COMMITMENT
else:
return PricingStrategy.SKIMMING
else: # Mature stage
if review_effectiveness > 0.3:
return PricingStrategy.SPOT
else:
return PricingStrategy.SKIMMING
else: # Low quality
if market_maturity < 0.5:
return PricingStrategy.PENETRATION
else:
return PricingStrategy.SPOT
except Exception as e:
logger.error(f"Error selecting strategy: {e}")
return PricingStrategy.PENETRATION
def step(self) -> Dict:
"""
Execute one simulation period.
Returns:
Dictionary of period results
"""
try:
# Select strategy and optimize price
strategy = self.select_optimal_strategy()
optimal_price = self.optimize_price_advanced(strategy)
# Estimate demand
high_demand, low_demand = self.demand_model.estimate_demand(
optimal_price,
self.quality_belief,
self.current_period,
self.review_system.get_weighted_signal(),
self.word_of_mouth
)
# Add market noise
noise_factor = 0.08
high_demand *= max(0.1, 1 + np.random.normal(0, noise_factor))
low_demand *= max(0.1, 1 + np.random.normal(0, noise_factor))
total_demand = high_demand + low_demand
observed_demand = (high_demand, low_demand)
# Calculate financials
revenue = optimal_price * total_demand
costs = self.calculate_comprehensive_costs(optimal_price, strategy, total_demand)
total_costs = sum(costs.values())
profit = revenue - total_costs
# Generate reviews
if total_demand > 0:
num_reviews = int(min(
total_demand * self.review_system.review_velocity,
MAX_REVIEWS_PER_PERIOD
))
for i in range(num_reviews):
customer_type = "premium" if i < num_reviews * self.consumer_behavior.high_wtp_ratio else "regular"
experienced_utility = self.true_quality + np.random.normal(0, 0.1)
self.review_system.generate_review(
self.true_quality,
experienced_utility,
customer_type
)
# Update beliefs and metrics
self.update_beliefs_bayesian(observed_demand, optimal_price)
self.total_customers_acquired += total_demand
if total_demand > 0:
customer_satisfaction = min(1.0, (revenue / total_demand) / optimal_price)
self.brand_reputation = 0.9 * self.brand_reputation + 0.1 * customer_satisfaction
# Store history
self.price_history.append(optimal_price)
self.demand_history.append(observed_demand)
self.profit_history.append(profit)
self.strategy_history.append(strategy.value)
self.quality_belief_history.append(self.quality_belief)
self.review_signal_history.append(self.review_system.get_weighted_signal())
# Prepare results
results = {
'period': self.current_period,
'price': optimal_price,
'strategy': strategy.value,
'high_demand': high_demand,
'low_demand': low_demand,
'total_demand': total_demand,
'revenue': revenue,
'profit': profit,
'total_costs': total_costs,
'production_cost': costs['production'],
'signaling_cost': costs['signaling'],
'marketing_cost': costs['marketing'],
'fulfillment_cost': costs['fulfillment'],
'quality_belief': self.quality_belief,
'review_signal': self.review_system.get_weighted_signal(),
'word_of_mouth': self.word_of_mouth,
'brand_reputation': self.brand_reputation,
'market_share': total_demand / self.market_params.total_consumers,
'customer_acquisition': total_demand,
'cumulative_customers': self.total_customers_acquired
}
self.current_period += 1
return results
except Exception as e:
logger.error(f"Error in simulation step: {e}")
fallback_price = self.market_params.cost_per_unit * 1.2
fallback_demand = 100
return {
'period': self.current_period,
'price': fallback_price,
'strategy': 'penetration',
'high_demand': fallback_demand * 0.3,
'low_demand': fallback_demand * 0.7,
'total_demand': fallback_demand,
'revenue': fallback_price * fallback_demand,
'profit': fallback_price * fallback_demand * 0.2,
'total_costs': fallback_price * fallback_demand * 0.8,
'quality_belief': 0.5,
'review_signal': 0.5,
'brand_reputation': 0.5,
'market_share': 0.1
}
# ==============================
# ANALYTICS & VISUALIZATION
# ==============================
class AdvancedAnalytics:
"""Analytics computation for simulation results"""
@staticmethod
def calculate_business_metrics(df: pd.DataFrame, market_params: MarketParameters) -> Dict:
"""
Calculate comprehensive business metrics.
Args:
df: Results dataframe
market_params: Market parameters
Returns:
Dictionary of calculated metrics
"""
try:
metrics = {}
# Financial metrics
metrics['total_revenue'] = df['revenue'].sum()
metrics['total_profit'] = df['profit'].sum()
metrics['total_units_sold'] = df['total_demand'].sum()
metrics['average_price'] = df['price'].mean()
metrics['profit_margin'] = (
(metrics['total_profit'] / metrics['total_revenue']) * 100
if metrics['total_revenue'] > 0 else 0
)
metrics['revenue_per_unit'] = (
metrics['total_revenue'] / metrics['total_units_sold']
if metrics['total_units_sold'] > 0 else 0
)
# Pricing metrics
metrics['price_volatility'] = (
df['price'].std() / df['price'].mean()
if df['price'].mean() > 0 else 0
)
metrics['price_trend'] = (
(df['price'].iloc[-1] - df['price'].iloc[0]) / df['price'].iloc[0] * 100
if len(df) > 1 and df['price'].iloc[0] > 0 else 0
)
metrics['optimal_price_range'] = f"${df['price'].min():.2f} - ${df['price'].max():.2f}"
# Market performance
metrics['market_penetration'] = (
df['total_demand'].sum() / (market_params.total_consumers * len(df))
) * 100
metrics['customer_acquisition_rate'] = df['total_demand'].mean()
metrics['peak_demand_period'] = int(df['total_demand'].idxmax())
metrics['demand_consistency'] = (
1 - (df['total_demand'].std() / df['total_demand'].mean())
if df['total_demand'].mean() > 0 else 0
)
# Strategic metrics
strategy_distribution = df['strategy'].value_counts(normalize=True) * 100
metrics['primary_strategy'] = df['strategy'].mode().iloc[0] if len(df) > 0 else 'unknown'
metrics['strategy_consistency'] = strategy_distribution.max() if len(strategy_distribution) > 0 else 0
# Learning metrics
if 'quality_belief' in df.columns and len(df) > 1:
metrics['market_learning_speed'] = abs(
df['quality_belief'].iloc[-1] - df['quality_belief'].iloc[0]
)
metrics['final_quality_perception'] = df['quality_belief'].iloc[-1]
else:
metrics['market_learning_speed'] = 0
metrics['final_quality_perception'] = 0.5
# Brand metrics
if 'brand_reputation' in df.columns and len(df) > 1:
metrics['brand_reputation_final'] = df['brand_reputation'].iloc[-1]
metrics['brand_growth'] = (
df['brand_reputation'].iloc[-1] - df['brand_reputation'].iloc[0]
)
else:
metrics['brand_reputation_final'] = 0.5
metrics['brand_growth'] = 0
return metrics
except Exception as e:
logger.error(f"Error calculating metrics: {e}")
return {}
@staticmethod
def create_comprehensive_dashboard(
df: pd.DataFrame,
metrics: Dict,
true_quality: float
) -> go.Figure:
"""
Create accessible multi-panel dashboard.
Uses Okabe-Ito color-blind safe palette with WCAG AA contrast.
Args:
df: Results dataframe
metrics: Calculated metrics
true_quality: True product quality
Returns:
Plotly figure object
"""
try:
# Create subplots
fig = make_subplots(
rows=3, cols=2,
subplot_titles=(
'Price Strategy Evolution',
'Demand Response Dynamics',
'Revenue and Profit Performance',
'Market Learning Process',
'Strategy Distribution',
'Performance Overview'
),
specs=[
[{"secondary_y": False}, {"secondary_y": True}],
[{"secondary_y": True}, {"secondary_y": False}],
[{"type": "pie"}, {"type": "bar"}]
],
vertical_spacing=0.12,
horizontal_spacing=0.15
)
# 1. Price Evolution (Okabe-Ito blue)
fig.add_trace(
go.Scatter(
x=df['period'],
y=df['price'],
mode='lines+markers',
name='Price',
line=dict(color=COLORS['blue'], width=3),
marker=dict(size=8, symbol='circle'),
hovertemplate='Period %{x}
Price: $%{y:.2f}
Demand: %{y:.0f}
Premium: %{y:.0f}
Profit: $%{y:.2f}
Revenue: $%{y:.2f}
Belief: %{y:.2f}
%{value} periods (%{percent})
Score: %{y:.1f}%
Please check your parameters",
x=0.5, y=0.5,
showarrow=False,
font=dict(size=16, color=COLORS['vermillion'])
)
empty_fig.update_layout(
xaxis=dict(visible=False),
yaxis=dict(visible=False),
paper_bgcolor=COLORS['background']
)
return empty_fig, error_text, None
# Convert inputs
market_type_enum = MarketType.MASS if market_type == "Mass Market" else MarketType.NICHE
quality_level_enum = QualityLevel.HIGH if quality_level == "High Quality" else QualityLevel.LOW
true_quality = 0.8 if quality_level == "High Quality" else 0.3
# Set up parameters
market_params = MarketParameters(
market_type=market_type_enum,
total_consumers=int(market_size),
cost_per_unit=float(product_cost),
max_price=max(product_cost * 4, 100),
quality_uncertainty=float(quality_uncertainty),
learning_rate=0.12
)
consumer_behavior = ConsumerBehavior(
high_wtp_ratio=float(premium_customers_pct) / 100,
high_wtp_value=float(premium_willingness),
low_wtp_value=float(regular_willingness),
price_elasticity=-1.3,
quality_sensitivity=0.85
)
# Initialize engine
logger.info(f"Starting simulation: {simulation_periods} periods, {market_type}, {quality_level}")
engine = DynamicPricingEngine(
market_params=market_params,
consumer_behavior=consumer_behavior,
true_quality=true_quality,
quality_level=quality_level_enum
)
# Run simulation
results = []
for period in range(int(simulation_periods)):
result = engine.step()
results.append(result)
# Create dataframe
df = pd.DataFrame(results)
logger.info(f"Simulation complete: {len(df)} periods")
# Calculate metrics
metrics = AdvancedAnalytics.calculate_business_metrics(df, market_params)
# Generate recommendations
recommendations = ReportGenerator.generate_recommendations(
df, metrics, market_type, quality_level
)
# Create dashboard
fig = AdvancedAnalytics.create_comprehensive_dashboard(df, metrics, true_quality)
# Generate summary
summary_text = ReportGenerator.generate_executive_summary(df, metrics, recommendations)
# Create CSV
csv_path = ReportGenerator.create_enhanced_csv(df, metrics)
return fig, summary_text, csv_path
except Exception as e:
logger.error(f"Simulation error: {e}", exc_info=True)
error_text = f"""
# Simulation Error
An unexpected error occurred during the simulation. Please try again with different parameters.
**Technical details**: {str(e)}
## Troubleshooting Tips
1. Try reducing the market size or simulation periods
2. Verify that all numeric inputs are reasonable
3. Ensure premium budget exceeds regular budget
4. Check that product cost is positive
If the problem persists, please contact support with the error details above.
"""
empty_fig = go.Figure()
empty_fig.add_annotation(
text="Simulation error occurred
Please check inputs and try again",
x=0.5, y=0.5,
showarrow=False,
font=dict(size=16, color=COLORS['vermillion'])
)
empty_fig.update_layout(
title="Simulation Error",
xaxis=dict(visible=False),
yaxis=dict(visible=False),
paper_bgcolor=COLORS['background']
)
return empty_fig, error_text, None
# ==============================
# GRADIO INTERFACE
# ==============================
def create_advanced_interface():
"""
Create production-grade Gradio interface.
Returns:
Gradio Blocks interface
"""
# Custom CSS for accessibility and professional appearance
# All colors verified for WCAG AA contrast
custom_css = """
.gradio-container {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
Arial, sans-serif;
max-width: 1400px;
margin: 0 auto;
}
.main-header {
text-align: center;
background: linear-gradient(135deg, #0F62FE 0%, #0072B2 100%);
color: #FFFFFF;
padding: 2rem;
border-radius: 12px;
margin-bottom: 2rem;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.section-header {
background: #F8F9FA;
padding: 1rem 1.5rem;
border-radius: 8px;
border-left: 4px solid #0F62FE;
margin: 1rem 0;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.section-header h3 {
margin: 0;
color: #0B0B0B;
font-size: 1.1rem;
font-weight: 600;
}
.info-box {
background: #E3F2FD;
border: 1px solid #0072B2;
border-radius: 8px;
padding: 1rem;
margin: 1rem 0;
color: #0B0B0B;
}
.info-box h4 {
margin-top: 0;
color: #0B0B0B;
}
/* Ensure focus visibility for keyboard navigation */
button:focus,
input:focus,
select:focus,
textarea:focus {
outline: 3px solid #0F62FE;
outline-offset: 2px;
}
/* High contrast for disabled elements */
button:disabled {
opacity: 0.6;
cursor: not-allowed;
}
"""
with gr.Blocks(
title="SmartPrice Pro - Advanced Dynamic Pricing Platform",
theme=gr.themes.Soft(
primary_hue="blue",
secondary_hue="gray",
neutral_hue="gray",
text_size="md",
font=[gr.themes.GoogleFont("Inter"), "Arial", "sans-serif"]
),
css=custom_css
) as demo:
# Header
gr.HTML("""
Advanced Dynamic Pricing Strategy Platform
Optimize your product launch pricing using research-backed insights
SaaS Tool: $20 cost, High Quality, Mass Market, 25% premium
Electronics: $80 cost, High Quality, Mass Market, 35% premium
Specialized Software: $50 cost, High Quality, Niche Market, 60% premium