Menu
CoddyTech

Menyatukan Semuanya

Termasuk bagian Logika & Alur dalam perjalanan GO di Coddy. Pelajaran 50 dari 68.

challenge icon

Tantangan

Mudah

Lengkapi sistem manajemen inventarismu dengan membuat program utama yang menyeluruh dan mengintegrasikan semua fungsionalitas yang telah kamu bangun di pelajaran sebelumnya. Tantangan terakhir ini menyatukan inisialisasi inventaris, pemeriksaan stok, penambahan barang, pembaruan stok, dan pembuatan laporan ke dalam antarmuka baris perintah lengkap dengan navigasi berbasis menu.

Kamu akan menerima tiga input:

  • string berisi data inventaris awal dengan format "product1:price1:quantity1,product2:price2:quantity2,product3:price3:quantity3" (misalnya, "Laptop:999.99:5,Mouse:25.50:15,Keyboard:75.00:8")
  • string berisi urutan operasi menu dengan format "operation1,operation2,operation3", dengan operasi berupa "check", "add", "update", "report", atau "exit" (misalnya, "check,add,update,report,exit")
  • string berisi parameter operasi dengan format "param1|param2|param3", dengan setiap parameter sesuai dengan operasi pada posisi yang sama (misalnya, "Mouse|Monitor:299.99:10|Laptop:5|full,10")

Tugasmu adalah:

  1. Gunakan struct Product yang sama dari pelajaran sebelumnya dengan field Price (float64) dan Quantity (int)
  2. Parse input pertama dan inisialisasi map inventaris dengan data produk yang ada
  3. Tampilkan pesan awal sistem:
    • "=== INVENTORY MANAGEMENT SYSTEM ==="
    • "System initialized with [number_of_products] products"
    • "Starting interactive session..."
  4. Parse input kedua untuk mendapatkan urutan operasi yang akan dilakukan
  5. Parse input ketiga untuk mendapatkan parameter bagi setiap operasi
  6. Untuk setiap operasi sesuai urutannya, tampilkan header operasi dan lakukan tindakan yang sesuai:
    • Untuk "check": Tampilkan "--- STOCK CHECK ---" dan periksa stok produk yang ditentukan
    • Untuk "add": Tampilkan "--- ADD ITEM ---" dan tambahkan produk yang ditentukan
    • Untuk "update": Tampilkan "--- UPDATE STOCK ---" dan perbarui stok produk yang ditentukan
    • Untuk "report": Tampilkan "--- GENERATE REPORT ---" dan buat laporan yang ditentukan
    • Untuk "exit": Tampilkan "--- SYSTEM EXIT ---" dan tampilkan informasi keluar
  7. Implementasikan fungsi checkStock yang mengembalikan kuantitas dan error seperti pada pelajaran sebelumnya
  8. Implementasikan fungsi addNewItem yang menambahkan produk dan mengembalikan error seperti pada pelajaran sebelumnya
  9. Implementasikan fungsi updateStock yang memperbarui kuantitas dan mengembalikan error seperti pada pelajaran sebelumnya
  10. Implementasikan fungsi generateReport yang mencetak laporan yang dijelaskan di bawah untuk operasi "report"
  11. Untuk operasi "check":
    • Gunakan parameter sebagai nama produk yang akan diperiksa
    • Tampilkan: "Checking stock for: [product_name]"
    • Jika ditemukan: "Stock level: [quantity] units"
    • Jika tidak ditemukan: "Product not found in inventory"
  12. Untuk operasi "add":
    • Parse parameter dengan format "product_name:price:quantity"
    • Tampilkan: "Adding new product: [product_name]"
    • Jika berhasil: "Product added successfully"
    • Jika gagal: "Failed to add product: [error_message]", dengan error "product already exists"
  13. Untuk operasi "update":
    • Parse parameter dengan format "product_name:change"
    • Tampilkan: "Updating stock for: [product_name]"
    • Jika berhasil dan perubahan nol atau positif: "Added [change] units. New stock: [new_quantity]"
    • Jika berhasil dan perubahan negatif: "Removed [absolute_change] units. New stock: [new_quantity]"
    • Jika gagal: "Update failed: [error_message]", dengan error "product not found", atau "insufficient stock" jika kuantitas baru akan kurang dari 0
  14. Untuk operasi "report":
    • Parse parameter dengan format "report_type,threshold", dengan report_type berupa "low" atau "full", dan threshold berupa bilangan bulat
    • Tampilkan: "Generating [report_type] report with threshold [threshold]"
    • Kemudian cetak laporan dengan produk dalam urutan alfabetis:
      • Untuk "low": "=== LOW REPORT ===", lalu "Products with stock below [threshold]:", kemudian "- [name]: [quantity] units (Price: $[price])" untuk setiap produk yang kuantitasnya di bawah ambang batas
      • Untuk "full": "=== FULL REPORT ===", lalu "Complete inventory (minimum threshold: [threshold]):", kemudian "- [name]: [quantity] units @ $[price] each [OK]" untuk setiap produk, dengan [LOW STOCK] sebagai pengganti [OK] jika kuantitasnya di bawah ambang batas
  15. Untuk operasi "exit":
    • Tampilkan statistik inventaris akhir:
      • "Final inventory status:"
      • "Total products: [total_products]"
      • "Total items: [total_items]"
      • "Total value: $[total_value]"
    • Tampilkan: "Session completed successfully"
    • Tampilkan: "Thank you for using the Inventory Management System"
  16. Setelah setiap operasi, kecuali exit, tampilkan: "Operation completed. Continuing to next operation..."

Gunakan package strings untuk memisahkan string input, package strconv untuk mengubah string menjadi angka, package errors untuk menangani error, package fmt untuk output berformat, dan package sort untuk pengurutan alfabetis. Format semua harga dan nilai hingga 2 angka desimal. Tantangan ini menunjukkan cara membuat sistem interaktif lengkap yang mengintegrasikan beberapa komponen fungsional menjadi pengalaman pengguna yang terpadu, dengan penanganan error dan pengelolaan state yang tepat.

Coba sendiri

package main

import (
	"fmt"
	"sort"
	"strconv"
	"strings"
)

type Product struct {
	Price    float64
	Quantity int
}

func generateReport(inventory map[string]Product, reportType string, threshold float64) {
	// Display report header
	switch reportType {
	case "full":
		fmt.Println("=== FULL INVENTORY REPORT ===")
	case "low_stock":
		fmt.Println("=== LOW STOCK REPORT ===")
	case "high_value":
		fmt.Println("=== HIGH VALUE REPORT ===")
	}

	// Calculate general statistics
	totalProducts := len(inventory)
	totalItems := 0
	totalValue := 0.0
	
	for _, product := range inventory {
		totalItems += product.Quantity
		totalValue += product.Price * float64(product.Quantity)
	}
	
	averagePrice := totalValue / float64(totalItems)

	// Display general statistics
	fmt.Printf("Total Products: %d\n", totalProducts)
	fmt.Printf("Total Items in Stock: %d\n", totalItems)
	fmt.Printf("Total Inventory Value: $%.2f\n", totalValue)
	fmt.Printf("Average Product Price: $%.2f\n", averagePrice)

	// Filter products based on report type
	var filteredProducts []string
	for name, product := range inventory {
		switch reportType {
		case "full":
			filteredProducts = append(filteredProducts, name)
		case "low_stock":
			if product.Quantity <= int(threshold) {
				filteredProducts = append(filteredProducts, name)
			}
		case "high_value":
			productValue := product.Price * float64(product.Quantity)
			if productValue >= threshold {
				filteredProducts = append(filteredProducts, name)
			}
		}
	}

	// Sort filtered products alphabetically
	sort.Strings(filteredProducts)

	// Display filtered products section header
	switch reportType {
	case "full":
		fmt.Println("All Products:")
	case "low_stock":
		fmt.Printf("Products with stock ≤ %.0f:\n", threshold)
	case "high_value":
		fmt.Printf("Products with value ≥ $%.2f:\n", threshold)
	}

	// Display filtered products
	filteredItems := 0
	filteredValue := 0.0
	for _, name := range filteredProducts {
		product := inventory[name]
		productValue := product.Price * float64(product.Quantity)
		fmt.Printf("- %s: $%.2f × %d = $%.2f\n", name, product.Price, product.Quantity, productValue)
		filteredItems += product.Quantity
		filteredValue += productValue
	}

	// Display filtered statistics
	fmt.Println("Filtered Results:")
	fmt.Printf("Products shown: %d\n", len(filteredProducts))
	fmt.Printf("Items in filtered products: %d\n", filteredItems)
	fmt.Printf("Value of filtered products: $%.2f\n", filteredValue)

	// Find most and least expensive products
	var mostExpensiveName, leastExpensiveName string
	var mostExpensivePrice, leastExpensivePrice float64
	first := true
	
	var sortedNames []string
	for name := range inventory {
		sortedNames = append(sortedNames, name)
	}
	sort.Strings(sortedNames)
	
	for _, name := range sortedNames {
		product := inventory[name]
		if first {
			mostExpensiveName = name
			mostExpensivePrice = product.Price
			leastExpensiveName = name
			leastExpensivePrice = product.Price
			first = false
		} else {
			if product.Price > mostExpensivePrice {
				mostExpensiveName = name
				mostExpensivePrice = product.Price
			}
			if product.Price < leastExpensivePrice {
				leastExpensiveName = name
				leastExpensivePrice = product.Price
			}
		}
	}

	fmt.Println("Price Analysis:")
	fmt.Printf("Most expensive: %s at $%.2f\n", mostExpensiveName, mostExpensivePrice)
	fmt.Printf("Least expensive: %s at $%.2f\n", leastExpensiveName, leastExpensivePrice)

	// Find highest and lowest stock products
	var highestStockName, lowestStockName string
	var highestStock, lowestStock int
	first = true
	
	for _, name := range sortedNames {
		product := inventory[name]
		if first {
			highestStockName = name
			highestStock = product.Quantity
			lowestStockName = name
			lowestStock = product.Quantity
			first = false
		} else {
			if product.Quantity > highestStock {
				highestStockName = name
				highestStock = product.Quantity
			}
			if product.Quantity < lowestStock {
				lowestStockName = name
				lowestStock = product.Quantity
			}
		}
	}

	fmt.Println("Stock Analysis:")
	fmt.Printf("Highest stock: %s with %d units\n", highestStockName, highestStock)
	fmt.Printf("Lowest stock: %s with %d units\n", lowestStockName, lowestStock)

	// Inventory health assessment
	lowStockCount := 0
	highStockCount := 0
	highValueCount := 0
	
	for _, product := range inventory {
		if product.Quantity <= 5 {
			lowStockCount++
		}
		if product.Quantity > 20 {
			highStockCount++
		}
		productValue := product.Price * float64(product.Quantity)
		if productValue >= 500.0 {
			highValueCount++
		}
	}

	fmt.Printf("Low stock items (≤5): %d\n", lowStockCount)
	fmt.Printf("High stock items (>20): %d\n", highStockCount)
	fmt.Printf("High value items (≥$500): %d\n", highValueCount)

	// Report completion
	fmt.Println("Report generated successfully")
	fmt.Printf("Threshold applied: %.2f\n", threshold)
}

func main() {
	var inventoryData string
	var reportConfig string
	fmt.Scanln(&inventoryData)
	fmt.Scanln(&reportConfig)

	// Parse inventory data
	inventory := make(map[string]Product)
	if inventoryData != "" {
		products := strings.Split(inventoryData, ",")
		for _, productStr := range products {
			parts := strings.Split(productStr, ":")
			name := parts[0]
			price, _ := strconv.ParseFloat(parts[1], 64)
			quantity, _ := strconv.Atoi(parts[2])
			inventory[name] = Product{Price: price, Quantity: quantity}
		}
	}

	// Parse report configuration
	configParts := strings.Split(reportConfig, ",")
	reportType := configParts[0]
	threshold, _ := strconv.ParseFloat(configParts[1], 64)

	// Generate report
	generateReport(inventory, reportType, threshold)
}

Semua pelajaran di Logika & Alur

Latihan sendiri: Compiler Go online