diff --git a/Checkpoint3/Checkpoint3.csproj b/Checkpoint3/Checkpoint3.csproj new file mode 100644 index 00000000..56f6f2cf --- /dev/null +++ b/Checkpoint3/Checkpoint3.csproj @@ -0,0 +1,12 @@ + + + + Exe + netcoreapp2.1 + + + + + + + diff --git a/Checkpoint3/Program.cs b/Checkpoint3/Program.cs new file mode 100644 index 00000000..dbff070b --- /dev/null +++ b/Checkpoint3/Program.cs @@ -0,0 +1,658 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore; +namespace Checkpoint3 +{ + class Program + { + static void Main(string[] args) + { + //create the context + Context todoContext = new Context(); + + //create the table + todoContext.Database.EnsureCreated(); + //begin user interaction + System.Console.WriteLine("-----------------------"); + System.Console.WriteLine("Welcome to My ToDo App!"); + System.Console.WriteLine("-----------------------"); + //the initial state of the program is to list currently incomplete todos, this will list nothing first time the app runs + Utils.ListIncomplete(todoContext); + //then give a menu of commands + Utils.OptionsMenu(); + bool needsCommand = true; + while (needsCommand) + { + //read the user's input + string input = Console.ReadLine(); + //Parse the input into an int if possible + bool successfullyParsed = int.TryParse(input, out int parsedInput); + + if (parsedInput == 1) + { + Utils.AddToDo(todoContext); + } + else if (parsedInput == 2) + { + Utils.UpdateToDo(todoContext); + } + else if (parsedInput == 3) + { + Utils.MarkComplete(todoContext); + } + else if (parsedInput == 4) + { + Utils.Delete(todoContext); + } + else if (parsedInput == 5) + { + Utils.ListComplete(todoContext); + } + else if (parsedInput == 6) + { + Utils.ListAll(todoContext); + } + else if (parsedInput == 7) + { + Utils.ListType(todoContext, 7); + } + else if (parsedInput == 8) + { + Utils.ListType(todoContext, 8); + } + else if (parsedInput == 9) + { + Utils.ListType(todoContext, 9); + } + else if (parsedInput == 10) + { + System.Console.WriteLine("Thank you for using My ToDo App. See you next time!"); + needsCommand = false; + } + else if (input.ToLower() == "help") + { + Utils.OptionsMenu(); + } + else + { + System.Console.WriteLine("Here's your current ToDo list!"); + Utils.ListIncomplete(todoContext); + } + } + } + } + + public enum Type { general, personal, work, school } + //default position for a new item will be incomplete + public enum Status { incomplete, complete } + //begin item class + public class Item + { + //Item properties + public int id { get; set; } + public int displayID { get; set; } + public string description { get; set; } + public Type type { get; set; } + public Status status { get; set; } + public DateTime deadline { get; set; } + + public Item() { } + + //new todo item + public Item(string description) + { + this.description = description; + } + } + //Utils class that contains Static medthod + public static class Utils + { + //method ListIncomplete takes in todoContext from main and prints out any todos that need completion, this is the default state for the program + public static void ListIncomplete(Context todoContext) + { + var results = from t in todoContext.todos + where (t.status == Status.incomplete) + select t; + + //Will display the following message if there are no incomplete todos + if (results.Count() == 0) + { + System.Console.WriteLine("You currently have nothing ToDo."); + System.Console.WriteLine(""); + } + //if there are incomplete todos, list them + else + { + System.Console.WriteLine("-----------------"); + System.Console.WriteLine("My Current ToDos:"); + System.Console.WriteLine("-----------------"); + //call function to print the list based on the results produced above + WriteList(results); + System.Console.WriteLine(""); + } + //display ids need to be saved to the database so that the user can use them to identify the item the'd like to manipulate + todoContext.SaveChanges(); + } + //method OptionsMenu simply prints the menu of options for user to select from + public static void OptionsMenu() + { + System.Console.WriteLine("-------"); + System.Console.WriteLine("Actions"); + System.Console.WriteLine("-------"); + System.Console.WriteLine("Enter 1 to ADD a new ToDo"); + System.Console.WriteLine("Enter 2 to UPDATE an existing ToDo"); + System.Console.WriteLine("Enter 3 to MARK a ToDo COMPLETE"); + System.Console.WriteLine("Enter 4 to DELETE an existing ToDo"); + System.Console.WriteLine(""); + System.Console.WriteLine("----------"); + System.Console.WriteLine("List Views"); + System.Console.WriteLine("----------"); + System.Console.WriteLine("Enter 5 to view COMPLETED ToDos ONLY"); + System.Console.WriteLine("Enter 6 to view ALL ToDos on record"); + System.Console.WriteLine("Enter 7 to view PERSONAL ToDos ONLY"); + System.Console.WriteLine("Enter 8 to view WORK ToDos ONLY"); + System.Console.WriteLine("Enter 9 to view SCHOOL ToDos ONLY"); + System.Console.WriteLine(""); + System.Console.WriteLine("-------------"); + System.Console.WriteLine("Exit Strategy"); + System.Console.WriteLine("-------------"); + System.Console.WriteLine("Enter 10 to QUIT "); + System.Console.WriteLine(""); + System.Console.WriteLine("----"); + System.Console.WriteLine("Help"); + System.Console.WriteLine("----"); + System.Console.WriteLine(@"Enter 'help' to get HELP"); + System.Console.WriteLine(""); + System.Console.WriteLine("----------------"); + System.Console.WriteLine("My Current ToDos"); + System.Console.WriteLine("----------------"); + System.Console.WriteLine("Enter ANY OTHER KEY to view your currently incomplete ToDos!"); + } + //FUNCTION 1: AddToDo takes in todo context and uses this context to add a new to do to the list + public static void AddToDo(Context todoContext) + { + //take input for new ToDo description + System.Console.WriteLine("Please enter your new ToDo:"); + string description = Console.ReadLine(); + //initialize a new item with a description + Item newItem = new Item(description); + todoContext.todos.Add(newItem); + + //Prompt user for a type for this todo + set type + System.Console.WriteLine("What type of ToDo is this?"); + SetType(newItem); + //Prompt user for a deadline for this todo + set type + System.Console.WriteLine("When is the deadline for this ToDo?"); + SetDeadline(newItem); + System.Console.WriteLine("Your ToDo has been added. Thank you!"); + System.Console.WriteLine(""); + //save changes to store this new ToDo and it's attributes + todoContext.SaveChanges(); + } + //method SetType takes in an item and updates it's type property + public static void SetType(Item item) + { + bool loop = true; + while (loop) + { + //give type options + System.Console.WriteLine("Please enter 1 for Personal, 2 for Work, 3 for School, or 4 for general."); + + //read the user's input + string input = Console.ReadLine(); + //Parse the input into an int if possible + bool successfullyParsed = int.TryParse(input, out int parsedInput); + //begin conditional statements to set the type according to the number entered + if (parsedInput == 1) + { + item.type = Type.personal; + loop = false; + } + else if (parsedInput == 2) + { + item.type = Type.work; + loop = false; + } + else if (parsedInput == 3) + { + item.type = Type.school; + loop = false; + } + else if (parsedInput == 4) + { + item.type = Type.general; + loop = false; + } + else + { + Console.WriteLine("Not a valid entry. Please try again."); + } + } + } + //method SetDeadline takes in an item and sets it's deadline property + public static void SetDeadline(Item item) + { + //prompt user for a deadline + System.Console.WriteLine("Please enter the deadline for this ToDo. Follow this Date/Time format: MM/DD/YYYY HH:MM:SS AM/PM."); + System.Console.WriteLine("Don't want to set a deadline? No problem. Press any key to continue with no deadline."); + //read the user's input + string input = Console.ReadLine(); + //Parse the input into a datetime if possible + bool successfullyParsed = DateTime.TryParse(input, out DateTime dt); + if (successfullyParsed) + { + //set the item's deadline to parsed DateTime input + item.deadline = dt; + } + } + //FUNCTION 2: UpdateToDo takes in the todoContext and makes changes to a specified todo's description, type or deadline + public static void UpdateToDo(Context todoContext) + { + //begin loop to confirm and update the ToDo + bool loop = true; + while (loop) + { + //prompt for displayID + System.Console.WriteLine("Please enter the ID of the ToDo item you would like to update:"); + //read the user's input + string input = Console.ReadLine(); + //Parse the input into an int if possible + bool successfullyParsed = int.TryParse(input, out int parsedInput); + var match = from t in todoContext.todos + where t.displayID == parsedInput + select t; + //if one unique match is returned, update this item + if (match.Count() == 1) + { + foreach (Item item in match) + { + System.Console.WriteLine($"Thanks. Here's the current description of this ToDo: {item.description}"); + System.Console.WriteLine("Please enter your new description below OR enter 0 to keep this description."); + string newDescription = Console.ReadLine(); + if (newDescription != "0") + { + item.description = newDescription; + } + System.Console.WriteLine("Thanks. Would you like to update the type? Enter any key to update OR enter 0 to keep the current type."); + string newType = Console.ReadLine().ToLower(); + if (newType != "0") + { + SetType(item); + } + System.Console.WriteLine("Thanks. Would you like to update the deadline? Enter any key to update OR enter 0 to keep the current deadline."); + string newDeadline = Console.ReadLine().ToLower(); + if (newDeadline != "0") + { + SetDeadline(item); + } + System.Console.WriteLine("Your ToDo has been updated. Thank you!"); + System.Console.WriteLine(""); + //exit loop + loop = false; + } + } + //If the user has run multiple lists recently, there can be multiple equivalent display ids. + //In that case, guide the user to match Item by description + else if (match.Count() > 1) + { + System.Console.WriteLine("There are multiple ToDos with that ID. Sorry about that! Please enter the description of the item you'd like to mark complete."); + string descriptionMatch = Console.ReadLine().ToLower().Trim(); + //tracking if a match is found. In case it's not, I want to display some feedback to the user. + bool matchFound = false; + foreach (Item item in match) + { + //if match complete the task and move on + if (descriptionMatch == item.description.ToLower().Trim()) + { + System.Console.WriteLine("Great, let's update it. Please enter your new description below OR enter 0 to keep the current description."); + string newDescription = Console.ReadLine(); + if (newDescription != "0") + { + item.description = newDescription; + } + System.Console.WriteLine("Thanks. Would you like to update the type? Enter any key to update OR enter 0 to keep the current type."); + string newType = Console.ReadLine().ToLower(); + if (newType != "0") + { + SetType(item); + } + System.Console.WriteLine("Thanks. Would you like to update the deadline? Enter any key to update OR enter 0 to keep the current deadline."); + string newDeadline = Console.ReadLine().ToLower(); + if (newDeadline != "0") + { + SetDeadline(item); + } + System.Console.WriteLine("Your ToDo has been updated. Thank you!"); + System.Console.WriteLine(""); + matchFound = true; + loop = false; + break; + } + //if no match keep searching + else + { + matchFound = false; + continue; + } + } + //let user no if no match was found based on the description they entered + if (matchFound == false) + { + System.Console.WriteLine("Sorry, that description did not return a match. Please try again."); + } + } + else + { + Console.WriteLine("That ID did not return a match. Please try again."); + } + //save any changes made in this method to the database + todoContext.SaveChanges(); + } + } + //FUNCTION 3: MarkComplete take in todoContext and updates the status property to complete + public static void MarkComplete(Context todoContext) + { + //begin loop to confirm and mark the ToDo complete + bool loop = true; + while (loop) + { + //prompt for displayID + System.Console.WriteLine("Please enter the ID of the ToDo item you would like to mark complete:"); + //read the user's input + string input = Console.ReadLine(); + //Parse the input into an int if possible + bool successfullyParsed = int.TryParse(input, out int parsedInput); + var match = from t in todoContext.todos + where t.displayID == parsedInput + select t; + //if one unique match is returned, mark this item complete + if (match.Count() == 1) + { + foreach (Item item in match) + { + System.Console.WriteLine($"Thanks. Here's the current description of this ToDo: {item.description}"); + System.Console.WriteLine("Enter any key to continue marking this ToDo complete OR enter 0 to keep this ToDo incomplete."); + string newStatus = Console.ReadLine(); + if (newStatus != "0") + { + item.status = Status.complete; + item.displayID = 0; + System.Console.WriteLine("Your ToDo has been marked complete. Thank you!"); + System.Console.WriteLine(""); + + } + else if (newStatus == "0") + { + System.Console.WriteLine("Great, it will stay incomplete. Thank you!"); + System.Console.WriteLine(""); + } + } + + loop = false; + } + //If the user has run multiple lists recently, there can be multiple equivalent display ids. + //In that case, guide the user to match Item by description + else if (match.Count() > 1) + { + System.Console.WriteLine("There are multiple ToDos with that ID. Sorry about that! Please enter the description of the item you'd like to mark complete."); + string descriptionMatch = Console.ReadLine().ToLower().Trim(); + //tracking if a match is found. In case it's not, I want to display some feedback to the user. + bool matchFound = false; + foreach (Item item in match) + { + //if match complete the task and move on + if (descriptionMatch == item.description.ToLower().Trim()) + { + item.status = Status.complete; + item.displayID = 0; + System.Console.WriteLine("Your ToDo has been marked complete. Thank you!"); + System.Console.WriteLine(""); + matchFound = true; + loop = false; + break; + } + //if no match keep searching + else + { + matchFound = false; + continue; + } + } + //let user no if no match was found based on the description they entered + if (matchFound == false) + { + System.Console.WriteLine("Sorry, that description did not return a match. Please try again."); + } + } + else + { + Console.WriteLine("That ID did not return a match. Please try again."); + } + //save any changes made in this method to the database + todoContext.SaveChanges(); + } + } + //FUNCTION 4: DELETE takes in the todoContext and removes a todo from the list + public static void Delete(Context todoContext) + { + //begin loop to confirm and mark the ToDo complete + bool loop = true; + while (loop) + { + //prompt for displayID + System.Console.WriteLine("Please enter the ID of the ToDo item you would like to delete:"); + //read the user's input + string input = Console.ReadLine(); + //Parse the input into an int if possible + bool successfullyParsed = int.TryParse(input, out int parsedInput); + //find a display ID match to the input + var match = from t in todoContext.todos + where t.displayID == parsedInput + select t; + //if one match is found, delete it + if (match.Count() == 1) + { + foreach (Item item in match) + { + System.Console.WriteLine($"Thanks. Here's the current description of this ToDo: {item.description}"); + System.Console.WriteLine("Enter any key to permanently delete this ToDo OR enter 0 to keep this ToDo in your database."); + string remove = Console.ReadLine(); + if (remove != "0") + { + item.displayID = 0; + todoContext.todos.Remove(item); + System.Console.WriteLine("Your ToDo has been deleted. Thank you!"); + System.Console.WriteLine(""); + } + else if (remove == "0") + { + System.Console.WriteLine("Great, it will stay in the database. Thank you!"); + System.Console.WriteLine(""); + } + } + //exit loop + loop = false; + } + //If the user has run multiple lists recently, there can be multiple equivalent display ids. + //In that case, guide the user to match Item by description + else if (match.Count() > 1) + { + System.Console.WriteLine("There are multiple ToDos with that ID. Sorry about that! Please enter the description of the item you'd like to mark complete."); + string descriptionMatch = Console.ReadLine().ToLower().Trim(); + //tracking if a match is found. In case it's not, I want to display some feedback to the user. + bool matchFound = false; + foreach (Item item in match) + { + //if match complete the task and move on + if (descriptionMatch == item.description.ToLower().Trim()) + { + item.displayID = 0; + todoContext.todos.Remove(item); + System.Console.WriteLine("Your ToDo has been deleted. Thank you!"); + System.Console.WriteLine(""); + matchFound = true; + loop = false; + break; + } + //if no match keep searching + else + { + matchFound = false; + continue; + } + } + //let user no if no match was found based on the description they entered + if (matchFound == false) + { + System.Console.WriteLine("Sorry, that description did not return a match. Please try again."); + } + } + else + { + Console.WriteLine("That ID did not return a match. Please try again."); + } + //save any changes made in this method to the database + todoContext.SaveChanges(); + } + } + //FUNCTION 5: ListComplete takes in a todocontext and prints the todo items with a complete status to the screen + public static void ListComplete(Context todoContext) + { + //find the complete todos in the list + var results = from t in todoContext.todos + where (t.status == Status.complete) + select t; + System.Console.WriteLine("My Completed ToDos:"); + WriteList(results); + System.Console.WriteLine(""); + todoContext.SaveChanges(); + } + //FUNCTION 6: takes in a todo context and returns all todos sorted by status (with incomplete todos first) + public static void ListAll(Context todoContext) + { + //get all todos and order by status + var results = from t in todoContext.todos + orderby t.status ascending + select t; + System.Console.WriteLine("----------"); + System.Console.WriteLine("All ToDos:"); + System.Console.WriteLine("----------"); + + //call function that prints the items based on the above results returned + WriteList(results); + System.Console.WriteLine(""); + //display ids need to be saved so that the user can select by them + todoContext.SaveChanges(); + } + //FUNCTION 7-9: take in a todoContext and an integer and list either Personal, Work, or school todos only + public static void ListType(Context todoContext, int type) + { + //conditional to sort out which type we should list + if (type == 7) + { + var results = from t in todoContext.todos + where t.type == Type.personal + select t; + System.Console.WriteLine("------------------"); + System.Console.WriteLine("My Personal Todos:"); + System.Console.WriteLine("------------------"); + //call function that prints the items based on the above results returned + WriteList(results); + } + else if (type == 8) + { + var results = from t in todoContext.todos + where t.type == Type.work + select t; + System.Console.WriteLine("--------------"); + System.Console.WriteLine("My Work Todos:"); + System.Console.WriteLine("--------------"); + //call function that prints the items based on the above results returned + WriteList(results); + } + else if (type == 9) + { + var results = from t in todoContext.todos + where t.type == Type.school + select t; + System.Console.WriteLine("----------------"); + System.Console.WriteLine("My School Todos:"); + System.Console.WriteLine("----------------"); + //call function that prints the items based on the above results returned + WriteList(results); + } + System.Console.WriteLine(""); + //display ids need to be saved so that the user can select by them + todoContext.SaveChanges(); + } + //Since many functions were ending with the same process for printing a list, I created a function to avoid copy/paste for the process of printing the list + public static void WriteList(IQueryable results) + { + //Will display the following message if there are no todos in this results query + if (results.Count() == 0) + { + System.Console.WriteLine("This ToDo list is empty."); + } + //if there are todos, list them + else + { + //initialize counter + int i = 0; + //create and print heading + string head1 = "ID"; + string head2 = "Description"; + string head3 = "Type"; + string head4 = "Deadline"; + string head5 = "Status"; + System.Console.WriteLine(head1.PadRight(3) + "| " + head2.PadRight(30) + "| " + head3.PadRight(25) + "| " + head4.PadRight(25) + "| " + head5.PadRight(15)); + System.Console.WriteLine("-".PadRight(102, '-')); + foreach (Item item in results) + { + i++; + item.displayID = i; + //use counter to set display id + if (item.deadline == DateTime.MinValue) + { + string column1 = item.displayID.ToString(); + string column2 = item.description.ToString(); + //display only the first 29 characters of a string if the todo is longer than 30 characters + if (column2.Length > 30) + { + column2 = column2.Substring(0, 29); + } + string column3 = item.type.ToString(); + string column4 = "no deadline"; + string column5 = item.status.ToString(); + System.Console.WriteLine(column1.PadRight(3) + "| " + column2.PadRight(30) + "| " + column3.PadRight(25) + "| " + column4.PadRight(25) + "| " + column5.PadRight(15)); + } + else + { + string column1 = item.displayID.ToString(); + string column2 = item.description.ToString(); + //display only the first 29 characters of a string if the todo is longer than 30 characters + if (column2.Length > 30) + { + column2 = column2.Substring(0, 29); + } + string column3 = item.type.ToString(); + string column4 = item.deadline.ToString(); + string column5 = item.status.ToString(); + System.Console.WriteLine(column1.PadRight(3) + "| " + column2.PadRight(30) + "| " + column3.PadRight(25) + "| " + column4.PadRight(25) + "| " + column5.PadRight(15)); + } + } + } + } + } + + //context class which creates the set of todos and calls on the Entity Framework to help link to the database + public class Context : DbContext + { + public DbSet todos { get; set; } + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + //link to the database + optionsBuilder.UseSqlite("Filename=./todoapp.db"); + } + } +} diff --git a/Checkpoint3/todoapp.db b/Checkpoint3/todoapp.db new file mode 100644 index 00000000..0c9688f6 Binary files /dev/null and b/Checkpoint3/todoapp.db differ diff --git a/Program.cs b/Program.cs new file mode 100644 index 00000000..d879ba8f --- /dev/null +++ b/Program.cs @@ -0,0 +1,12 @@ +using System; + +namespace csharp_workbook +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine("Hello World!"); + } + } +} diff --git a/csharp-workbook.csproj b/csharp-workbook.csproj new file mode 100644 index 00000000..d06178dc --- /dev/null +++ b/csharp-workbook.csproj @@ -0,0 +1,9 @@ + + + + Exe + netcoreapp2.1 + csharp_workbook + + +