إضافة عنصر جديد
جزء من قسم Logic & Flow في رحلة GO على Coddy — الدرس 47 من 68.
التحدي
سهلقم بتوسيع نظام إدارة المخزون الخاص بك من خلال تنفيذ وظيفة لإضافة منتجات جديدة بأمان. يعتمد هذا التحدي على نظام فحص المخزون السابق ويضيف القدرة على توسيع مخزونك مع منع الإدخالات المكررة من خلال المعالجة الصحيحة للأخطاء.
ستتلقى مدخلين:
- سلسلة نصية تحتوي على بيانات المخزون الحالي بالتنسيق
"product1:price1:quantity1,product2:price2:quantity2,product3:price3:quantity3"(على سبيل المثال،"Laptop:999.99:5,Mouse:25.50:15,Keyboard:75.00:8") - سلسلة نصية تحتوي على المنتجات الجديدة المراد إضافتها بالتنسيق
"product1:price1:quantity1,product2:price2:quantity2,product3:price3:quantity3"(على سبيل المثال،"Monitor:299.99:10,Mouse:19.99:20,Webcam:89.99:12")
مهمتك هي:
- استخدم نفس هيكل
Productمن الدروس السابقة مع حقولPrice(float64) وQuantity(int) - قم بتحليل المدخل الأول عن طريق التقسيم عند الفواصل للحصول على إدخالات المنتجات الحالية الفردية
- لكل إدخال منتج حالي، قم بالتقسيم عند النقطتين الرأسيتين للحصول على اسم المنتج، والسعر، والكمية
- قم بتحويل سلسلة السعر النصية إلى float64 وسلسلة الكمية النصية إلى int
- قم بإنشاء وتعبئة خريطة
inventoryببيانات المنتجات الحالية - قم بإنشاء دالة تسمى
addNewItemتأخذ خريطة المخزون، واسم المنتج، والسعر، والكمية كمعاملات وتعيد خطأ (error):- إذا كان المنتج موجوداً بالفعل في المخزون، فقم بإرجاع خطأ مع الرسالة
"product already exists: [product_name]" - إذا لم يكن المنتج موجوداً، فقم بإضافته إلى المخزون وأرجع nil
- إذا كان المنتج موجوداً بالفعل في المخزون، فقم بإرجاع خطأ مع الرسالة
- قم بتحليل المدخل الثاني عن طريق التقسيم عند الفواصل للحصول على قائمة المنتجات الجديدة المراد إضافتها
- لكل إدخال منتج جديد، قم بالتقسيم عند النقطتين الرأسيتين للحصول على اسم المنتج، والسعر، والكمية
- قم بتحويل سلسلة السعر النصية إلى float64 وسلسلة الكمية النصية إلى int
- اعرض عنوان عملية الإضافة:
"Adding New Items:" - لكل منتج جديد، استدعِ دالة
addNewItemواعرض النتائج:- في حالة عدم وجود خطأ:
"[product_name]: Successfully added - $[price] (Stock: [quantity])" - في حالة وجود خطأ:
"[product_name]: Failed to add - [error_message]"
- في حالة عدم وجود خطأ:
- قم بحساب وعرض إحصائيات الإضافة:
"Addition Summary:""Items processed: [total_number_of_items_processed]""Items added: [number_of_items_successfully_added]""Items rejected: [number_of_items_that_failed_to_add]"
- اعرض المخزون المحدث بترتيب أبجدي حسب اسم المنتج:
"Updated Inventory:"- لكل منتج:
"- [product_name]: $[price] (Stock: [quantity])"
- قم بحساب وعرض إحصائيات المخزون النهائية:
"Final Inventory Statistics:""Total Products: [total_number_of_products_in_inventory]""Total Items in Stock: [sum_of_all_quantities]""Total Inventory Value: $[sum_of_price_times_quantity_for_all_products]"
- أدرج أي منتجات مرفوضة:
- إذا كانت هناك منتجات مرفوضة:
"Rejected products: [comma_separated_list_of_rejected_products]" - إذا لم تكن هناك منتجات مرفوضة:
"All new products were added successfully"
- إذا كانت هناك منتجات مرفوضة:
استخدم حزمة strings لتقسيم السلاسل النصية المدخلة، وحزمة strconv لتحويل السلاسل النصية إلى أرقام، وحزمة errors لإنشاء رسائل الخطأ، وحزمة fmt للمخرجات المنسقة، وحزمة sort لفرز أسماء المنتجات أبجدياً. قم بتنسيق جميع الأسعار إلى منزلتين عشريتين وقيمة المخزون الإجمالية إلى منزلتين عشريتين. يوضح هذا التحدي كيفية توسيع مجموعات البيانات بأمان مع منع الإدخالات المكررة من خلال المعالجة الصحيحة للأخطاء والتحقق من الصحة.
جرّب بنفسك
package main
import (
"errors"
"fmt"
"strconv"
"strings"
)
type Product struct {
Price float64
Quantity int
}
func checkStock(inventory map[string]Product, productName string) (int, error) {
product, exists := inventory[productName]
if !exists {
return 0, errors.New("product not found: " + productName)
}
return product.Quantity, nil
}
func main() {
var inventoryData string
var checkRequests string
fmt.Scanln(&inventoryData)
fmt.Scanln(&checkRequests)
inventory := make(map[string]Product)
// Parse inventory data
productEntries := strings.Split(inventoryData, ",")
for _, entry := range productEntries {
parts := strings.Split(entry, ":")
name := parts[0]
price, _ := strconv.ParseFloat(parts[1], 64)
quantity, _ := strconv.Atoi(parts[2])
inventory[name] = Product{Price: price, Quantity: quantity}
}
// Parse check requests
productsToCheck := strings.Split(checkRequests, ",")
fmt.Println("Stock Check Results:")
var productsFound int
var productsNotFound int
var totalStock int
var missingProducts []string
for _, productName := range productsToCheck {
quantity, err := checkStock(inventory, productName)
if err != nil {
fmt.Printf("%s: Error - %s\n", productName, err.Error())
productsNotFound++
missingProducts = append(missingProducts, productName)
} else {
fmt.Printf("%s: %d units in stock\n", productName, quantity)
productsFound++
totalStock += quantity
}
}
fmt.Println("Check Summary:")
fmt.Printf("Products checked: %d\n", len(productsToCheck))
fmt.Printf("Products found: %d\n", productsFound)
fmt.Printf("Products not found: %d\n", productsNotFound)
fmt.Printf("Total stock for found products: %d units\n", totalStock)
if len(missingProducts) > 0 {
fmt.Printf("Missing products: %s\n", strings.Join(missingProducts, ","))
} else {
fmt.Println("All requested products are available")
}
}جميع دروس Logic & Flow
1تدفق التحكم المتقدم
جملة Switch مع `fallthrough`الخروج من الحلقات المتداخلةالاستمرار في حلقة محددةجملة `goto`ملخص - التحكم المتقدم في الحلقات2الـ Structs والميثودز (Methods)
تعريف الـ Methods على الـ Structsالـ Value Receiversالـ Pointer Receiversاختيار الـ Receiversالـ Methods مقابل الـ Functionsملخص - سلوك الـ Struct5تعمق في الـ Maps
Maps من نوع Structsالـ Pointers كقيم في الـ Mapsالتحقق من الـ Nil Mapsمقارنة الـ Mapsمراجعة - عداد تكرار الكلمات8مشروع: مخزون بسيط
نظرة عامة على المشروعالتحقق من المخزون3الواجهات (الأساسيات)
ما هي الواجهة؟تعريف الواجهةتطبيق الواجهةاستخدام أنواع الواجهاتالواجهة الفارغةتأكيدات النوع (Type Assertions)تبديل النوع (Type Switch)ملخص - الأشكال والسلوكيات