Gitea Migration

This commit is contained in:
2026-02-23 09:50:15 -05:00
commit ecd4120b0a
8 changed files with 868 additions and 0 deletions

18
LICENSE Normal file
View File

@@ -0,0 +1,18 @@
MIT License
Copyright (c) 2026 rapturate
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.

3
README.md Normal file
View File

@@ -0,0 +1,3 @@
# To_Do_List
A console To Do List, written in Java, for a software development class. Shows my functional understanding of Java and organizational skills for code

BIN
To_Do_List_Console.jar Normal file

Binary file not shown.

6
bin/list.txt Normal file
View File

@@ -0,0 +1,6 @@
Health, Doctors Appointment, 10/31/2025, 2
Health, Dentist Appointment, 10/31/2025, 3
School, School Visit, 11/22/2025, 3
Rover, Sadie, 11/22/1995, 4
Rover, Sadie and Finn, 09/10/2025, 4
na, Dog Sit, 12/31/1969, 10

224
src/Item.java Normal file
View File

@@ -0,0 +1,224 @@
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Item {
private String category = " ";
private String name;
private Date dueDate;
private int priority = 10;
//Constructors
/**
* Initializes an {@code Item} object.
* <p>
* Usage:
* {@snippet :
* Item item = new Item("Jump up and down");
* }
* @param String The name of the item to do.
* @return {@code void}
*/
public Item(String name){
this.name = name;
}
public Item(String name, String category, String dateString, int priority){
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
this.name = name;
this.category = category;
try {
this.dueDate = formatter.parse(dateString);
} catch (ParseException e){
System.out.println("Date formatting failed.");
e.printStackTrace();
}
this.priority = priority;
}
//Setters
// Method Signature: setCategoty(String) -> void
// Purpose: sets the category name
// Example: Item.setCategory("Health")
/**
* Sets the {@code String category} field.
* <p>
* Usage:
* {@snippet :
* item.setCategory("Health");
* }
* @param String The String for {@code Private String category}.
* @return {@code void}
*/
public void setCategory(String category){
this.category = category;
}
// Method Signature: setName(String) -> void
// Purpose: sets the name of the event
// Example: Item.setName("Workout")
/**
* Sets the {@code private String name} field.
* <p>
* Usage:
* {@snippet :
* item.setName("Field Work");
* }
* @param String The String for {@code Private String name}.
* @return {@code void}
*/
public void setName(String name){
this.name = name;
}
// Method Signature: setDueDate(String) -> void
// Purpose: sets the date. This class takes in a String, converts it into a Date and puts it into dueDate.
// Default: if the date is input incorrectly, it defaults to 12/31/1969.
// Example: Item.setCategory(dateString)
/**
* Sets the {@code private Date dueDate} field.
* <p>
* The date MUST be formatted as MM/DD/YYYY.
* <p>
* Usage:
* {@snippet :
* item.setDueDate("MM/DD/YYYY");
* }
* @param String The String that will be formatted for {@code Private Date dueDate}.
* @return {@code void}
*/
public void setDueDate(String dateString){
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
Date date = new Date(0);
try {
date = formatter.parse(dateString);
} catch (ParseException e){
System.out.println("Bad Date format.");
}
this.dueDate = date;
}
// Method Signature: setPriority(int) -> void
// Purpose: sets the priority on a scale of 1-10. 10 being the least important and 1 being the most.
// Example: Item.setPriority(1)
/**
* Sets the {@code private int priority} field.
* <p>
* Usage:
* {@snippet :
* item.setPriority(10);
* }
* @param int The integer for {@code Private String priority}.
* @return {@code void}
*/
public void setPriority(int priority){
this.priority = priority;
}
//Getters
/**
* Gets the String stored in {@code private String category} field.
* <p>
* Usage:
* {@snippet :
* String category = item.getCategory();
* }
* @return {@code String}
*/
public String getCategory() {
return this.category;
}
/**
* Gets the String stored in {@code private String name} field.
* <p>
* Usage:
* {@snippet :
* String name = item.getName();
* }
* @return {@code String}
*/
public String getName() {
return this.name;
}
/**
* Gets the {@code Date} object stored in {@code private int dueDate} field.
* <p>
* Usage:
* {@snippet :
* Date dueDate = item.getDueDate();
* }
* @return {@code Date}
*/
public Date getDueDate() {
return this.dueDate;
}
/**
* Gets the integer stored in {@code private int dueDate} field and converts it to a {@code String}.
* <p>
* Usage:
* {@snippet :
* String dueDateString = item.getDueDateString();
* }
* @return {@code String}
*/
public String getDueDateString(){
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
return formatter.format(this.dueDate);
}
/**
* Gets the integer stored in {@code private int priority} field.
* <p>
* Usage:
* {@snippet :
* int priority = item.getPriority();
* }
* @return {@code int}
*/
public int getPriority() {
return this.priority;
}
/**
* Takes all of the fields in {@code Item} and converts them to a formatted {@code String} for command line printing.
* <p>
* Usage:
* {@snippet :
* String itemString = item.formatString();
* }
* @return {@code String}: returns "" if there is no date
*/
public String formatString(){
String dateString = "";
if(dueDate.compareTo(new Date(0)) != 0 ){ //If the compareTo funcioon returns 0 than the date is set to default which means 12/31/1969.
SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyy");
dateString = format.format(this.dueDate);
if(dateString.equals("12/31/1969")){
dateString = "";
}
}
if(this.category.equals("na")){
this.category = "";
}
return String.format("%-23s %-20s %-12s %-10d\n", this.name, this.category, dateString, this.priority);
}
}

21
src/MainLoop.java Normal file
View File

@@ -0,0 +1,21 @@
import java.util.Scanner;
/**
*
* @author Lewis Price
* @since 1.0
*/
public class MainLoop {
public static void main(String[] args) {
String listPath;
System.out.println("Enter the path to where you want the todo list file to be.");
Scanner scanner = new Scanner(System.in);
listPath = scanner.next();
UserInterface ui = new UserInterface(listPath);
ui.run();
scanner.close();
}
}

481
src/ToDoList.java Normal file
View File

@@ -0,0 +1,481 @@
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.InputMismatchException;
import java.util.Scanner;
public class ToDoList {
private ArrayList<Item> listArr;
private String pathName;
private Scanner scanner;
private String listHeader = String.format("%-23s %-20s %-12s %-10s\n----------------------------------------------------------------------------------------------------\n"
, "Name", "Category", "Date", "Priority");
private String footer = "----------------------------------------------------------------------------------------------------\n";
//Constructor
/**
* Constructor for creating a new ToDoList.
*
* {@snippet :
* ToDoList list = new ToDoList( [filePath] , [Scanner Object] );
* }
*
* @param pathName Takes the path of the list.txt file to open or create a new file.
* @param Scanner Scanner passthrough to prevent {@code Scanner} clashes.
*/
public ToDoList(String pathName, Scanner scanner){
listArr = new ArrayList<Item>();
this.pathName = pathName;
this.scanner = scanner;
openList();
}
//Setters
/**
* Used by the system to add a new {@code Item} to the {@code ArrayList<Item>}
*
* {@snippet :
* list.addItem( [item] );
* }
*
* @param Item The {@code Item} being added to the {@code ArrayList<Item>}
* @return void
*/
private void addItem(Item item){
listArr.add(item);
}
/**
* Used by the system to create a header for console output.
*
* {@snippet :
* formatHeader( "Add Item" );
* }
*
* @param String: the name of the page that needs a header output string.
* @return {@code String header}
*/
private String formatHeader(String pageName){
String formatedHeader = "";
int i;
for(i = 0; i < (50 - pageName.length()/2); i++){
formatedHeader += "-";
}
formatedHeader += pageName;
for( i += pageName.length(); i < 100; i++){
formatedHeader += "-";
}
formatedHeader += "\n";
return formatedHeader;
}
/**
* Begins the System output and input to create and add a new {@code Item} to {@code ArrayList<Item>}.
* <p>
* Usage
* {@snippet :
* list.addItemAction();
* }
* <p>
* -------------
* <p>
* Defaults:
* <p>
* Date: 12/31/1969
* <p>
* - This date is read by the system as null and won't be visibly printed.
* <p>
* Category: "na"
* <p>
* - "na" is read by the system as null and won't be visibly printed.
* <p>
* Priority: 10
* <p>
* - Priority 10 is the least important therefore the default if not provided.
*
* @return void, but prints messages to console.
*/
public void addItemAction() {
System.out.println(formatHeader("Add Item"));
System.out.print("Name (Required): ");
String name = scanner.nextLine();
Item newItem = new Item(name);
System.out.print("Category: ");
String category = scanner.nextLine();
if(category.equals("na") || category.equals("")) {
category = "na";
}
newItem.setCategory(category);
System.out.print("Date (MM/DD/YYYY): ");
String dateString = scanner.nextLine();
if(dateString.equals("na") || dateString.equals("")) {
newItem.setDueDate("12/31/1969"); //defaults to 12/31/1969
} else {
newItem.setDueDate(dateString);
}
System.out.print("Priority: ");
String priority = scanner.nextLine();
try {
Integer.parseInt(priority);
} catch (NumberFormatException e){
priority = "10";
}
if(priority.equals("")){
priority = "10";
}else if(Integer.parseInt(priority) < 1 || Integer.parseInt(priority) > 10) {
System.out.println("Priority out of range, defaulted to 10.");
priority = "10";
}
newItem.setPriority(Integer.parseInt(priority));
addItem(newItem);
System.out.println("\n\nAdded:\n" + listHeader + newItem.formatString());
}
/**
* Takes a {@code String} to create an {@code Item} to {@code ArrayList<Item>}.
* <p>
* This function must include a all {@code Item} parameters.
* <p>
* Usage
* {@snippet :
* list.addItemAction({@code "name, category, date, priority");
* }
* <p>
*
* @param String, parses this string into different sections to create a new {@code Item}
* @return void, but prints messages to console.
*/
public void addItemByString(String inputString) {
String[] parsedString = inputString.split(", ");
Item newItem = new Item(parsedString[0], parsedString[1], parsedString[2], Integer.parseInt(parsedString[3]));
addItem(newItem);
System.out.println("\n\nAdded:\n" + listHeader + newItem.formatString());
}
/**
* Formats, displays, and deletes an {@code Item} from user input from {@code ArrayList<Item>}.
* <p>
* Does not save to the txt file. See {@code saveChanges()}.
*<p>
* Usage:
* {@snippet :
* list.deleteItem();
* }
*
* @return void, but prints to console.
*/
public void deleteItem(){
System.out.println(formatHeader("Delete Item"));
System.out.println("Type one name and all items by that name will be removed.");
System.out.print("Name: ");
String name = scanner.nextLine();
ArrayList<Item> tempList = new ArrayList<>();
ArrayList<Item> deletedItems = new ArrayList<>();
//Deletes
for(Item list: listArr){
if(!list.getName().equalsIgnoreCase(name)){
tempList.add(list);
} else {
deletedItems.add(list);
}
}
if(deletedItems.size() > 0){
System.out.println(formatHeader("Deleted Items"));
for(Item list: deletedItems){
System.out.print(list.formatString());
}
System.out.print(footer);
listArr = tempList;
saveChanges();
} else {
System.out.println("No item by that name.");
}
}
/**
* Formats, displays, and changes an {@code Item} from user input from {@code ArrayList<Item>}.
* <p>
* Does not save to the txt file. See {@code saveChanges()}.
*<p>
* Usage:
* {@snippet :
* list.changeItem();
* }
*
* @return void, but prints to console.
*/
public void changeItem(){
System.out.println(formatHeader("Change Item"));
ArrayList<Item> alteredItems = new ArrayList<>();
System.out.println();
System.out.println("Type the name of the item you'd like to change.");
System.out.print("Name: ");
String name = scanner.nextLine();
System.out.println("What aspect would you like to change?");
System.out.println("Type 'Name', 'Category', 'Date' or 'Priority'.");
System.out.print("Response: ");
String response = scanner.nextLine();
int changeCount = 0;
//Change Name
if(response.equalsIgnoreCase("Name")){
System.out.print("New Name: ");
String newName = scanner.nextLine();
for(Item changedItem : listArr){
if(changedItem.getName().equalsIgnoreCase(name)){
alteredItems.add(changedItem);
changedItem.setName(newName);
changeCount++;
}
}
System.out.println(String.format("%d item(s) changed", changeCount));
//Change Category
} else if(response.equalsIgnoreCase("Category")){
System.out.print("\nNew Category Name: ");
String newCatName = scanner.nextLine();
for(Item changedItem : listArr){
if(changedItem.getName().equalsIgnoreCase(name)){
alteredItems.add(changedItem);
changedItem.setCategory(newCatName);
changeCount++;
}
}
System.out.println(String.format("%d item(s) changed", changeCount));
//Change Date
} else if(response.equalsIgnoreCase("Date")){
System.out.print("New Date (MM/DD/YYY): ");
String dateString = scanner.nextLine();
for(Item changedItem : listArr){
if(changedItem.getName().equalsIgnoreCase(name)){
alteredItems.add(changedItem);
changedItem.setDueDate(dateString);
changeCount++;
}
}
System.out.println(String.format("%d item(s) changed", changeCount));
//Change Priority
} else if(response.equalsIgnoreCase("Priority")){
System.out.print("New Priority: ");
for(Item changedItem : listArr){
if(changedItem.getName().equalsIgnoreCase(name)){
try {
String newPriorityString = scanner.nextLine();
alteredItems.add(changedItem);
int newPriority = Integer.parseInt(newPriorityString);
changedItem.setPriority(newPriority);
changeCount++;
} catch (InputMismatchException e) {
System.out.println("Not an integer. Nothing changed.");
}
}
}
System.out.println(String.format("%d item(s) changed", changeCount));
//Bad Input
} else {
System.out.println("Bad input, nothing altered.");
}
//Print Changed Items
System.out.print(listHeader);
for(Item item : alteredItems){
System.out.println(item.formatString());
}
System.out.print(footer);
printList();
}
/**
*Opens a {@code .txt file} from a developers {@code main} function.
*<p>
* Usage:
* {@snippet :
* list.openList();
* }
*
* @return void, but prints to console.
*/
public void openList(){
File listFile = new File(pathName);
try(Scanner fileReader = new Scanner(listFile)){
while (fileReader.hasNextLine()) {
String line = fileReader.nextLine();
String[] splitLine = line.split(", ");
Item item = new Item(splitLine[1]);
if(splitLine.length == 0){
break;
}
if(splitLine[0].equals("na")){
item.setCategory("");
} else {
item.setCategory(splitLine[0]);
}
if(splitLine[2].equals("12/31/1969")){
item.setDueDate("12/31/1969");
} else {
item.setDueDate(splitLine[2]);
}
if(splitLine[3].equals("na")){
item.setPriority(10);
} else {
item.setPriority(Integer.parseInt(splitLine[3]));
}
listArr.add(item);
}
} catch (FileNotFoundException e) {
System.out.println("No Previous List. Creating a new one.");
File file = new File(pathName);
try{
file.createNewFile();
} catch(IOException failed){
System.out.println("File creation failed.");
failed.printStackTrace();
}
}
}
//Organization
/**
* Sorts the {@code ArrayList<Item>} by asking users which field they want to sort by.
* <p>
* Does not save to the txt file. See {@code saveChanges()}.
*<p>
* Usage:
* {@snippet :
* list.sortBy();
* }
*
* @return void, but prints to console.
*/
public void sortBy(){
System.out.println(formatHeader("Sort By"));
System.out.println( "- Category: Alphabetically by category name then alphabetically by Name.\n" +
"- Name: Alphabetically by Name.\n" +
"- Date: Earliest Date first, then by Category for repeated Dates.\n" +
"- Priorty: 1 is most important, 10 is least important. If Priorities are equal, sorted by Date. \n");
System.out.print("Option: ");
String organizeBy = scanner.nextLine();
if(organizeBy.equalsIgnoreCase("category")){
listArr.sort(Comparator.comparing(Item::getCategory).thenComparing(Item::getName));
} else if(organizeBy.equalsIgnoreCase("name")){
listArr.sort(Comparator.comparing(Item::getName).thenComparing(Item::getDueDate));
} else if(organizeBy.equalsIgnoreCase("date")){
listArr.sort(Comparator.comparing(Item::getDueDate).thenComparing(Item::getCategory));
} else if(organizeBy.equalsIgnoreCase("priority")){
listArr.sort(Comparator.comparingInt(Item::getPriority).thenComparing(Item::getDueDate));
} else {
System.out.println("Cannot organize by that.");
return;
}
}
/**
* Saves the {@code ArrayList<Item>} to the {@code list.txt} using the developer provided {@code path}.
*<p>
* Usage:
* {@snippet :
* list.saveChanges();
* }
* @return void, but prints to console.
*/
public void saveChanges(){
File file = new File(pathName);
try (FileWriter writer = new FileWriter(file, false)){
for(Item listInput : listArr){
String category = listInput.getCategory();
if(category.equals("")){
category = "na";
}
String name = listInput.getName();
String date = listInput.getDueDateString();
String priority = Integer.toString(listInput.getPriority());
String line = String.format("%s, %s, %s, %s\n",category, name, date, priority);
writer.write(line);
}
writer.close();
} catch (IOException e){
System.out.println("File not found.");
e.printStackTrace();
}
}
//Getters
/**
* Formats a {@code String} from the encapsulated {@code ArrayList<Item> listArr}.
*<p>
* Usage:
* {@snippet :
* list.openList();
* }
*
* @return {@code String}
*/
public String printList(){
String list = footer
+ formatHeader("To Do List")
+ footer
+ listHeader;
for(int i = 0; i < listArr.size(); i++){
list = list.concat(listArr.get(i).formatString());
}
return list;
}
public String getCategory(String category){
String list = listHeader;
for(int i = 0; i < listArr.size(); i++){
if(listArr.get(i).getCategory().equals(category)){
list = list.concat(i+1 + ": " + listArr.get(i).formatString());
}
}
return list;
}
}

115
src/UserInterface.java Normal file
View File

@@ -0,0 +1,115 @@
import java.util.Scanner;
public class UserInterface {
private String pathName;
private Scanner scanner;
private ToDoList list;
/**
* Constructor
* <p>
* Initializes a {@code UserInterface} object.
* <p>
* Usage:
* {@snippet :
* UserInterface ui = new UserInterface("./list.txt");
* }
* @param String The path to the list.txt file as a string.
*/
public UserInterface(String listPath){
this.pathName = listPath; //Relative path to the starting .txt file. If one is not found, a new one is created.
this.scanner = new Scanner(System.in); //The only scanner that will be declared in the overall program
this.list = new ToDoList(pathName, scanner);
}
/**
* Starts a while loop that runs an instance of ToDoList.
* <p>
* Usage:
* {@snippet :
* ToDoList list.run();
* }
* @return {@code void}, but has outputs to the terminal.
*/
public void run(){
//Loop that continues until the user inputs "quit". Capitalization not important
while(true){
printChoices();
String input = getInput();
if(runInput(input)) break;
list.saveChanges();
}
scanner.close();
}
/**
* Formats and prints a consistent "Directions" message.
* <p>
* Usage:
* {@snippet :
* printChoices();
* }
* @return {@code void}, but prints to console.
*/
private void printChoices(){
System.out.println(list.printList());
String directionMessage = "\n"
+ "-'Home': takes you to your current list.\n"
+ "-'Add': adds new item.\n"
+ "-'Delete': deletes an item.\n"
+ "-'Change': changes an item.\n"
+ "-'Organize': organizes based on what you want to organize by.\n"
+ "-'Quit': exits the program.\n";
System.out.println(directionMessage);
}
/**
* Recieves the {@code String input} via the instance of {@code java.util.Scanner} that was declared in this class.
* <p>
* Usage:
* {@snippet :
* String input = getInput();
* }
* @return {@code String input}, and prints a prompt to console.
*/
private String getInput(){
System.out.print("Choice: ");
return scanner.nextLine();
}
/**
* Recieves the {@code String input} via the instance of {@code java.util.Scanner} that was declared in this class. If the user types "quit", the program quits, otherwise it continues.
* <p>
* The {@code input string} is not case sensitive.
* <p>
* Usage:
* {@snippet :
* if(runInput("Quit")) break; //this will break out of a loop.
* }
* @param String input: the input {@code String} that {@code runInput()} will use.
* @return {@code boolean endLoop}: returns true if input = "Quit" to end the loop in {@code run()}, false otherwise.
*/
private boolean runInput(String input){
if(input.equalsIgnoreCase("quit")){
System.out.println("Bye!");
return true;
} else if(input.equalsIgnoreCase("Add")){
list.addItemAction();
} else if (input.equalsIgnoreCase("Delete")){
list.deleteItem();
} else if(input.equalsIgnoreCase("Change")){
list.changeItem();
} else if (input.equalsIgnoreCase("Organize")){
list.sortBy();
} else if (input.equalsIgnoreCase("Home")){
System.out.println(list.printList());
} else {
System.out.println("That was not an option.");
}
return false;
}
}