From cc11d9e405e658d8306a6904254fc9099522a153 Mon Sep 17 00:00:00 2001
From: Andrej Rasevic <andrej@rasevicengineering.com>
Date: Fri, 10 Jan 2025 17:24:57 -0500
Subject: [PATCH] adding exercise 2

---
 Exercises/Exercise2/Exercise2_Description.md | 16 ++++
 Exercises/Exercise2/cmd/main.go              | 86 ++++++++++++++++++
 Exercises/Exercise2/go.mod                   |  3 +
 Exercises/Exercise2/todo.go                  | 91 ++++++++++++++++++++
 4 files changed, 196 insertions(+)
 create mode 100644 Exercises/Exercise2/Exercise2_Description.md
 create mode 100644 Exercises/Exercise2/cmd/main.go
 create mode 100644 Exercises/Exercise2/go.mod
 create mode 100644 Exercises/Exercise2/todo.go

diff --git a/Exercises/Exercise2/Exercise2_Description.md b/Exercises/Exercise2/Exercise2_Description.md
new file mode 100644
index 0000000..a8add09
--- /dev/null
+++ b/Exercises/Exercise2/Exercise2_Description.md
@@ -0,0 +1,16 @@
+# Exercise 2: 
+
+## Due Date: Tuesday, January 14, 2025 11:55 PM EST
+## Objectives: To get familiar with using fundamentals of Go idioms and data structures.
+
+## Specifications/Requirements
+1. You are given a go module inside of the Exercises/Exercise2 folder. You are building a command line application that allows you to manage a "todo" list. The interface for your command line application has been provided for you. It is inside of the cmd/main.go file. You do not need to touch any code in that file but you should understand it and study it. The work you need to do is to complete the TODO items inside of the todo.go file. They consist of the following:  
+*   complete the definition of the type item struct  
+*   complete the Add method which adds a new todo item to the list
+*   complete the Complete method which updates the given todo item as completed
+*   complete the Delete method which removes the given todo item from the list 
+
+There are several functions in that file that have also been completed for you and that main.go invoke. Be careful not to alter these. To compile your application you need to run the following command from inside of your exercise 2 directory:
+go build cmd/main.go
+
+If your program compiles successfully this will generate a binary named main at the root level of your application (i.e. just inside of your exercise2 directory). To deliver your submission you will need to commit your changes locally and push to your repo on the university gitlab server. You __MUST__ verify that your push was successful by logging into gitlab and verifying that you can see your files. You also __should not__ commit the binary your program generates. 
diff --git a/Exercises/Exercise2/cmd/main.go b/Exercises/Exercise2/cmd/main.go
new file mode 100644
index 0000000..51a0f69
--- /dev/null
+++ b/Exercises/Exercise2/cmd/main.go
@@ -0,0 +1,86 @@
+package main
+
+import (
+  "flag"
+  "fmt"
+  "os"
+
+  "cmsc398b/exercise2"
+)
+
+// Default file name
+var todoFileName = "todo.json"
+
+func main() {
+  // Parsing command line flags
+  task := flag.String("task", "", "Task to be added to the ToDo list")
+  list := flag.Bool("list", false, "List all tasks")
+  complete := flag.Int("complete", 0, "Item to be completed")
+	delete := flag.Int("delete", -1, "Item to be deleted")
+
+  flag.Usage = func() {
+    fmt.Fprintf(flag.CommandLine.Output(),
+      "%s cli client. CMSC398B Winter 2024 Exercise 2\n", os.Args[0])
+    fmt.Fprintln(flag.CommandLine.Output(), "Usage information:")
+    flag.PrintDefaults()
+  }
+
+  flag.Parse()
+
+  // Check if the user defined the ENV VAR for a custom file name
+  if os.Getenv("TODO_FILENAME") != "" {
+    todoFileName = os.Getenv("TODO_FILENAME")
+  }
+
+  // Define an items list
+  l := &todo.List{}
+
+  // Use the Get command to read to do items from file
+  if err := l.Get(todoFileName); err != nil {
+    fmt.Fprintln(os.Stderr, err)
+    os.Exit(1)
+  }
+
+  // Decide what to do based on the provided flags
+  switch {
+  case *list:
+    // List current to do items
+    fmt.Print(l)
+  case *complete > 0:
+    // Complete the given item
+    if err := l.Complete(*complete); err != nil {
+      fmt.Fprintln(os.Stderr, err)
+      os.Exit(1)
+    }
+
+    // Save the new list
+    if err := l.Save(todoFileName); err != nil {
+      fmt.Fprintln(os.Stderr, err)
+      os.Exit(1)
+    }
+  case *task != "":
+    // Add the task
+    l.Add(*task)
+
+    // Save the new list
+    if err := l.Save(todoFileName); err != nil {
+      fmt.Fprintln(os.Stderr, err)
+      os.Exit(1)
+    }
+	case *delete >= 0:
+		// Delete the given todo
+		if err := l.Delete(*delete); err != nil {
+      fmt.Fprintln(os.Stderr, err)
+      os.Exit(1)
+    }	
+		// Save the new list
+		if err := l.Save(todoFileName); err != nil {
+		fmt.Fprintln(os.Stderr, err)
+		os.Exit(1)
+    }
+  default:
+    // Invalid flag provided
+    flag.Usage()
+    os.Exit(1)
+  }
+}
diff --git a/Exercises/Exercise2/go.mod b/Exercises/Exercise2/go.mod
new file mode 100644
index 0000000..2950274
--- /dev/null
+++ b/Exercises/Exercise2/go.mod
@@ -0,0 +1,3 @@
+module cmsc398b/exercise2
+
+go 1.23
diff --git a/Exercises/Exercise2/todo.go b/Exercises/Exercise2/todo.go
new file mode 100644
index 0000000..2425008
--- /dev/null
+++ b/Exercises/Exercise2/todo.go
@@ -0,0 +1,91 @@
+package todo
+
+import (
+  "encoding/json"
+  "errors"
+  "fmt"
+  "os"
+  "time"
+)
+
+//TODO
+// item struct represents a ToDo item
+// Members: Task (string) Done (bool) CreateAt (time.Time) CompletedAt (time.Time)
+type item struct {
+	CompletedAt time.Time
+}
+
+// List represents a list of ToDo items
+type List []item
+
+//String prints out a formatted list
+//Implements the fmt.Stringer interface
+func (l *List) String() string {
+  formatted := ""
+
+  for k, t := range *l {
+    prefix := "  "
+    if t.Done {
+      prefix = "X "
+    }
+
+    // Adjust the item number k to print numbers starting from 1 instead of 0
+    formatted += fmt.Sprintf("%s%d: %s\n", prefix, k+1, t.Task)
+  }
+
+  return formatted
+}
+
+// TODO
+// Add creates a new todo item and appends it to the list
+func (l *List) Add(task string) {
+ 
+}
+
+//TODO
+// Complete method marks a ToDo item as completed by
+// setting Done = true and CompletedAt to the current time
+func (l *List) Complete(i int) error {
+  
+  //if i <= 0 || i > len(ls) {
+    //return fmt.Errorf("Item %d does not exist", i)
+  //}
+
+  return nil
+}
+
+//TODO
+// Delete method deletes a ToDo item from the list
+func (l *List) Delete(i int) error {
+  
+  return nil
+}
+
+// Save method encodes the List as JSON and saves it
+// using the provided file name
+func (l *List) Save(filename string) error {
+  data, err := json.Marshal(l)
+  if err != nil {
+    return err
+  }
+
+  return os.WriteFile(filename, data, 0644)
+}
+
+// Get method opens the provided file name, decodes
+// the JSON data and parse into a List
+func (l *List) Get(filename string) error {
+  file, err := os.ReadFile(filename)
+  if err != nil {
+    if errors.Is(err, os.ErrNotExist) {
+      return nil
+    }
+    return err
+  }
+
+  if len(file) == 0 {
+    return nil
+  }
+
+  return json.Unmarshal(file, l)
+}
-- 
GitLab