forked from steger/pr3-sose2026
Merge remote-tracking branch 'upstream/main'
commit
625a2da5fe
|
|
@ -1,40 +1,107 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// a new type named Category that can hold integer values
|
||||||
|
type Category int
|
||||||
|
|
||||||
|
// The go equivalent of an enum that enumerates different named Categories
|
||||||
|
const (
|
||||||
|
Electronics Category = iota //0
|
||||||
|
Groceries //1
|
||||||
|
Clothes //2
|
||||||
|
)
|
||||||
|
|
||||||
|
// implementation of the fmt.Stringer interface. In that way, Categories can be printed using the fmt.Print* functions
|
||||||
|
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 {
|
type Product struct {
|
||||||
Name string
|
Name string
|
||||||
Price float64
|
Price float64
|
||||||
Quantity int
|
Quantity int
|
||||||
Category string //TODO: use enum instead
|
Category Category
|
||||||
}
|
}
|
||||||
|
|
||||||
func addProduct(inventory *[]Product, name string, price float64, quantity int, category string) {
|
// Add a new product to the inventory
|
||||||
//TODO: implement
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
func removeProduct(inventory *[]Product, name string) {
|
// Remove a product from the inventory
|
||||||
//TODO: implement
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println("Product not found.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateQuantity(inventory *[]Product, name string, newQuantity int) {
|
// Update the quantity of a product.
|
||||||
//TODO: implement
|
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.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Display the inventory
|
||||||
func displayInventory(inventory []Product) {
|
func displayInventory(inventory []Product) {
|
||||||
//TODO: implement
|
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 main() {
|
func main() {
|
||||||
|
// Initialize inventory
|
||||||
inventory := []Product{
|
inventory := []Product{
|
||||||
{Name: "Laptop", Price: 1000, Quantity: 5, Category: "Electronics"},
|
{Name: "Laptop", Price: 1000, Quantity: 5, Category: Electronics},
|
||||||
{Name: "Apples", Price: 2, Quantity: 50, Category: "Groceries"},
|
{Name: "Apples", Price: 2, Quantity: 50, Category: Groceries},
|
||||||
{Name: "T-shirt", Price: 10, Quantity: 20, Category: "Clothes"},
|
{Name: "T-shirt", Price: 10, Quantity: 20, Category: Clothes},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display initial inventory
|
// Display initial inventory
|
||||||
displayInventory(inventory)
|
displayInventory(inventory)
|
||||||
|
|
||||||
// Add a new product
|
// Add a new product
|
||||||
addProduct(&inventory, "Phone", 800, 10, "Electronics")
|
addProduct(&inventory, "Phone", 800, 10, Electronics)
|
||||||
|
|
||||||
// Display updated inventory
|
// Display updated inventory
|
||||||
displayInventory(inventory)
|
displayInventory(inventory)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type Counter struct {
|
||||||
|
value int
|
||||||
|
}
|
||||||
|
|
||||||
|
// pointer receiver. The method operates directly on the object c points to
|
||||||
|
// Use a pointer receiver whenever the object needs to be modified.
|
||||||
|
func (c *Counter) Increment() {
|
||||||
|
c.value++
|
||||||
|
}
|
||||||
|
|
||||||
|
// value receiver. The method operates on copy of object c. Use a value
|
||||||
|
// receiver when the object does not need to be modified in the method.
|
||||||
|
func (c Counter) String() string {
|
||||||
|
return fmt.Sprintf("Counter value: %d", c.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
c := Counter{}
|
||||||
|
fmt.Println(c)
|
||||||
|
c.Increment()
|
||||||
|
fmt.Println(c)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
)
|
||||||
|
|
||||||
|
type geometry interface {
|
||||||
|
area() float64
|
||||||
|
perim() float64
|
||||||
|
}
|
||||||
|
|
||||||
|
type rect struct {
|
||||||
|
width, height float64
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure that rect implements the geometry interface
|
||||||
|
var _ geometry = rect{}
|
||||||
|
|
||||||
|
type circle struct {
|
||||||
|
radius float64
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure that circle implements the geometry interface
|
||||||
|
var _ geometry = circle{}
|
||||||
|
|
||||||
|
func (r rect) area() float64 {
|
||||||
|
return r.width * r.height
|
||||||
|
}
|
||||||
|
func (r rect) perim() float64 {
|
||||||
|
return 2*r.width + 2*r.height
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c circle) area() float64 {
|
||||||
|
return math.Pi * c.radius * c.radius
|
||||||
|
}
|
||||||
|
func (c circle) perim() float64 {
|
||||||
|
return 2 * math.Pi * c.radius
|
||||||
|
}
|
||||||
|
|
||||||
|
//Metods demonstrates how to use an interface
|
||||||
|
func measure(g geometry) {
|
||||||
|
fmt.Println(g)
|
||||||
|
fmt.Println(g.area())
|
||||||
|
fmt.Println(g.perim())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Method demonstrates casting an interface to a concrete type.
|
||||||
|
//Should be avoided in practice whenever possible.
|
||||||
|
func detectCircle(g geometry) {
|
||||||
|
if c, ok := g.(circle); ok {
|
||||||
|
fmt.Println("circle with radius", c.radius)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
r := rect{width: 3, height: 4}
|
||||||
|
c := circle{radius: 5}
|
||||||
|
|
||||||
|
measure(r)
|
||||||
|
measure(c)
|
||||||
|
|
||||||
|
detectCircle(r)
|
||||||
|
detectCircle(c)
|
||||||
|
}
|
||||||
|
|
@ -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()
|
||||||
|
}
|
||||||
|
|
@ -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!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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())
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,10 @@ package main
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
func SlicesIndex[S []E, E int](s []string, v string) int {
|
// a generic function that takes a slice of any type and a value of that type, and returns the index of the value in the slice, or -1 if it is not found.
|
||||||
|
// The type parameters S and E are declared in square brackets before the function name, and they can be used in the function signature and body.
|
||||||
|
// The constraint comparable means that the type E must support the == operator, which is necessary for comparing the value with the elements of the slice.
|
||||||
|
func SlicesIndex[S []E, E comparable](s S, v E) int {
|
||||||
for i := range s {
|
for i := range s {
|
||||||
if v == s[i] {
|
if v == s[i] {
|
||||||
return i
|
return i
|
||||||
|
|
@ -11,27 +14,34 @@ func SlicesIndex[S []E, E int](s []string, v string) int {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
type List struct {
|
// represents a linked list of any type T. The type parameter T is used in the definition of List and its methods,
|
||||||
head, tail *element
|
// and it can be instantiated with any type when we create a List value. The type any is in fact defined as
|
||||||
|
// an empty interface. Thanks to duck-typing it can be used to represent any type, but it does not provide any
|
||||||
|
// operations on the values of that type.
|
||||||
|
type List[T any] struct {
|
||||||
|
head, tail *element[T]
|
||||||
}
|
}
|
||||||
|
|
||||||
type element struct {
|
// the generic element of the linked list
|
||||||
next *element
|
type element[T any] struct {
|
||||||
val int
|
next *element[T]
|
||||||
|
val T
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lst *List) Push(v int) {
|
// adds an instance of the generic type to the list
|
||||||
|
func (lst *List[T]) Push(v T) {
|
||||||
if lst.tail == nil {
|
if lst.tail == nil {
|
||||||
lst.head = &element{val: v}
|
lst.head = &element[T]{val: v}
|
||||||
lst.tail = lst.head
|
lst.tail = lst.head
|
||||||
} else {
|
} else {
|
||||||
lst.tail.next = &element{val: v}
|
lst.tail.next = &element[T]{val: v}
|
||||||
lst.tail = lst.tail.next
|
lst.tail = lst.tail.next
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lst *List) AllElements() []int {
|
// returns all elements of the list as a slice of the generic type.
|
||||||
var elems []int
|
func (lst List[T]) AllElements() []T {
|
||||||
|
var elems []T
|
||||||
for e := lst.head; e != nil; e = e.next {
|
for e := lst.head; e != nil; e = e.next {
|
||||||
elems = append(elems, e.val)
|
elems = append(elems, e.val)
|
||||||
}
|
}
|
||||||
|
|
@ -39,13 +49,21 @@ func (lst *List) AllElements() []int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
var s = []string{"foo", "bar", "zoo"}
|
var s = []string{"foo", "bar", "zoo"}
|
||||||
|
// The types S and E are explicitly specified as []string and string respectively.
|
||||||
|
fmt.Println("index of zoo:", SlicesIndex[[]string, string](s, "zoo"))
|
||||||
|
|
||||||
fmt.Println("index of zoo:", SlicesIndex(s, "zoo"))
|
var s2 = []int{2, 4, 5, 6}
|
||||||
|
// The type E is inferred from the type of the value 4, which is int,
|
||||||
|
// and the type S is inferred from the type of the slice s2, which is []int.
|
||||||
|
fmt.Println("index of 4: ", SlicesIndex(s2, 4))
|
||||||
|
|
||||||
lst := List{}
|
// instantiate a list of float64 elements
|
||||||
|
lst := List[float64]{}
|
||||||
lst.Push(10)
|
lst.Push(10)
|
||||||
lst.Push(13)
|
lst.Push(13)
|
||||||
lst.Push(23)
|
lst.Push(23)
|
||||||
|
lst.Push(23.3)
|
||||||
fmt.Println("list:", lst.AllElements())
|
fmt.Println("list:", lst.AllElements())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,18 +6,22 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
f := createFile("/tmp/defer.txt")
|
|
||||||
writeFile(f)
|
|
||||||
closeFile(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func createFile(p string) *os.File {
|
|
||||||
fmt.Println("creating")
|
fmt.Println("creating")
|
||||||
f, err := os.Create(p)
|
f, err := os.Create("/tmp/defer.txt")
|
||||||
|
|
||||||
|
// defer the closing of the file until the surrounding function returns.
|
||||||
|
// This ensures that the file will be closed even if there is a panic or an early return in the function.
|
||||||
|
defer closeFile(f)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return f
|
|
||||||
|
//will not be called in case of a panic before
|
||||||
|
writeFile(f)
|
||||||
|
|
||||||
|
// closeFile will be called here due to the defer-statement, even in case of a panic before.
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeFile(f *os.File) {
|
func writeFile(f *os.File) {
|
||||||
|
|
@ -27,8 +31,10 @@ func writeFile(f *os.File) {
|
||||||
|
|
||||||
func closeFile(f *os.File) {
|
func closeFile(f *os.File) {
|
||||||
fmt.Println("closing")
|
fmt.Println("closing")
|
||||||
err := f.Close()
|
var err error
|
||||||
|
if f != nil {
|
||||||
|
err = f.Close()
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
module gitty.informatik.hs-mannheim.de/steger/pr3-sose2026/go/03-modules
|
||||||
|
|
||||||
|
go 1.26.1
|
||||||
|
|
||||||
|
require github.com/google/uuid v1.6.0
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
|
@ -1,5 +1,27 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
func main() {
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
// importing the myMath package with an alias mm. This allows us to use mm instead of myMath to access the functions in the package.
|
||||||
|
// go packages are imported using their full path, which is the path to the package relative to the GOPATH or module root. .
|
||||||
|
mm "gitty.informatik.hs-mannheim.de/steger/pr3-sose2026/go/03-modules/myMath"
|
||||||
|
|
||||||
|
// the underscore is used to import a package solely for its side effects (i.e., the init function).
|
||||||
|
// This is useful when you want to initialize a package but do not need to access any of its exported functions or variables.
|
||||||
|
// _ "gitty.informatik.hs-mannheim.de/steger/pr3-sose2026/go/03-modules/myMath"
|
||||||
|
|
||||||
|
// importing a third-party package from GitHub. This package provides functions for generating UUIDs (Universally Unique Identifiers).
|
||||||
|
// To use this package, you need to run go get github.com/google/uuid to download and install the package in your Go workspace.
|
||||||
|
// Alternatively, you can run go mod tidy to automatically download and install any missing dependencies based on the imports in your code.
|
||||||
|
"github.com/google/uuid"
|
||||||
|
//run go get github.com/google/uuid
|
||||||
|
//or go mod tidy => go.sum
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(mm.Add(1, 2))
|
||||||
|
|
||||||
|
id := uuid.New()
|
||||||
|
fmt.Println("Generated UUID:", id)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
package myMath
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// init is a special function that is called automatically when the package is imported. It is used to initialize the package
|
||||||
|
// and can be used to set up any necessary state or perform any necessary setup before the package is used.
|
||||||
|
func init() {
|
||||||
|
fmt.Println("initializing myMath")
|
||||||
|
}
|
||||||
|
|
||||||
|
// functions that start with an uppercase letter are exported and can be accessed from outside the package
|
||||||
|
func Add(a, b int) int {
|
||||||
|
return a + b
|
||||||
|
}
|
||||||
|
|
||||||
|
// functions that start with a lowercase letter are not exported and cannot be accessed from outside the package
|
||||||
|
func greater(a, b int) bool {
|
||||||
|
return a > b
|
||||||
|
}
|
||||||
|
|
||||||
|
func Min(a, b int) int {
|
||||||
|
if greater(a, b) {
|
||||||
|
return b
|
||||||
|
} else {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
package myMath_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"gitty.informatik.hs-mannheim.de/steger/pr3-sose2026/go/03-modules/myMath"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAdd(t *testing.T) {
|
||||||
|
sum := myMath.Add(2, 3)
|
||||||
|
if sum != 5 {
|
||||||
|
t.Errorf("Add(2,3) = %v, want %v", sum, 5)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMin(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
in0 int
|
||||||
|
in1 int
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want int
|
||||||
|
}{
|
||||||
|
{"first greater", args{3, 2}, 2},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := myMath.Min(tt.args.in0, tt.args.in1); got != tt.want {
|
||||||
|
t.Errorf("Min() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue