From 81a12a4f0695f13081070b58b35ece11a96149f0 Mon Sep 17 00:00:00 2001 From: ChaosLL1337 Date: Wed, 21 Oct 2026 06:44:08 +0000 Subject: [PATCH] =?UTF-8?q?L=C3=B6sungen=20geholt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go/01-basics/calculator.go | 112 +++++++++++------------- go/01-basics/inventory.go | 101 +++++++++++++++------ go/02-next-level/02-struct-embedding.go | 40 +++++++++ go/02-next-level/03-errors.go | 62 +++++++++++++ go/02-next-level/04-closure.go | 28 ++++++ 5 files changed, 252 insertions(+), 91 deletions(-) create mode 100644 go/02-next-level/02-struct-embedding.go create mode 100644 go/02-next-level/03-errors.go create mode 100644 go/02-next-level/04-closure.go diff --git a/go/01-basics/calculator.go b/go/01-basics/calculator.go index f9bb191..5240c30 100644 --- a/go/01-basics/calculator.go +++ b/go/01-basics/calculator.go @@ -1,74 +1,60 @@ package main - + import ( "fmt" ) - -const ( - opAdd = "add" - opSubtract = "subtract" - opMultiply = "multiply" - opDivide = "divide" - opExit = "exit" -) - -var result float64 - -func add(a, b float64) { - result = a + b -} -func multiply(a, b float64) { - result = a * b -} -func subtract(a, b float64) { - result = a - b -} -func divide(a, b float64) { - result = a / b -} - + func main() { - var x float64 - var y float64 + const ( + add = "add" + subtract = "subtract" + multiply = "multiply" + divide = "divide" + exit = "exit" + ) - //TODO: implement according to README.md + //TODO: implement according to README.md + fmt.Println("Welcome to the Simple Calculator!") + for { + var operation string + fmt.Print("\nEnter operation (add, subtract, multiply, divide, exit): ") + fmt.Scan(&operation) - //the following code just demonstrates how to use fmt.Scan - - for { - fmt.Print("What would you like to do? (add|subtract|divide|multiply|exit)") - var str string - fmt.Scan(&str) - if str == opExit { + //the following code just demonstrates how to use fmt.Scan + if operation == exit { + fmt.Println("Goodbye!") break - } else { - - fmt.Print("Please enter a float: ") - fmt.Scan(&x) - - fmt.Print("Please enter a float: ") - fmt.Scan(&y) - - switch str { - case opAdd: - add(x, y) - fmt.Println(result) - case opMultiply: - multiply(x, y) - fmt.Println(result) - case opDivide: - if y == 0 { - fmt.Println("Division by 0 is not possible") - continue - } - divide(x, y) - fmt.Println(result) - case opSubtract: - subtract(x, y) - fmt.Println(result) - default: - fmt.Println("Unknown operation") + } + + var str string + fmt.Print("Please enter a string: ") + fmt.Scan(&str) + var num1, num2 float64 + fmt.Print("Enter the first number: ") + fmt.Scan(&num1) + fmt.Print("Enter the second number: ") + fmt.Scan(&num2) + + var x float64 + fmt.Print("Please enter a float: ") + fmt.Scan(&x) + + fmt.Printf("You entered '%s' and %f\n", str, x) + switch operation { + case add: + fmt.Printf("Result: %.2f\n", num1+num2) + case subtract: + fmt.Printf("Result: %.2f\n", num1-num2) + case multiply: + fmt.Printf("Result: %.2f\n", num1*num2) + case divide: + if num2 == 0 { + fmt.Println("Error: Division by zero is not allowed!") + } else { + fmt.Printf("Result: %.2f\n", num1/num2) } + default: + fmt.Println("Invalid operation. Please try again.") } } -} \ No newline at end of file +} diff --git a/go/01-basics/inventory.go b/go/01-basics/inventory.go index 21ed0b4..61643ba 100644 --- a/go/01-basics/inventory.go +++ b/go/01-basics/inventory.go @@ -1,65 +1,110 @@ -package main + package main -import ( - "fmt" -) +import "fmt" -type Product struct { - Name string - Price float64 - Quantity int - Category int //TODO: use enum instead -} +type Category int -const( - Electronics int = iota +const ( + Electronics Category = iota Groceries Clothes ) +func (c Category) String() string { + switch c { + case Electronics: + return "Electronics" + case Groceries: + return "Groceries" + case Clothes: + return "Clothes" + default: + return "Unknown" + } +} + +// Struct for product details +type Product struct { + Name string + Price float64 + Quantity int + Category string //TODO: use enum instead + Category Category +} + func addProduct(inventory *[]Product, name string, price float64, quantity int, category string) { //TODO: implement - var l int = inventory.len - inventory = append(inventory, name, price, quantity, category) +// Add a new product to the inventory +func addProduct(inventory *[]Product, 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) } +// Remove a product from the inventory func removeProduct(inventory *[]Product, name string) { //TODO: implement - inventory = inventory.delete(name) + for i, product := range *inventory { + if product.Name == name { + *inventory = append((*inventory)[:i], (*inventory)[i+1:]...) + fmt.Printf("Removed product: %s\n", name) + return + } + } + fmt.Println("Product not found.") } +// Update the quantity of a product func updateQuantity(inventory *[]Product, name string, newQuantity int) { //TODO: implement - sliceInventory[name].quantity = newQuantity; + 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.") } +// Display the inventory func displayInventory(inventory []Product) { //TODO: implement - for _, p := range sliceInventory{ - fmt.Println(karte(sliceInventory[p])) + fmt.Println("Inventory:") + for _, product := range inventory { + fmt.Printf("%s - %s (Price: $%.2f, Quantity: %d)\n", + product.Name, product.Category, product.Price, product.Quantity) } } 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"}, {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}, } - var arrInventory = [3]string{"Laptop", "Apples", "T-shirt"} - var sliceInventory = arrInventory[:] - - karte := map[string]Product{ - "Laptop": {Name: "Laptop", Price: 1000, Quantity: 5, Category: Electronics}, - "Apples": {Name: "Apples", Price: 2, Quantity: 50, Category: Groceries}, - "T-shirt": {Name: "T-shirt", Price: 10, Quantity: 20, Category: Clothes}, - - } // Display initial inventory displayInventory(inventory) // Add a new product + addProduct(&inventory, "Phone", 800, 10, "Electronics") addProduct(&inventory, "Phone", 800, 10, Electronics) // Display updated inventory @@ -73,4 +118,4 @@ func main() { // Display final inventory displayInventory(inventory) -} +} \ No newline at end of file diff --git a/go/02-next-level/02-struct-embedding.go b/go/02-next-level/02-struct-embedding.go new file mode 100644 index 0000000..f50d633 --- /dev/null +++ b/go/02-next-level/02-struct-embedding.go @@ -0,0 +1,40 @@ +package main + +import "fmt" + +type Person struct { + Name string +} + +func (p Person) Say() { + fmt.Println("Hi, my name is", p.Name) +} + +type Student struct { + Person //struct Person is embedded + Semester int +} + +type Teacher struct { + Person //struct Person is embedded + Subject string +} + +func main() { + + max := Person{"Max"} + + daniel := Student{Person{"Daniel"}, 3} + + sebastian := Teacher{Person{"Sebastian"}, "PR3"} + + max.Say() + + daniel.Say() //can be invoked directly on Student + + sebastian.Say() //can be invoked directly on Teacher + + max = sebastian.Person + + max.Say() +} diff --git a/go/02-next-level/03-errors.go b/go/02-next-level/03-errors.go new file mode 100644 index 0000000..6e68e3b --- /dev/null +++ b/go/02-next-level/03-errors.go @@ -0,0 +1,62 @@ +package main + +import ( + "errors" + "fmt" +) + +// a function that can fail, so it returns an error as the second return value +func f(arg int) (int, error) { + if arg == 42 { + // in case of an error, return the zero value for the result and a non-nil error + return 0, errors.New("can't work with 42") + } + + // simply return the result and a nil error in the success case + return arg + 3, nil +} + +// define some errors to use in makeTea +var ErrOutOfTea = fmt.Errorf("no more tea available") +var ErrPower = fmt.Errorf("can't boil water") + +// a function that can fail in multiple ways, so it returns an error as the second return value +func makeTea(arg int) error { + if arg == 2 { + // return the error directly, so we can check for it later with errors.Is + return ErrOutOfTea + } else if arg == 4 { + // use %w to wrap the error, so we can check for it later with errors.Is + return fmt.Errorf("making tea: %w", ErrPower) + } + return nil +} + +func main() { + for _, i := range []int{7, 42} { + + //typical pattern for checking errors in Go: if the error is not nil, handle it and return or continue; otherwise, use the result + if r, e := f(i); e != nil { + fmt.Println("f failed:", e) + } else { + fmt.Println("f worked:", r) + } + } + + for i := range 5 { + if err := makeTea(i); err != nil { + + // use errors.Is to check for specific errors, even if they are wrapped + if errors.Is(err, ErrOutOfTea) { + fmt.Println("We should buy new tea!") + } else if errors.Is(err, ErrPower) { // this error is wrapped, but errors.Is can still check for it + fmt.Println("Now it is dark.") + } else { + fmt.Printf("unknown error: %s\n", err) + } + continue + } + + fmt.Println("Tea is ready!") + } +} diff --git a/go/02-next-level/04-closure.go b/go/02-next-level/04-closure.go new file mode 100644 index 0000000..a7d0781 --- /dev/null +++ b/go/02-next-level/04-closure.go @@ -0,0 +1,28 @@ +package main + +import "fmt" + +// a closure is a function value that references variables from outside its body. +// The function may access and assign to the referenced variables; in this sense the function is "bound" to the variables. +func intSeq() func() int { //returns a function that returns an int + i := 0 // i is a variable that intSeq's function value will reference. It continues to exist even after intSeq returns. + return func() int { // the anonomous function is returned here. It is not executed yet. + i++ + return i + } +} + +func main() { + + //functions are first class citizens in Go, so we can assign them to variables, + // pass them as arguments to other functions, and return them from functions. + nextInt := intSeq() + + fmt.Println(nextInt()) + fmt.Println(nextInt()) + fmt.Println(nextInt()) + + //a second function value from intSeq, with its own i variable. + newInts := intSeq() + fmt.Println(newInts()) +}