1
0
Fork 0
Sebastian Steger 2026-03-12 06:31:52 +01:00
commit 827232a5b4
20 changed files with 463 additions and 0 deletions

View File

@ -0,0 +1,20 @@
# PR3 Code Repository
This repository contains all code of the PR3 lecture. This includes assignments. Solutions and code produced during the lecture is added incrementally during the semester.
## Usage
The code for each programming language is located in a dedicated subfolder. The individual development environment is defined by a [Development Container](https://containers.dev/) which ensures a uniform easy to set up coding experience on all platforms (Windows/MacOS/Linux). The following tools shall be available on the developer's machine:
- A [container runtime](https://en.wikipedia.org/wiki/OS-level_virtualization) such as [docker](https://www.docker.com/) or [podman](https://podman.io/). Windows users should install [Windows Subsystem for Linux (WSL)](https://learn.microsoft.com/en-us/windows/wsl/) beforehand.
- [Visual Studio Code](https://code.visualstudio.com/) along with the [Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension.
Follow these steps to get started:
1. Clone this repository into a local folder of your choice. Use a WSL folder on Windows.
2. Navigate to the subfolder of the desired programming language (e.g. `cd pr3-xyz/go`).
3. Open Visual Studio Code in that folder by executing `code .`
4. Click on *Reopen in Container* in the popup that appears on the bottom right corner: ![](vscode-devcontainer-popup.png)
This will open the folder in the dedicated *Development Container* that contains all required tools. Furthermore, programming language specific Visual Studio Code extensions are automatically installed inside the *Development Container* without affecting the host system.

View File

@ -0,0 +1,10 @@
FROM golang:1.26-bookworm
RUN apt-get update \
&& apt-get install -y build-essential \
&& rm -rf /var/lib/apt/lists/*
ARG USERNAME=developer
ARG USER_UID=1000
ARG USER_GID=$USER_UID
RUN groupadd --gid $USER_GID $USERNAME && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME

View File

@ -0,0 +1,16 @@
{
"name": "Go Dev Container",
"build": {
"dockerfile": "Dockerfile"
},
"postCreateCommand": "go install github.com/go-delve/delve/cmd/dlv@latest && go install github.com/cweill/gotests/gotests@v1.9.0 && go install golang.org/x/tools/gopls@latest && go install golang.org/x/tools/cmd/goimports@latest && go install honnef.co/go/tools/cmd/staticcheck@latest",
"customizations": {
"vscode": { "extensions": [
"golang.go",
"gruntfuggly.todo-tree",
"-github.copilot"
]}
},
"remoteUser": "developer",
"updateRemoteUserUID": true
}

12
go/.vscode/settings.json vendored 100644
View File

@ -0,0 +1,12 @@
{
"chat.disableAIFeatures": true,
"terminal.integrated.env.linux": {
"EDITOR": "code --wait"
},
"terminal.integrated.profiles.linux": {
"bash": {
"path": "bash",
"icon": "terminal-bash"
}
}
}

View File

@ -0,0 +1,17 @@
# Hello World
## Run
`go run hello-world.go`
## Build
`go build hello-world.go`
## Formatting
`go fmt hello-world.go`
## Linting
`go vet hello-world.go`
### Examples
1. `fmt.Printf("hello world, %s\n")`
2. `a := 7` (already caught by the compiler)

View File

@ -0,0 +1,3 @@
module gitty.informatik.th-mannheim.de/steger/pr3-sose2026/go/00-hello-world/hello-world
go 1.26.0

View File

@ -0,0 +1,7 @@
package main
import "fmt"
func main() {
fmt.Println("hello world")
}

View File

@ -0,0 +1,84 @@
# Go By Example
<https://gobyexample.com/>
# Assignment 1 - Simple Calculator
## Objective
Write a Go program that performs basic mathematical operations (addition, subtraction, multiplication, and division) based on user input.
## Steps
1. Define constants for valid operations (*add*,*subtract*,*multiply*,*divide*).
2. Use variables to store user inputs and computed results.
3. Use a loop to allow the user to perform multiple calculations until they choose to exit.
4. Validate inputs using statements (e.g., handle division by zero).
5. Use a statement to perform the selected mathematical operation.
## Example Output
```
Enter operation (add, subtract, multiply, divide, exit): add
Enter the first number: 5
Enter the second number: 3
Result: 8
Enter operation (add, subtract, multiply, divide, exit): divide
Enter the first number: 10
Enter the second number: 0
Error: Division by zero is not allowed!
Enter operation (add, subtract, multiply, divide, exit): exit
Goodbye!
```
## Hint
The program can use the `fmt.Scan` function to accept user input.
# Assignment 2 - Inventory Management System
## Objective
Create a program that simulates an inventory management system for a store.
## Steps
1. Define product categories (e.g., Electronics, Groceries, Clothes) using `const` and `iota`.
2. Store a fixed list of initial product names in an **array**.
3. Convert the array into a **slice** so the inventory can grow or shrink dynamically.
4. Use a **map** to associate product names with details like quantity, price, and category.
5. Implement the following **functions**:
- *AddProduct*: Add a new product to the inventory.
- *RemoveProduct*: Remove a product from the inventory.
- *DisplayInventory*: Display all products with their details.
- *UpdateQuantity*: Update the quantity of a product.
## Example Output
```
Welcome to the Inventory Manager!
Initial Inventory:
1. Laptop - Electronics (Price: $1000, Quantity: 5)
2. Apples - Groceries (Price: $2, Quantity: 50)
3. T-shirt - Clothes (Price: $10, Quantity: 20)
Adding a new product: Phone (Electronics, Price: $800, Quantity: 10)
Updated Inventory:
1. Laptop - Electronics (Price: $1000, Quantity: 5)
2. Apples - Groceries (Price: $2, Quantity: 50)
3. T-shirt - Clothes (Price: $10, Quantity: 20)
4. Phone - Electronics (Price: $800, Quantity: 10)
Updating quantity for Apples: New Quantity = 30
Removing product: T-shirt
Final Inventory:
1. Laptop - Electronics (Price: $1000, Quantity: 5)
2. Apples - Groceries (Price: $2, Quantity: 30)
3. Phone - Electronics (Price: $800, Quantity: 10)
```
- Use **arrays** to store initial product information.
- Use **slices** to dynamically manage items in the inventory.
- Use **maps** to track product details (e.g., quantity or price).
- Define **functions** for adding, removing, and displaying products.
- Use **enums** (via constants) to represent product categories.

View File

@ -0,0 +1,22 @@
package main
import (
"fmt"
)
func main() {
//TODO: implement according to README.md
//the following code just demonstrates how to use fmt.Scan
var str string
fmt.Print("Please enter a string: ")
fmt.Scan(&str)
var x float64
fmt.Print("Please enter a float: ")
fmt.Scan(&x)
fmt.Printf("You entered '%s' and %f\n", str, x)
}

View File

@ -0,0 +1,50 @@
package main
type Product struct {
Name string
Price float64
Quantity int
Category string //TODO: use enum instead
}
func addProduct(inventory *[]Product, name string, price float64, quantity int, category string) {
//TODO: implement
}
func removeProduct(inventory *[]Product, name string) {
//TODO: implement
}
func updateQuantity(inventory *[]Product, name string, newQuantity int) {
//TODO: implement
}
func displayInventory(inventory []Product) {
//TODO: implement
}
func main() {
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"},
}
// Display initial inventory
displayInventory(inventory)
// Add a new product
addProduct(&inventory, "Phone", 800, 10, "Electronics")
// Display updated inventory
displayInventory(inventory)
// Update the quantity of an existing product
updateQuantity(&inventory, "Apples", 30)
// Remove a product
removeProduct(&inventory, "T-shirt")
// Display final inventory
displayInventory(inventory)
}

View File

@ -0,0 +1,51 @@
package main
import "fmt"
func SlicesIndex[S []E, E int](s []string, v string) int {
for i := range s {
if v == s[i] {
return i
}
}
return -1
}
type List struct {
head, tail *element
}
type element struct {
next *element
val int
}
func (lst *List) Push(v int) {
if lst.tail == nil {
lst.head = &element{val: v}
lst.tail = lst.head
} else {
lst.tail.next = &element{val: v}
lst.tail = lst.tail.next
}
}
func (lst *List) AllElements() []int {
var elems []int
for e := lst.head; e != nil; e = e.next {
elems = append(elems, e.val)
}
return elems
}
func main() {
var s = []string{"foo", "bar", "zoo"}
fmt.Println("index of zoo:", SlicesIndex(s, "zoo"))
lst := List{}
lst.Push(10)
lst.Push(13)
lst.Push(23)
fmt.Println("list:", lst.AllElements())
}

View File

@ -0,0 +1,35 @@
package main
import (
"fmt"
"os"
)
func main() {
f := createFile("/tmp/defer.txt")
writeFile(f)
closeFile(f)
}
func createFile(p string) *os.File {
fmt.Println("creating")
f, err := os.Create(p)
if err != nil {
panic(err)
}
return f
}
func writeFile(f *os.File) {
fmt.Println("writing")
fmt.Fprintln(f, "data")
}
func closeFile(f *os.File) {
fmt.Println("closing")
err := f.Close()
if err != nil {
panic(err)
}
}

View File

@ -0,0 +1,5 @@
package main
func main() {
}

View File

View File

@ -0,0 +1,9 @@
# Assignment
Implement an arbitrary [design pattern](https://refactoring.guru/design-patterns/catalog) in Go.
1. Create a package named `patterns` in the `04-design-patterns` folder
2. Implement the design pattern in that package
3. Implement a corresponding unit test
4. Create an example application that uses the design pattern in the file `04-design-patterns/main.go`
5. Zip the source code and upload

View File

@ -0,0 +1,17 @@
package main
func print(ci <-chan int) {
//TODO: implement
}
func main() {
c := make(chan int)
c <- 1
c <- 2
c <- 3
close(c)
print(c)
}

View File

@ -0,0 +1,86 @@
package main
import (
"fmt"
"math/rand"
"sort"
"time"
)
func mergeSortSequential(data []float64) {
if len(data) <= 1 {
return
}
mid := len(data) / 2
left := data[:mid]
right := data[mid:]
mergeSortSequential(left)
mergeSortSequential(right)
copy(data, merge(left, right))
}
func merge(left, right []float64) []float64 {
result := make([]float64, 0, len(left)+len(right))
i, j := 0, 0
for i < len(left) && j < len(right) {
if left[i] < right[j] {
result = append(result, left[i])
i++
} else {
result = append(result, right[j])
j++
}
}
result = append(result, left[i:]...)
result = append(result, right[j:]...)
return result
}
func main() {
//1. DATA CREATION
data := make([]float64, 1000*1000*20)
for i := range data {
data[i] = rand.Float64() * 100 // Random floats between 0 and 100
}
expected := make([]float64, len(data))
copy(expected, data)
sort.Float64s(expected)
//2. SORTING
start := time.Now()
mergeSortSequential(data)
elapsed := time.Since(start)
fmt.Printf("MergeSort took %s\n", elapsed)
//3. VERIFICATION
if sort.Float64sAreSorted(data) {
fmt.Println("Data is sorted correctly")
} else {
fmt.Println("Data is NOT sorted correctly")
}
if len(data) != len(expected) {
fmt.Println("Data and expected slices have different lengths")
return
}
for i := range data {
if data[i] != expected[i] {
fmt.Println("Data and expected slices do not match")
return
}
}
fmt.Println("Data and expected slices match")
}

View File

@ -0,0 +1,19 @@
package main
import (
"math/rand"
"time"
)
func main() {
ch1 := make(chan string)
go func() {
time.Sleep(time.Duration(rand.Intn(5)+1) * time.Second)
ch1 <- "Message from channel 1"
}()
msg1 := <-ch1
println("Received:", msg1)
}

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB