하나로 합치기
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").
해야 할 일:
- 이전 강의에서 사용한 것과 동일한
Product구조체를 사용합니다. 이 구조체에는Price(float64)와Quantity(int) 필드가 있습니다. - 첫 번째 입력을 구문 분석하고 기존 제품 데이터로 재고 맵을 초기화합니다.
- 시스템 시작 메시지를 표시합니다.
"=== 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함수를 구현합니다. - 아래의
"report"작업에서 설명하는 보고서를 출력하는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]"를 표시합니다. 오류는"product already exists"입니다.
- 매개변수를
"update"작업의 경우:- 매개변수를
"product_name:change"형식으로 구문 분석합니다. "Updating stock for: [product_name]"을 표시합니다.- 성공했고 change가 0 이상이면
"Added [change] units. New stock: [new_quantity]"를 표시합니다. - 성공했고 change가 음수이면
"Removed [absolute_change] units. New stock: [new_quantity]"를 표시합니다. - 실패하면
"Update failed: [error_message]"를 표시합니다. 오류는"product not found"이거나 새 수량이 0 미만이 되는 경우"insufficient stock"입니다.
- 매개변수를
"report"작업의 경우:- 매개변수를
"report_type,threshold"형식으로 구문 분석합니다. report_type은"low"또는"full"이고 threshold는 정수입니다. "Generating [report_type] report with threshold [threshold]"를 표시합니다.- 그런 다음 제품을 알파벳순으로 정렬하여 보고서를 출력합니다.
"low"의 경우: 먼저"=== LOW REPORT ==="을 출력한 다음"Products with stock below [threshold]:"를 출력하고, 수량이 threshold 미만인 각 제품에 대해"- [name]: [quantity] units (Price: $[price])"를 출력합니다."full"의 경우: 먼저"=== FULL REPORT ==="를 출력한 다음"Complete inventory (minimum threshold: [threshold]):"를 출력하고, 모든 제품에 대해"- [name]: [quantity] units @ $[price] each [OK]"를 출력합니다. 수량이 threshold 미만이면[OK]대신[LOW STOCK]을 사용합니다.
- 매개변수를
"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"를 표시합니다.
- 최종 재고 통계를 표시합니다.
- exit를 제외한 각 작업 후에
"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)
}로직 & 흐름의 모든 레슨
직접 연습해 보세요: 온라인 Go 컴파일러