diff --git a/go/01-basics/inventory.go b/go/01-basics/inventory.go index 79e4868..68d4daa 100644 --- a/go/01-basics/inventory.go +++ b/go/01-basics/inventory.go @@ -1,6 +1,8 @@ package main -import "fmt" +import ( + "fmt" +) // a new type named Category that can hold integer values type Category int @@ -26,7 +28,6 @@ func (c Category) String() string { } } -// Struct for product details type Product struct { Name string Price float64 @@ -34,84 +35,86 @@ type Product struct { Category Category } -// Add a new product to the inventory -func addProduct(inventory *[]Product, //pointer to the slice of of Products that shall be modified. In that way it can serve as in input/output parameter - name string, price float64, quantity int, category Category) { - // Check if the product already exists in the inventory - for _, product := range *inventory { - if product.Name == name { - fmt.Println("Product already exists.") - return - } - } - // Add the new product - *inventory = append(*inventory, Product{ - Name: name, - Price: price, - Quantity: quantity, - Category: category, - }) - fmt.Printf("Added product: %s\n", name) +// implementation of the fmt.Stringer interface for printing products +func (p Product) String() string { + return fmt.Sprintf("%s (%s, Price: $%.2f, Quantity: %d)", p.Name, p.Category, p.Price, p.Quantity) } -// Remove a product from the inventory -func removeProduct(inventory *[]Product, //pointer to the slice of of Products that shall be modified. In that way it can serve as in input/output parameter - name string) { - for i, product := range *inventory { - if product.Name == name { - *inventory = append((*inventory)[:i], (*inventory)[i+1:]...) - fmt.Printf("Removed product: %s\n", name) - return - } +func addProduct(inventory map[string]Product, name string, price float64, quantity int, category Category) { + + //do not create a new product in case a product with the name already exists + if _, exists := inventory[name]; exists { + fmt.Printf("Unable to add new Product %s: Product already exists.\n", name) + return } - fmt.Println("Product not found.") + + //create a new product... + p := Product{name, price, quantity, category} + inventory[name] = p // ...and insert it into the map } -// Update the quantity of a product. -func updateQuantity(inventory *[]Product, //pointer to the slice of of Products that shall be modified. In that way it can serve as in input/output parameter - name string, newQuantity int) { - for i, product := range *inventory { - if product.Name == name { - (*inventory)[i].Quantity = newQuantity - fmt.Printf("Updated quantity for %s: New Quantity = %d\n", name, newQuantity) - return - } - } - fmt.Println("Product not found.") +func removeProduct(inventory map[string]Product, name string) { + //no checks required. Does nothing if the product doesn't exist. + delete(inventory, name) } -// Display the inventory -func displayInventory(inventory []Product) { - fmt.Println("Inventory:") - for _, product := range inventory { //iterating over a range returns pairs of index and the content of a container (here: inventory). Since we don't care about the index, we use _ as a placeholder. - fmt.Printf("%s - %s (Price: $%.2f, Quantity: %d)\n", - product.Name, product.Category, product.Price, product.Quantity) +func updateQuantity(inventory map[string]Product, name string, newQuantity int) { + p := inventory[name] //read from the map + p.Quantity = newQuantity //update value + inventory[name] = p //store back into the map +} + +func displayInventory(inventory map[string]Product) { + //Iterate over the inventory + i := 1 + for _, p := range inventory { //don't care about the key (_), only the value (p) is relevant + fmt.Printf("%d. %s\n", i, p) + i++ } } func main() { - // Initialize inventory - inventory := []Product{ - {Name: "Laptop", Price: 1000, Quantity: 5, Category: Electronics}, - {Name: "Apples", Price: 2, Quantity: 50, Category: Groceries}, - {Name: "T-shirt", Price: 10, Quantity: 20, Category: Clothes}, + + fmt.Println("Welcome to the Inventory Manager!") + + // Store a fixed list of initial product names in an array. + initialProductNames := [...]string{"Laptop"} + + // Convert the array into a slice so the inventory can grow or shrink dynamically. + productNames := initialProductNames[:] + productNames = append(productNames, "Apples", "T-shirt") + + // Use a map to associate product names with details like quantity, price, and category. + prices := []float64{1000.0, 2.0, 10.0} + quantities := []int{5, 50, 20} + categories := []Category{Electronics, Groceries, Clothes} + + inventory := make(map[string]Product) + for i, name := range productNames { + inventory[name] = Product{name, prices[i], quantities[i], categories[i]} } // Display initial inventory + fmt.Println("\nInitial Inventory:") displayInventory(inventory) // Add a new product - addProduct(&inventory, "Phone", 800, 10, Electronics) + fmt.Println("\nAdding a new product: Phone (Electronics, Price: $800, Quantity: 10)") + addProduct(inventory, "Phone", 800, 10, Electronics) // Display updated inventory + fmt.Println("\nUpdated Inventory:") displayInventory(inventory) // Update the quantity of an existing product - updateQuantity(&inventory, "Apples", 30) + fmt.Println("\nUpdating quantity for Apples: New Quantity = 30") + updateQuantity(inventory, "Apples", 30) // Remove a product - removeProduct(&inventory, "T-shirt") + fmt.Println("\nRemoving product: T-shirt") + removeProduct(inventory, "T-shirt") // Display final inventory + fmt.Println("\nFinal Inventory:") displayInventory(inventory) }