하나로 합치기
Coddy GO 여정의 로직 & 흐름 섹션에 포함된 레슨 — 68개 중 50번째.
챌린지
쉬움이전 레슨에서 구축한 모든 기능을 통합하는 포괄적인 메인 프로그램을 작성하여 재고 관리 시스템을 완성하세요. 이 최종 챌린지는 재고 초기화, 재고 확인, 품목 추가, 재고 업데이트 및 보고서 생성을 메뉴 기반 내비게이션이 포함된 완전한 명령줄 인터페이스로 통합합니다.
세 가지 입력을 받게 됩니다:
"product1:price1:quantity1,product2:price2:quantity2,product3:price3:quantity3"형식의 초기 재고 데이터를 포함하는 문자열 (예:"Laptop:999.99:5,Mouse:25.50:15,Keyboard:75.00:8")"operation1,operation2,operation3"형식의 메뉴 작업 시퀀스를 포함하는 문자열. 여기서 작업은"check","add","update","report", 또는"exit"가 될 수 있습니다 (예:"check,add,update,report,exit")"param1|param2|param3"형식의 작업 매개변수를 포함하는 문자열. 각 매개변수는 동일한 위치의 작업에 대응합니다 (예:"Mouse|Monitor:299.99:10|Laptop:5|full,10")
당신의 과제는 다음과 같습니다:
- 이전 레슨과 동일하게
Price(float64) 및Quantity(int) 필드를 가진Product구조체를 사용합니다. - 첫 번째 입력을 파싱하고 기존 제품 데이터로 재고 맵을 초기화합니다.
- 시스템 시작 메시지를 표시합니다:
"=== INVENTORY MANAGEMENT SYSTEM ===""System initialized with [number_of_products] products""Starting interactive session..."
- 두 번째 입력을 파싱하여 수행할 작업 시퀀스를 가져옵니다.
- 세 번째 입력을 파싱하여 각 작업에 대한 매개변수를 가져옵니다.
- 시퀀스의 각 작업에 대해 작업 헤더를 표시하고 해당 동작을 수행합니다:
"check"의 경우:"--- STOCK CHECK ---"를 표시하고 지정된 제품의 재고를 확인합니다."add"의 경우:"--- ADD ITEM ---"를 표시하고 지정된 제품을 추가합니다."update"의 경우:"--- UPDATE STOCK ---"를 표시하고 지정된 제품의 재고를 업데이트합니다."report"의 경우:"--- GENERATE REPORT ---"를 표시하고 지정된 보고서를 생성합니다."exit"의 경우:"--- SYSTEM EXIT ---"를 표시하고 종료 정보를 보여줍니다.
- 이전 레슨과 같이 수량과 에러를 반환하는
checkStock함수를 구현합니다. - 이전 레슨과 같이 제품을 추가하고 에러를 반환하는
addNewItem함수를 구현합니다. - 이전 레슨과 같이 수량을 업데이트하고 에러를 반환하는
updateStock함수를 구현합니다. - 이전 레슨과 같이 보고서를 생성하는
generateReport함수를 구현합니다. "check"작업의 경우:- 매개변수를 확인할 제품 이름으로 사용합니다.
- 표시:
"Checking stock for: [product_name]" - 찾은 경우:
"Stock level: [quantity] units" - 찾지 못한 경우:
"Product not found in inventory"
"add"작업의 경우:"product_name:price:quantity"형식의 매개변수를 파싱합니다.- 표시:
"Adding new product: [product_name]" - 성공한 경우:
"Product added successfully" - 실패한 경우:
"Failed to add product: [error_message]"
"update"작업의 경우:"product_name:change"형식의 매개변수를 파싱합니다.- 표시:
"Updating stock for: [product_name]" - 성공하고 변화량이 양수인 경우:
"Added [change] units. New stock: [new_quantity]" - 성공하고 변화량이 음수인 경우:
"Removed [absolute_change] units. New stock: [new_quantity]" - 실패한 경우:
"Update failed: [error_message]"
"report"작업의 경우:"report_type,threshold"형식의 매개변수를 파싱합니다.- 표시:
"Generating [report_type] report with threshold [threshold]" - 이전 레슨과 같이 전체 보고서를 생성하고 표시합니다.
"exit"작업의 경우:- 최종 재고 통계를 표시합니다:
"Final inventory status:""Total products: [total_products]""Total items: [total_items]""Total value: $[total_value]"
- 표시:
"Session completed successfully" - 표시:
"Thank you for using the Inventory Management System"
- 최종 재고 통계를 표시합니다:
- 각 작업(종료 제외) 후에 다음을 표시합니다:
"Operation completed. Continuing to next operation..."
입력 문자열을 분할하기 위해 strings 패키지를, 문자열을 숫자로 변환하기 위해 strconv 패키지를, 에러 처리를 위해 errors 패키지를, 형식화된 출력을 위해 fmt 패키지를, 알파벳순 정렬을 위해 sort 패키지를 사용하세요. 모든 가격과 값은 소수점 2째 자리까지 표시합니다. 이 챌린지는 여러 기능적 구성 요소를 적절한 에러 처리 및 상태 관리와 함께 응집력 있는 사용자 경험으로 통합하여 완전한 대화형 시스템을 만드는 방법을 보여줍니다.
직접 해보기
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)
}