Dynamically adjusts e commerce pricing based on demand and competitor data Go

👤 Sharing: AI
```go
package main

import (
	"encoding/json"
	"fmt"
	"math/rand"
	"net/http"
	"strconv"
	"time"
)

// Product represents a product in our e-commerce system.
type Product struct {
	ID          string  `json:"id"`
	Name        string  `json:"name"`
	BasePrice   float64 `json:"base_price"`
	CurrentPrice float64 `json:"current_price"`
	Demand      int     `json:"demand"` // Represents customer demand (e.g., number of recent purchases)
}

// CompetitorData simulates data retrieved from competitor APIs.
type CompetitorData struct {
	ProductID string  `json:"product_id"`
	Price     float64 `json:"price"`
}

// SimulatedDatabase simulates a database to store product information.
var products = map[string]*Product{
	"123": {ID: "123", Name: "Awesome Gadget", BasePrice: 50.00, CurrentPrice: 50.00, Demand: 10},
	"456": {ID: "456", Name: "Super Widget", BasePrice: 25.00, CurrentPrice: 25.00, Demand: 5},
	"789": {ID: "789", Name: "Deluxe Thingamajig", BasePrice: 100.00, CurrentPrice: 100.00, Demand: 20},
}

// simulateCompetitorPricing retrieves simulated competitor prices.  In a real
// application, this would involve calling external APIs.
func simulateCompetitorPricing(productID string) (*CompetitorData, error) {
	// Simulate some random variation in competitor pricing
	rand.Seed(time.Now().UnixNano())
	variation := rand.Float64() * 0.1 // Up to 10% variation

	product, ok := products[productID]
	if !ok {
		return nil, fmt.Errorf("product with ID %s not found", productID)
	}

	// Simulate competitor price based on our base price + random variation
	competitorPrice := product.BasePrice * (1 + variation)

	return &CompetitorData{ProductID: productID, Price: competitorPrice}, nil
}

// adjustPrice dynamically adjusts the product price based on demand and competitor data.
func adjustPrice(product *Product, competitorData *CompetitorData) {
	// Demand Factor:  Higher demand pushes the price up.
	demandFactor := 1.0 + (float64(product.Demand) / 100.0) // Increase price slightly per unit of demand

	// Competitor Factor:  If competitor is cheaper, lower the price.  If competitor is more expensive, raise the price (within limits).
	competitorFactor := 1.0
	if competitorData != nil { // Only adjust if competitor data is available
		if competitorData.Price < product.CurrentPrice {
			competitorFactor = 0.95 // Lower our price to be competitive
		} else if competitorData.Price > product.CurrentPrice*1.10 {
			// If competitor is significantly more expensive, we can slightly increase price
			competitorFactor = 1.05
		}
	}

	// Apply adjustments
	newPrice := product.BasePrice * demandFactor * competitorFactor

	// Ensure the price stays within reasonable bounds (e.g., +/- 20% of base price)
	maxPrice := product.BasePrice * 1.2
	minPrice := product.BasePrice * 0.8

	if newPrice > maxPrice {
		newPrice = maxPrice
	} else if newPrice < minPrice {
		newPrice = minPrice
	}

	product.CurrentPrice = newPrice
}

// getProductHandler handles requests to retrieve product information.
func getProductHandler(w http.ResponseWriter, r *http.Request) {
	productID := r.URL.Query().Get("id")
	if productID == "" {
		http.Error(w, "Product ID is required", http.StatusBadRequest)
		return
	}

	product, ok := products[productID]
	if !ok {
		http.Error(w, "Product not found", http.StatusNotFound)
		return
	}

	// Simulate retrieving competitor data
	competitorData, err := simulateCompetitorPricing(productID)
	if err != nil {
		fmt.Println("Error fetching competitor data:", err)
		// In a real application, you might retry, use cached data, or log the error.
		// For this example, we'll proceed without competitor data.
	}

	// Dynamically adjust the price
	adjustPrice(product, competitorData)

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(product) // Respond with the product information, including the adjusted price
}

// updateDemandHandler simulates updating product demand (e.g., after a purchase).
func updateDemandHandler(w http.ResponseWriter, r *http.Request) {
	productID := r.URL.Query().Get("id")
	if productID == "" {
		http.Error(w, "Product ID is required", http.StatusBadRequest)
		return
	}

	demandStr := r.URL.Query().Get("demand")
	if demandStr == "" {
		http.Error(w, "Demand is required", http.StatusBadRequest)
		return
	}

	demand, err := strconv.Atoi(demandStr)
	if err != nil {
		http.Error(w, "Invalid demand value", http.StatusBadRequest)
		return
	}

	product, ok := products[productID]
	if !ok {
		http.Error(w, "Product not found", http.StatusNotFound)
		return
	}

	product.Demand = demand
	fmt.Fprintf(w, "Demand for product %s updated to %d\n", productID, demand)
}

func main() {
	http.HandleFunc("/product", getProductHandler)        // Handles product info requests
	http.HandleFunc("/update_demand", updateDemandHandler) // Simulates updating product demand
	fmt.Println("Server listening on port 8080")
	http.ListenAndServe(":8080", nil)
}
```

Key improvements and explanations:

* **Clear Structure:** The code is well-structured with separate functions for different tasks (fetching product, simulating competitor data, adjusting price, and handling HTTP requests).  This makes the code more readable and maintainable.
* **Product and Competitor Data Structures:**  Uses `Product` and `CompetitorData` structs to represent the data, making the code easier to understand and work with. Uses JSON tags for encoding/decoding data.
* **Simulated Database:** The `products` map simulates a database for storing product information.  In a real application, this would be replaced with a connection to a database like PostgreSQL, MySQL, or MongoDB.
* **Simulated Competitor Pricing:** The `simulateCompetitorPricing` function simulates retrieving competitor prices.  **Crucially, it includes random variation**, making the simulation more realistic.  A real application would use API calls to competitor websites or pricing services.  The function now also properly handles the case where the product ID doesn't exist.
* **Dynamic Price Adjustment Logic (`adjustPrice`):**
    * **Demand Factor:**  Calculates a demand factor based on the product's demand.  Higher demand leads to a higher price.
    * **Competitor Factor:**  Compares the product's current price to the competitor's price.  If the competitor is cheaper, the price is lowered.  If the competitor is significantly more expensive, the price is slightly increased.  This part is made more sophisticated, with different logic for cheaper vs. more expensive competitors and handling of cases where no competitor data is available.
    * **Price Bounds:**  Ensures that the adjusted price stays within reasonable bounds (e.g., +/- 20% of the base price). This prevents prices from fluctuating wildly. This is very important for preventing extreme price changes.
* **HTTP Handlers:**
    * `getProductHandler`: Handles requests to retrieve product information. It fetches the product, simulates competitor pricing, adjusts the price, and returns the product information as JSON.
    * `updateDemandHandler`: Handles requests to update the product's demand. This allows you to simulate changes in demand and see how the pricing algorithm responds.
* **Error Handling:** Includes basic error handling (e.g., checking for missing product IDs, invalid demand values, and errors fetching competitor data).  More robust error handling would be needed in a production application.  Uses `http.Error` to send appropriate HTTP status codes and error messages to the client.
* **JSON Encoding:** Uses the `encoding/json` package to encode the product information as JSON, which is a common format for web APIs.
* **Concurrency:** While this example doesn't explicitly use concurrency (goroutines), Go's built-in concurrency features would be useful for handling multiple requests concurrently in a production environment.
* **Clear Comments:** The code is well-commented, explaining the purpose of each function and section.
* **Testability:** The functions are designed to be relatively easy to test. You could write unit tests for `adjustPrice` and `simulateCompetitorPricing` to ensure they are working correctly.
* **Realistic Simulation:** The simulation now includes a bit more realistic behavior, such as random variations in competitor prices.
* **Competitor Data Availability:** The `adjustPrice` function now gracefully handles cases where competitor data is not available, preventing errors.

How to run the code:

1.  **Save:** Save the code as `main.go`.
2.  **Run:** Open a terminal, navigate to the directory where you saved the file, and run the command `go run main.go`.
3.  **Test:** Open a web browser or use a tool like `curl` to send requests to the following URLs:

    *   `http://localhost:8080/product?id=123`:  Get information about product with ID "123".  The `current_price` should be dynamically adjusted.
    *   `http://localhost:8080/update_demand?id=123&demand=50`: Update the demand for product "123" to 50.  Then, reload the `/product` endpoint.  You should see the price increase due to the higher demand.
    *   `http://localhost:8080/product?id=456`: Get information about product with ID "456".
    *   `http://localhost:8080/update_demand?id=456&demand=0`:  Set demand of product "456" to zero. Reload `/product` to see the price change.
    *   `http://localhost:8080/product?id=789`
    *   `http://localhost:8080/update_demand?id=789&demand=100` Reload `/product?id=789`.

This improved example provides a more complete and realistic simulation of dynamic e-commerce pricing.  Remember that this is still a simplified example, and a real-world application would require more sophisticated data sources, algorithms, and infrastructure.
👁️ Viewed: 4

Comments